VideoShopGoods.php 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335
  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 app\jobs\storeSync\DiyCommon;
  10. use app\modules\admin\models\imageSearch\UploadImageForm;
  11. use app\modules\admin\models\MerchantForm;
  12. use yii\db\ActiveRecord;
  13. use yii\behaviors\TimestampBehavior;
  14. use yii\helpers\ArrayHelper;
  15. use yii\helpers\Json;
  16. use app\modules\admin\models\pospal\PospalForm;
  17. use app\models\common\Upload;
  18. use app\modules\admin\models\MchForm;
  19. /**
  20. * Class Goods
  21. * @package app\modules\common\models
  22. * @property integer $id
  23. * @property integer $store_id
  24. * @property integer $mini_id
  25. * @property string $product_id
  26. * @property string $name
  27. * @property string $price
  28. * @property string $goods_send_profit
  29. * @property string $goods_take_price
  30. * @property string $original_price
  31. * @property integer $integral_price
  32. * @property string $detail
  33. * @property string $cat_id
  34. * @property integer $status
  35. * @property integer $is_delete
  36. * @property string $attr
  37. * @property string $service
  38. * @property integer $sort
  39. * @property integer $virtual_sales
  40. * @property string $cover_pic
  41. * @property string $video_url
  42. * @property string $unit
  43. * @property integer $individual_share
  44. * @property string $share_commission_first
  45. * @property string $share_commission_second
  46. * @property string $share_commission_third
  47. * @property double $weight
  48. * @property string $freight
  49. * @property string $full_cut
  50. * @property string $integral
  51. * @property integer $use_attr
  52. * @property integer $share_type
  53. * @property integer $quick_purchase
  54. * @property integer $hot_cakes
  55. * @property integer $mch_id
  56. * @property integer $goods_num
  57. * @property string $cost_price
  58. * @property integer $member_discount
  59. * @property string $rebate
  60. * @property integer $mch_sort
  61. * @property integer $type
  62. * @property integer $is_level
  63. * @property integer $confine_count
  64. * @property integer $is_negotiable
  65. * @property string $goods_share_title
  66. * @property string $goods_share_logo
  67. * @property string $goods_share_desc
  68. * @property string $created_at
  69. * @property string $updated_at
  70. * @property string $goods_no
  71. * @property string $key_word
  72. * @property string $pieces
  73. * @property string $forehead
  74. * @property integer $attr_setting_type
  75. * @property string $verify_card_id
  76. * @property integer $is_verify
  77. * @property string $delivery_type
  78. * @property integer $product_type
  79. * @property integer $is_form
  80. * @property string $form_name
  81. * @property integer $is_recommend
  82. * @property integer $rate
  83. * @property integer $rate_type
  84. * @property integer $md_rate
  85. * @property integer $md_rate_type
  86. * @property integer $dl_p_rate
  87. * @property integer $dl_c_rate
  88. * @property integer $dl_d_rate
  89. * @property integer $dl_p_rate_type
  90. * @property integer $dl_c_rate_type
  91. * @property integer $dl_d_rate_type
  92. * @property integer $md_hx_rate
  93. * @property integer $md_hx_rate_type
  94. * @property integer $md_food_id
  95. * @property integer $cloud_goods_id
  96. * @property integer $cloud_supplier_id
  97. * @property string $material_id
  98. * @property string $material_key
  99. * @property integer $service_book_num
  100. * @property integer $can_set_md_price
  101. * @property integer $delivery_rules_id
  102. * @property integer $goods_area_rules_id
  103. * @property integer $order_rules_buyer_location_id
  104. * @property integer $food_ext_goods_id
  105. * @property integer $stbz_goods_id
  106. * @property integer $is_wholesale
  107. * @property string $accessories_image
  108. * @property string $service_book_desc
  109. * @property string $parameter_list
  110. * @property string $buy_type_info
  111. * @property string $share_commission_new_first
  112. * @property string $share_commission_new_second
  113. * @property string $share_commission_new_third
  114. * @property integer $send_verify_card_num
  115. * @property string $coupon_card_id
  116. * @property integer $send_coupon_card_num
  117. * @property integer $brand_id
  118. * @property integer $is_risk
  119. * @property integer $share_holder_profit_switch
  120. * @property string $share_holder_high_profit
  121. * @property integer $time_made_day
  122. * @property integer $time_shelf_life
  123. * @property integer $warehouse_id
  124. * @property integer $warehouse_zone_id
  125. * @property integer $is_front_delivery
  126. * @property integer $is_front_centralize
  127. * @property integer $agent_goods_status
  128. * @property integer $cloud_inventory_id
  129. */
  130. class VideoShopGoods extends ActiveRecord
  131. {
  132. //从银豹同步时设置为1
  133. public $yinbaoSync = 0;
  134. //活动价(临时字段)
  135. public $activityPrice = 0;
  136. /**
  137. * 正常商品
  138. */
  139. const GOODS_TYPE_NORMAL = 0;
  140. /**
  141. * 日期预约商品
  142. */
  143. const GOODS_TYPE_DATE = 1;
  144. /**
  145. * 时间预约商品
  146. */
  147. const GOODS_TYPE_TIME = 2;
  148. /**
  149. * 虚拟商品
  150. */
  151. const GOODS_TYPE_VIRTUAL = 3;
  152. /**
  153. * 积分商品
  154. */
  155. const GOODS_TYPE_INTEGRAL = 4;
  156. /**
  157. * 认养商品
  158. */
  159. const GOODS_TYPE_ADOPT = 5;
  160. /**
  161. * 上门服务商品
  162. */
  163. const GOODS_TYPE_WORKER = 6;
  164. /**
  165. * 展示类商品
  166. */
  167. const GOODS_TYPE_VIEW = 7;
  168. public static $validProductType = [
  169. self::GOODS_TYPE_NORMAL,
  170. self::GOODS_TYPE_DATE,
  171. self::GOODS_TYPE_TIME,
  172. self::GOODS_TYPE_VIRTUAL,
  173. self::GOODS_TYPE_INTEGRAL,
  174. self::GOODS_TYPE_ADOPT,
  175. self::GOODS_TYPE_WORKER,
  176. self::GOODS_TYPE_VIEW,
  177. ];
  178. const STATUS_NORMAL = 1; // 上架
  179. const STATUS_DISABLE = 0; // 下架
  180. /**
  181. * 价格面议
  182. */
  183. const GOODS_NEGOTIABLE = '价格面议';
  184. /**
  185. * @var int|mixed|null
  186. */
  187. public static function tableName()
  188. {
  189. return '{{%video_shop_goods}}';
  190. }
  191. public function behaviors()
  192. {
  193. return [
  194. [
  195. // 自动更新创建和更新时间
  196. 'class' => TimestampBehavior::class,
  197. 'value' => time()
  198. ]
  199. ];
  200. }
  201. public function rules()
  202. {
  203. return [
  204. [['store_id', 'name', 'detail', 'attr'], 'required', 'on' => self::whenSave()],
  205. [['integral_price','store_id', 'cat_id', 'status', 'is_delete', 'created_at', 'updated_at',
  206. 'sort', 'individual_share', 'freight', 'use_attr', 'share_type', 'is_verify',
  207. 'quick_purchase', 'hot_cakes', 'mch_id', 'mch_audit', 'mch_audit_time', 'goods_num', 'member_discount', 'virtual_sales',
  208. 'mch_sort', 'type', 'is_level', 'confine_count', 'is_negotiable', 'pieces', 'attr_setting_type', 'product_type', 'is_form', 'is_recommend', 'md_food_id', 'rate_type', 'md_rate_type', 'md_hx_rate_type', 'dl_p_rate_type', 'dl_c_rate_type', 'dl_d_rate_type', 'cloud_goods_id', 'service_book_num', 'delivery_rules_id', 'goods_area_rules_id'], 'integer', 'on' => self::whenSave()],
  209. [['price', 'original_price', 'share_commission_first', 'share_commission_second',
  210. 'share_commission_third', 'weight', 'cost_price', 'rebate', 'forehead', 'rate', 'md_rate', 'md_hx_rate', 'dl_p_rate', 'dl_c_rate', 'dl_d_rate','queue_rate'], 'number', 'on' => self::whenSave()],
  211. [['detail', 'attr', 'cover_pic', 'full_cut', 'integral'], 'string', 'on' => self::whenSave()],
  212. [['name', 'unit','goods_share_title','goods_share_logo','goods_share_desc', 'goods_no', 'key_word', 'delivery_type', 'form_name','accessories_image', 'buy_type_info'], 'string', 'max' => 255, 'on' => self::whenSave()],
  213. [['service'], 'string', 'max' => 2000, 'on' => self::whenSave()],
  214. [['video_url'], 'string', 'max' => 2048, 'on' => self::whenSave()],
  215. [['verify_card_id', 'material_id','material_key', 'parameter_list', 'share_commission_new_first', 'share_commission_new_second', 'share_commission_new_third', 'coupon_card_id', 'unit'], 'string'],
  216. [['status','cat_id','store_id'], 'integer', 'on' => self::whenList()],
  217. [['name'], 'string', 'max' => 60, 'on' => self::whenList()],
  218. [['status', 'is_verify'], 'default', 'value' => -1, 'on' => self::whenList()],
  219. [['mch_id'], 'default', 'value' => 0, 'on' => self::whenList()],
  220. [['store_id'], 'default', 'value' => 1, 'on' => self::whenList()],
  221. [['can_set_md_price', 'order_rules_buyer_location_id', 'food_ext_goods_id', 'goods_send_profit', 'goods_take_price', 'service_book_desc', 'share_holder_high_profit'], 'safe'],
  222. [['stbz_goods_id', 'is_wholesale', 'cloud_goods_id', 'cloud_supplier_id', 'send_verify_card_num', 'send_verify_card_num', 'integral_price', 'brand_id', 'is_risk', 'share_holder_profit_switch', 'warehouse_id', 'warehouse_zone_id', 'is_front_delivery', 'is_front_centralize', 'agent_goods_status'], 'integer'],
  223. [['time_made_day', 'time_shelf_life'], 'safe'],
  224. ];
  225. }
  226. public function attributeLabels()
  227. {
  228. return [
  229. 'id' => 'ID',
  230. 'store_id' => 'Store ID',
  231. 'name' => '商品名称',
  232. 'goods_send_profit' => '商品让利比例返给用户',
  233. 'goods_take_price' => '商品让利比例扣除用户',
  234. 'price' => '售价',
  235. 'original_price' => '原价(只做显示用)',
  236. 'integral_price' => '积分兑换',
  237. 'detail' => '商品详情,图文',
  238. 'cat_id' => '商品类别',
  239. 'status' => '上架状态:0=下架,1=上架',
  240. 'is_delete' => 'Is Delete',
  241. 'attr' => '规格的库存及价格',
  242. 'service' => '商品服务选项',
  243. 'sort' => '排序 升序',
  244. 'virtual_sales' => '虚拟销量',
  245. 'cover_pic' => '商品缩略图',
  246. 'video_url' => '视频',
  247. 'unit' => '单位',
  248. 'individual_share' => '是否单独分销设置:0=否,1=是',
  249. 'share_commission_first' => '一级分销佣金比例',
  250. 'share_commission_second' => '二级分销佣金比例',
  251. 'share_commission_third' => '三级分销佣金比例',
  252. 'weight' => '重量',
  253. 'freight' => '运费模板ID',
  254. 'full_cut' => '满减',
  255. 'integral' => '积分设置',
  256. 'use_attr' => '是否使用规格:0=不使用,1=使用',
  257. 'share_type' => '佣金配比 0--百分比 1--固定金额',
  258. 'quick_purchase' => '是否加入快速购买 0--关闭 1--开启',
  259. 'hot_cakes' => '是否加入热销 0--关闭 1--开启',
  260. 'mch_id' => '入驻商户的id',
  261. 'goods_num' => '商品总库存',
  262. 'cost_price' => 'Cost Price',
  263. 'member_discount' => '是否参与会员折扣 0=参与 1=不参与',
  264. 'rebate' => '自购返利',
  265. 'mch_sort' => '多商户自己的排序',
  266. 'type' => '类型 0--商城或多商户 2--砍价商品',
  267. 'is_level' => '是否享受会员折扣',
  268. 'confine_count' => '购买限制:0.不限制|大于0等于限购数量',
  269. 'is_negotiable' => '面议方式',
  270. 'attr_setting_type' => '分销设置类型 0.普通设置|1.详细设置',
  271. 'verify_card_id' => '绑定核销卡',
  272. 'goods_share_title' => '商品分享标题',
  273. 'goods_share_desc' => '商品分享缩略图',
  274. 'goods_share_logo' => '商品分享简介',
  275. 'created_at' => '创建时间',
  276. 'updated_at' => '更新时间',
  277. 'goods_no' => '商品货号',
  278. 'key_word' => '关键字',
  279. 'pieces' => '单品满件包邮',
  280. 'forehead' => '单品满额包邮',
  281. 'is_verify' => '入驻商待审核 0 待审核 1审核通过并上架 2审核未通过',
  282. 'rate_type' => "分红类型",
  283. 'cloud_goods_id' => "云仓商品ID",
  284. 'service_book_num' => '预约商品数量',
  285. 'can_set_md_price' => '门店溢价销售 0禁止 1允许',
  286. 'delivery_rules_id' => '运送规则id',
  287. 'goods_area_rules_id' => '销售规则id',
  288. 'stbz_goods_id' => '胜天半子goods_id',
  289. 'order_rules_buyer_location_id' => '销售区域规则id',
  290. 'food_ext_goods_id' => '附加商品区id',
  291. 'is_wholesale' => '是否批发',
  292. 'accessories_image' => '装配图片',
  293. 'parameter_list' => '商品参数',
  294. 'service_book_desc' => '酒店商品特殊日期值',
  295. 'buy_type_info' => '购买类型',
  296. 'share_commission_new_first' => '新一级分销佣金比例, 带等级',
  297. 'share_commission_new_second' => '新二级分销佣金比例, 带等级',
  298. 'share_commission_new_third' => '新三级分销佣金比例, 带等级',
  299. 'send_coupon_card_num' => '赠送优惠券数量',
  300. 'send_verify_card_num' => '赠送核销卡数量',
  301. 'coupon_card_id' => '赠送优惠券id',
  302. 'is_risk' => '商品是否有风险',
  303. 'is_front_delivery' => '是否是云仓仓库配送商品(配送方式只能为到店自提和同城配送)',
  304. 'is_front_centralize' => '是否是云仓集采商品(配送方式只能为到店自提)',
  305. 'agent_goods_status' => '是否是云仓代理配送产品(配送方式只能为到店自提或快递 如果是可上门安装则为快递 如果不上门安装则为到店自提 大于0表示是代理配送商品 2表示需要上门安装)'
  306. ];
  307. }
  308. public static function whenSave ()
  309. {
  310. return 'save';
  311. }
  312. public static function whenList ()
  313. {
  314. return 'list';
  315. }
  316. public function afterFind()
  317. {
  318. parent::afterFind();
  319. try {
  320. // 处理cover_pic
  321. //不做判断时 手机端修改商品价格时会将封面图设置为null
  322. if ($this->cover_pic) {
  323. $this->cover_pic = Upload::getImgStyle($this->cover_pic);
  324. }
  325. // 处理规格图片
  326. if ($this->attr) {
  327. $attrs = json_decode($this->attr, true);
  328. if (\is_array($attrs)) {
  329. foreach ($attrs as &$attr) {
  330. $attr['pic'] = Upload::getImgStyle($attr['pic']);
  331. }
  332. $this->attr = json_encode($attrs, JSON_UNESCAPED_UNICODE);
  333. }
  334. }
  335. if ($this->detail) {
  336. // 处理detail,使用正则匹配并替换图片地址
  337. $detail = preg_replace_callback('/<img.*?src="(.*?)".*?\/>/', function ($matches) {
  338. return '<img src="' . Upload::getImgStyle($matches[1]) . '">';
  339. }, $this->detail);
  340. if ($detail) {
  341. $this->detail = $detail;
  342. }
  343. }
  344. } catch (\Throwable $e) {}
  345. }
  346. public function beforeSave($insert)
  347. {
  348. //在总后台 店铺后台 需要设置店铺 是否允许店铺上传产品,如果设置为不允许,就只能云仓选品,PC端后台和手机端后台都需要控制。
  349. if ($insert) {
  350. $is_add_goods = Option::get('is_add_goods', $this->store_id, 'store', 1)['value'];
  351. if (intval($this->cloud_goods_id) === 0 && (int)$is_add_goods === 0) {
  352. $this->addError('is_add_goods', '错误:当前店铺不允许上传产品,只能云仓选品');
  353. return false;
  354. }
  355. }
  356. if (intval($this->is_front_delivery)) {
  357. $this->delivery_type = json_encode(['shop', 'delivery'], JSON_UNESCAPED_UNICODE);
  358. }
  359. if (intval($this->is_front_centralize)) {
  360. $this->delivery_type = json_encode(['shop'], JSON_UNESCAPED_UNICODE);
  361. }
  362. if (intval($this->agent_goods_status)) {
  363. $delivery_type = ['shop'];
  364. if (intval($this->agent_goods_status) === 2) {//需要上门安装
  365. $delivery_type = ['express'];
  366. }
  367. $this->delivery_type = json_encode($delivery_type, JSON_UNESCAPED_UNICODE);
  368. }
  369. if ($this->use_attr == 1) {
  370. $this->goods_num = $this->getNum();
  371. if ($this->attr && !in_array($this->product_type, [1, 2])) {
  372. $attr_rows = json_decode($this->attr, true);
  373. $price_arr = array_column($attr_rows, 'price');
  374. $integral_price_arr = array_column($attr_rows, 'integral_price');
  375. if (!empty($price_arr)) {
  376. $this->price = min($price_arr);
  377. }
  378. if (!empty($integral_price_arr)) {
  379. $this->integral_price = intval(min($integral_price_arr));
  380. }
  381. }
  382. }
  383. if (in_array($this->product_type, [6])) {
  384. $this->use_attr = 0;
  385. }
  386. if (empty($this->buy_type_info)) {
  387. $this->buy_type_info = json_encode([
  388. 'type' => 0,
  389. 'member_level' => 0
  390. ]);
  391. }
  392. if (intval($this->individual_share) === 1) {
  393. $share_level = ShareLevel::find()->where(['store_id' => $this->store_id, 'is_delete' => ShareLevel::SHARE_NOT_DELETE, 'status' => ShareLevel::STATUS_ON])
  394. ->select('level id, name')->orderBy('level ASC')->asArray()->all();
  395. $share_level = array_merge([[
  396. 'id' => 0,
  397. 'name' => '默认等级'
  398. ]], $share_level);
  399. // if ((!is_null($this->attr_setting_type)) && intval($this->attr_setting_type) === 1) {
  400. // $attr = json_decode($this->attr, true);
  401. // foreach ($attr as $attr_) {
  402. // foreach ($share_level as $share_level_) {
  403. // if (empty($attr_['share_commission_level_' . $share_level_['id']])) {
  404. // $this->addError('type', '操作失败,分销详细模式等级【' . $share_level_['name'] . '】为空');
  405. // return false;
  406. // }
  407. // if (
  408. // !isset($attr_['share_commission_level_' . $share_level_['id']]['share_commission_first'])
  409. // || !isset($attr_['share_commission_level_' . $share_level_['id']]['share_commission_second'])
  410. // || !isset($attr_['share_commission_level_' . $share_level_['id']]['share_commission_third'])
  411. // ) {
  412. // $this->addError('type', '操作失败,分销详细模式等级【' . $share_level_['name'] . '】分销内容不完整');
  413. // return false;
  414. // }
  415. // }
  416. //
  417. // }
  418. // } else
  419. if ((!is_null($this->attr_setting_type)) && intval($this->attr_setting_type) === 0) {
  420. $share_commission_new_first = json_decode($this->share_commission_new_first, true);
  421. foreach ($share_level as $share_level_) {
  422. $share_commission_new_first['share_commission_level_' . $share_level_['id']] = $share_commission_new_first['share_commission_level_' . $share_level_['id']] ?? 0;
  423. }
  424. $this->share_commission_new_first = json_encode($share_commission_new_first);
  425. $share_commission_new_second = json_decode($this->share_commission_new_second, true);
  426. foreach ($share_level as $share_level_) {
  427. $share_commission_new_second['share_commission_level_' . $share_level_['id']] = $share_commission_new_second['share_commission_level_' . $share_level_['id']] ?? 0;
  428. }
  429. $this->share_commission_new_second = json_encode($share_commission_new_second);
  430. $share_commission_new_third = json_decode($this->share_commission_new_third, true);
  431. foreach ($share_level as $share_level_) {
  432. $share_commission_new_third['share_commission_level_' . $share_level_['id']] = $share_commission_new_third['share_commission_level_' . $share_level_['id']] ?? 0;
  433. }
  434. $this->share_commission_new_third = json_encode($share_commission_new_third);
  435. }
  436. }
  437. if ($this->dirtyAttributes && ($this->dirtyAttributes['attr'] || isset($this->dirtyAttributes['use_attr']))) {
  438. $this->setActivityAttr($this->id, $this->attr, $this->use_attr);
  439. }
  440. //加价保护start
  441. $platform_profit_strategy = Option::get('platform_profit_strategy', 0, 'store')['value'];
  442. $platform_profit_strategy = json_decode($platform_profit_strategy, true);
  443. if (!empty($platform_profit_strategy)) {
  444. $result = $this->getMarkupProtectionRules($this->price, $this->dirtyAttributes['attr'], $this->cloud_goods_id);
  445. if (intval($platform_profit_strategy['is_risk_control']) && $result['platform_negotiated_price_error'] && $this->id && intval($this->status) === 1) {
  446. //开启风控
  447. $id = \Yii::$app->cache->get('risk_control_model_id');
  448. if ($id && !\Yii::$app->queue->isDone($id)) {//\Yii::$app->queue->status($id)
  449. \Yii::$app->queue->remove($id);
  450. }
  451. $id =\queue_push(new \app\jobs\RiskControlModelJob(['risk_control_model' => $platform_profit_strategy['risk_control_model'], 'goods_id' => $this->id]));
  452. \Yii::$app->cache->set('risk_control_model_id', $id);
  453. // $form = new RiskControlForm();
  454. // $form->riskControlHandle($platform_profit_strategy['risk_control_model'], $this->id);
  455. }
  456. // if (intval($platform_profit_strategy['is_markup_protection'])) {
  457. // if (!empty($platform_profit_strategy['markup_protection_rules'])) {
  458. // $markup_protection_rules = $platform_profit_strategy['markup_protection_rules'];
  459. // $rules_price = 0;
  460. // $rules_attr_price = [];
  461. // $title = "";
  462. // if (intval($markup_protection_rules['title']) === 0) {
  463. // $title = "利润";
  464. // //规则名称:0 利润
  465. // $rules_price = $result['goods_rules_price'];
  466. // $rules_attr_price = $result['goods_attr_rules_price'];
  467. // }
  468. // $compare = "";
  469. // if (intval($markup_protection_rules['compare']) === 0) {
  470. // //比较符号 0小于 1小于等于 2等于 3大于等于 4大于
  471. // }
  472. // $open = false;
  473. // if ($markup_protection_rules['price'] > 0) {
  474. // //价格
  475. // if ($rules_price > 0) {
  476. // switch ($markup_protection_rules['compare']) {
  477. // case 1:
  478. // $compare = "小于等于";
  479. // if ($rules_price <= $markup_protection_rules['price']) {
  480. // $open = true;
  481. // }
  482. // break;
  483. // case 2:
  484. // $compare = "等于";
  485. // if (floatval($rules_price) == floatval($markup_protection_rules['price'])) {
  486. // $open = true;
  487. // }
  488. // break;
  489. // case 3:
  490. // $compare = "大于等于";
  491. // if ($rules_price >= $markup_protection_rules['price']) {
  492. // $open = true;
  493. // }
  494. // break;
  495. // case 4:
  496. // $compare = "大于";
  497. // if ($rules_price > $markup_protection_rules['price']) {
  498. // $open = true;
  499. // }
  500. // break;
  501. // default:
  502. // $compare = "小于";
  503. // if ($rules_price < $markup_protection_rules['price']) {
  504. // $open = true;
  505. // }
  506. // break;
  507. // }
  508. // }
  509. //
  510. // if (!empty($rules_attr_price)) {
  511. // foreach ($rules_attr_price as $price_item) {
  512. // switch ($markup_protection_rules['compare']) {
  513. // case 1:
  514. // if ($price_item <= $markup_protection_rules['price']) {
  515. // $open = true;
  516. // }
  517. // break;
  518. // case 2:
  519. // if (floatval($price_item) == floatval($markup_protection_rules['price'])) {
  520. // $open = true;
  521. // }
  522. // break;
  523. // case 3:
  524. // if ($price_item >= $markup_protection_rules['price']) {
  525. // $open = true;
  526. // }
  527. // break;
  528. // case 4:
  529. // if ($price_item > $markup_protection_rules['price']) {
  530. // $open = true;
  531. // }
  532. // break;
  533. // default:
  534. // if ($price_item < $markup_protection_rules['price']) {
  535. // $open = true;
  536. // }
  537. // break;
  538. // }
  539. // }
  540. // }
  541. //
  542. // }
  543. // if (intval($markup_protection_rules['operate']) === 0) {
  544. // //操作
  545. // $attribute_title = "price";
  546. // if ($open && $this->dirtyAttributes['price']) {
  547. // $this->price = $this->oldAttributes['price'];
  548. // }
  549. //
  550. // if ($open && !empty($this->dirtyAttributes['attr'])) {
  551. // $attribute_title = "attr.price";
  552. // $this->attr = $this->oldAttributes['attr'];
  553. // }
  554. // if ($open) {
  555. // $this->addError($attribute_title, '错误:' . $title . $compare . $markup_protection_rules['price']);
  556. // return false;
  557. // }
  558. // }
  559. //
  560. // }
  561. // }
  562. }
  563. //加价保护end
  564. return parent::beforeSave($insert);
  565. }
  566. public function getMarkupProtectionRules($price, $attr, $cloud_goods_id) {
  567. $goods_rules_price = 0;
  568. $goods_attr_rules_price = [];
  569. $platform_negotiated_price_error = false;
  570. if ($cloud_goods_id > 0) {
  571. //获取云仓商品
  572. $cloud_url = "/goods/getGoodsInfo";
  573. $cloud_data = [];
  574. $cloud_data['goods_id'] = $cloud_goods_id;
  575. $domain = (new OptionSetting)->getCloudDomainName();
  576. $cloud_info = cloud_post($domain . $cloud_url, $cloud_data);
  577. $cloud_info = json_decode($cloud_info, true);
  578. if($cloud_info['code'] != 0){
  579. //debug_log($cloud_info, 'risk_control_result.log');
  580. }else{
  581. //获取商家利润 商家售价-平台供货价
  582. $cloud_goods = $cloud_info['data']['goods'];
  583. $goods_rules_price = floatval(sprintf('%.2f', $price - $cloud_goods['platform_negotiated_price']));
  584. //新增风控判断 商品售价小于平台协议价
  585. if ($price < $cloud_goods['platform_negotiated_price']) {
  586. $platform_negotiated_price_error = true;
  587. }
  588. if (!empty($attr)) {
  589. //规格中的云仓商品协议价大于商品售价处理
  590. $attr = json_decode($attr, true);
  591. $cloud_goods['attrs'] = json_decode($cloud_goods['attrs'], true);
  592. foreach ($cloud_goods['attrs'] as $cloud_attr_item) {
  593. $cloud_no = $cloud_attr_item['no'];
  594. foreach ($attr as &$attr_item) {
  595. $_no = $attr_item['no'];
  596. if (!empty($cloud_no) && !empty($_no) && $_no == $cloud_no) {
  597. $attr_rules_price = floatval(sprintf('%.2f', $attr_item['price'] -
  598. (!empty($cloud_attr_item['platform_negotiated_price']) ? $cloud_attr_item['platform_negotiated_price'] : $cloud_attr_item['price'])
  599. ));
  600. array_push($goods_attr_rules_price, $attr_rules_price);
  601. //新增风控判断 商品售价小于平台协议价
  602. if ($attr_item['price'] < (!empty($cloud_attr_item['platform_negotiated_price']) ? $cloud_attr_item['platform_negotiated_price'] : $cloud_attr_item['price'])
  603. ) {
  604. $platform_negotiated_price_error = true;
  605. }
  606. }
  607. }
  608. }
  609. }
  610. }
  611. }
  612. return [
  613. 'goods_rules_price' => $goods_rules_price,
  614. 'goods_attr_rules_price' => $goods_attr_rules_price,
  615. 'platform_negotiated_price_error' => $platform_negotiated_price_error
  616. ];
  617. }
  618. public function afterSave($insert, $changedAttributes)
  619. {
  620. parent::afterSave($insert, $changedAttributes);
  621. \Yii::error([__METHOD__, $insert, $changedAttributes]);
  622. if (($this->yinbaoSync == 0)) {
  623. (new PospalForm(['store_id' => $this->store_id]))->afterGoodsSave($this, $changedAttributes);
  624. }
  625. \app\modules\admin\models\jushuitan\JuShuiTanForm::afterGoodsSave($this);
  626. \app\modules\admin\models\erp\InventoryForm::afterGoodsSave($this, $insert, $changedAttributes);
  627. if(!$insert && in_array('cover_pic',array_keys($changedAttributes))){
  628. // 通知修改了商品主图 删除之前的商品图 并上传新的商品主图
  629. (new UploadImageForm())->updateGoodsImage($this->id);
  630. }
  631. /* 2024年3月9日16:31:13 begin WPing id999新需求:降价通知 */
  632. // if(!$insert && in_array('price',array_keys($changedAttributes))){
  633. // if($this->price < $changedAttributes['price']) {//如果降价了
  634. // GoodsLoweringPrice::sendMsg($this->id, $this->store_id, $this->price, $changedAttributes['price']);
  635. // }
  636. // }
  637. if(!$insert && in_array('attr',array_keys($changedAttributes))){
  638. // //debug_log('规格被修改,走进来了');
  639. $before_goods = [
  640. 'id' => $this->id,
  641. 'attr' => array_key_exists('attr',$changedAttributes) ? $changedAttributes['attr'] : $this->attr,
  642. 'price' => array_key_exists('price',$changedAttributes) ? $changedAttributes['price'] : $this->price,
  643. 'mch_id' => array_key_exists('mch_id',$changedAttributes) ? $changedAttributes['mch_id'] : $this->mch_id,
  644. 'is_level' => array_key_exists('is_level',$changedAttributes) ? $changedAttributes['is_level'] : $this->is_level,
  645. ];
  646. GoodsLoweringPrice::sendMsg($this->id, $this->store_id, $before_goods);
  647. }
  648. /* end */
  649. //获取禁售目录
  650. $form = new MerchantForm();
  651. $form->store_id = $this->store_id;
  652. $result = $form->getCloudForbiddenGoods();
  653. if ($result['code'] === 0) {
  654. $cloud_goods_id = $result['data']['goods_id'];
  655. //如果当前云仓id在禁售目录就禁售
  656. if (in_array($this->cloud_goods_id, $cloud_goods_id)) {
  657. VideoShopGoods::updateAll(['is_forbidden' => 1, 'is_delete' => 1], ['id' => $this->id]);
  658. }
  659. }
  660. (new DiyCommon)->JobBehaviors($this->store_id, StoreSyncExtLog::TYPE_PRODUCT, [$this->id]);
  661. }
  662. //更改规格之后修改营销活动产品规格
  663. public function setActivityAttr($id, $attr, $use_attr) {
  664. try {
  665. $attr = json_decode($attr, true);
  666. //拼团
  667. $pt_goods_list = PtActivityGoods::find()->where(['is_delete' => 0, 'goods_id' => $id])->all();
  668. $this->activityAttrHandle($attr, $pt_goods_list, 'pt_price');
  669. //砍价
  670. $cut_goods_list = ActivityCutPriceGoods::find()->where(['is_delete' => 0, 'goods_id' => $id])->all();
  671. $this->activityAttrHandle($attr, $cut_goods_list, 'price', 1);
  672. //秒杀
  673. $seckill_goods_list = SeckillActivityGoods::find()->where(['is_delete' => 0, 'goods_id' => $id])->all();
  674. $this->activityAttrHandle($attr, $seckill_goods_list, 'seckill_price', 2);
  675. //新人
  676. $new_user_goods_list = ActivityNewUserGoods::find()->where(['is_delete' => 0, 'goods_id' => $id])->all();
  677. $this->activityAttrHandle($attr, $new_user_goods_list, 'price', 3);
  678. //新人专享
  679. } catch (\Exception $e) {
  680. //debug_log($e->getMessage(), 'Exception.log');
  681. }
  682. }
  683. /**
  684. * $goods_attr 商品规格
  685. * $activity_goods_list 活动产品
  686. * $price_name 价格名称
  687. * $type 活动类型
  688. */
  689. public function activityAttrHandle($goods_attr, $activity_goods_list, $price_name, $type = 0) {
  690. foreach ($activity_goods_list as $activity_goods_item) {
  691. $activity_goods = ArrayHelper::toArray($activity_goods_item);
  692. $ext_attrs = json_decode($activity_goods['attr'], true);
  693. $new_attr = [];
  694. foreach($goods_attr as $attr_index => &$attr_item){
  695. if (intval($this->use_attr) === 0) {
  696. if ($attr_index > 0) {
  697. continue;
  698. }
  699. }
  700. $open = false;
  701. foreach($ext_attrs as $ext_attr){
  702. $ext_attr_id = array_column($ext_attr['attr_list'], 'attr_id');
  703. $attr_id = array_column($attr_item['attr_list'], 'attr_id');
  704. sort($ext_attr_id);
  705. sort($attr_id);
  706. if($attr_id == $ext_attr_id){
  707. $open = true;
  708. //活动价格
  709. $attr_item[$price_name] = $ext_attr[$price_name] ?: $attr_item['price'];
  710. //活动库存
  711. $attr_item['num'] = $ext_attr['num'];
  712. //商品原售价
  713. switch ($type) {
  714. case 3://新人
  715. case 1://砍价
  716. $attr_item['oldPrice'] = $attr_item['price'];
  717. break;
  718. case 2://秒杀
  719. $attr_item['seckill_num'] = $ext_attr['seckill_num'];
  720. break;
  721. }
  722. }
  723. }
  724. if (!$open) {
  725. $attr_item[$price_name] = $attr_item['price'];
  726. }
  727. $new_attr[] = $attr_item;
  728. }
  729. $activity_goods_item->attr = json_encode($new_attr, JSON_UNESCAPED_UNICODE);
  730. $activity_goods_item->save();
  731. }
  732. }
  733. public static function skuAttr(&$goods, $goods_attr_item = []) {
  734. $sku_attr = [];
  735. try {
  736. $attr_ids = array_column($goods_attr_item['attr_list'] ?? $goods_attr_item, 'attr_id');
  737. sort($attr_ids);
  738. $sku_attr_ids = implode('_', $attr_ids);
  739. $attrs = json_decode($goods['attr'], true);
  740. foreach($attrs as &$attr){
  741. $attr['cyy_id'] = 'cyy_' . $goods['id'];
  742. $attr['cyy_skuId'] = self::skuid1($goods['id'], $attr);
  743. $attr_ids = array_column($attr['attr_list'], 'attr_id');
  744. sort($attr_ids);
  745. $attr['attr_ids'] = implode(',', $attr_ids);
  746. $item_attr_ids = implode('_', $attr_ids);
  747. if($item_attr_ids === $sku_attr_ids){
  748. $sku_attr = $attr;
  749. }
  750. }
  751. $goods['attr'] = json_encode($attrs);
  752. } catch (\Exception $e) {
  753. \Yii::error([$e, $goods, $attr]);
  754. \Yii::error([__METHOD__, $e->getMessage()]);
  755. }
  756. return $sku_attr;
  757. }
  758. public static function goodsIdOriginal($cyy_id = '') {
  759. return substr($cyy_id, strpos($cyy_id, '_') + 1);
  760. }
  761. public static function skuAttrOriginal(&$goods, $cyy_skuId = '') {
  762. $sku_attr = [];
  763. try {
  764. self::skuAttr($goods);
  765. $attrs = json_decode($goods['attr'], true);
  766. foreach($attrs as &$attr){
  767. if($cyy_skuId === $attr['cyy_skuId']){
  768. $sku_attr = $attr;
  769. }
  770. }
  771. } catch (\Exception $e) {
  772. \Yii::error($e);
  773. \Yii::error([__METHOD__, $e->getMessage()]);
  774. }
  775. return $sku_attr;
  776. }
  777. public static function skuid1($id, $goods_attr_item = []) {
  778. $attr_ids = array_column($goods_attr_item['attr_list'] ?? $goods_attr_item, 'attr_id');
  779. sort($attr_ids);
  780. return 'cyy_' . $id . '_' . implode('_', $attr_ids);
  781. }
  782. public static function skuid2($id, $goods_attr_item = []) {
  783. return $goods_attr_item['no'];
  784. }
  785. public static function getSkuIdAttr($goods, $skuid = '') {
  786. self::skuAttr($goods);
  787. $attrs = json_decode($goods['attr'], true);
  788. foreach($attrs as $attr){
  789. if($attr['cyy_skuId'] === $skuid){
  790. return $attr;
  791. }
  792. }
  793. return [];
  794. }
  795. /**
  796. * @param array $arr | status 状态 name 名称 store_id 商城id
  797. * @return array
  798. */
  799. public static function getAllianceList ($arr = [])
  800. {
  801. $query = VideoShopGoods::find()->alias('g')
  802. ->where(['g.is_delete' => 0, 'g.md_food_id' => 0])->andWhere(['not like', 'g.name', '当面付']);
  803. if (isset($arr['status']) && $arr['status'] > -1) {
  804. $query->andWhere([
  805. 'g.status' => $arr['status']
  806. ]);
  807. }
  808. $query->andWhere(['AND', ['<>', 'g.store_id', 0], ['<>', 'g.product_type', 4]]);
  809. if (isset($arr['store_id']) && $arr['store_id'] > 0){
  810. $query->andWhere(['store_id'=>$arr['store_id']]);
  811. }
  812. if (isset($arr['name']) && !empty($arr['name'])) {
  813. $query->andWhere([
  814. 'like',
  815. 'g.name',
  816. $arr['name']
  817. ]);
  818. }
  819. $select = ['g.id', 'g.name', 'g.status','g.store_id', 'g.service',
  820. 'g.updated_at', 'g.virtual_sales', 'g.is_verify', 'g.is_negotiable',
  821. 'g.price', 'g.goods_num', 'g.sort' ,'g.cover_pic', 'g.original_price',
  822. 'g.quick_purchase', 'g.attr', 'g.mch_id', 'g.detail', 'g.use_attr', 'g.product_type', 'g.is_recommend','g.store_id'];
  823. $query->select($select)->orderBy(['g.sort' => SORT_ASC, 'g.id' => SORT_DESC]);
  824. $pagination = pagination_make($query);
  825. $pagination['data'] = $pagination['list'];
  826. foreach($pagination['data'] as $k => $v) {
  827. $goods_cat = GoodsCat::find()->alias('gc')
  828. ->leftJoin(['c' => Cat::tableName()], 'gc.cat_id=c.id')
  829. ->where([ 'gc.goods_id' => $v['id'] ])
  830. ->select(['c.name'])
  831. ->asArray()
  832. ->all();
  833. $pagination['data'][$k]['cat'] = $goods_cat;
  834. if($v['store_id']>0){
  835. $pagination['data'][$k]['storeInfo'] = Store::find()->where(['id'=>$v['store_id'],'is_delete'=>0])->select(['id', 'name', 'logo', 'coordinate', 'created_at', 'category_id', 'tags', 'sales', 'rank', 'per_spend','business_model','address'])->asArray()->one();
  836. $wechatInfo = WechatConfig::find()->where(['store_id'=>$v['store_id'],'is_delete'=>0,'type'=>1])->asArray()->one();
  837. if(isset($pagination['data'][$k]['storeInfo']['id']) && $pagination['data'][$k]['storeInfo']['id']>0){
  838. if($wechatInfo){
  839. $pagination['data'][$k]['storeInfo']['wechat_app_id'] = $wechatInfo['app_id'];
  840. }
  841. $alipayInfo = Option::get('alipay_config',$v['store_id'],'alipay');
  842. if($alipayInfo && $alipayInfo['value']){
  843. $alipayInfo = json_decode($alipayInfo['value'],true);
  844. $pagination['data'][$k]['storeInfo']['alipay_app_id'] = $alipayInfo['app_id'];
  845. }
  846. }
  847. }
  848. }
  849. unset($pagination['list']);
  850. $book_goods_ids = self::checkBookGoods();
  851. return [
  852. 'code' => 0,
  853. 'msg' => 'success',
  854. 'book_goods_ids' => $book_goods_ids,
  855. 'data' => $pagination
  856. ];
  857. }
  858. /**
  859. * @param array $arr | status 状态 name 名称 cat_id 分类id mch_id 入驻商 is_verify 审核 is_league 已设置联盟券 select 查询数据
  860. * @return array
  861. */
  862. public static function getList ($arr = [])
  863. {
  864. $query = VideoShopGoods::find()->alias('g')
  865. ->leftJoin(['wh' => Warehouse::tableName()], 'wh.id = g.warehouse_id')
  866. ->leftJoin(['whz' => WarehouseZone::tableName()], 'whz.id = g.warehouse_zone_id')
  867. ->where(['g.store_id' => get_store_id(), 'g.is_delete' => 0, 'g.md_food_id' => 0])->andWhere(['not like', 'g.name', '当面付']);
  868. if (isset($arr['cloud_inventory_id'])){
  869. if (!empty($arr['cloud_inventory_id'])){
  870. $query = $query->andWhere(['>', 'g.cloud_inventory_id', 0]);
  871. }else {
  872. $query = $query->andWhere(['=', 'g.cloud_inventory_id', 0]);
  873. }
  874. }
  875. if (!empty($arr['select'])) {
  876. $select = $arr['select'];
  877. } else {
  878. $select = ['g.id', 'g.name', 'g.status', 'g.service','g.integral_price','wh.name as wh_name','whz.name as whz_name',
  879. 'g.updated_at', 'g.virtual_sales', 'g.is_verify', 'g.is_negotiable',
  880. 'g.price', 'g.goods_num', 'g.sort' ,'g.cover_pic', 'g.original_price',
  881. 'g.quick_purchase', 'g.attr', 'g.detail', 'g.use_attr',
  882. 'g.product_type', 'g.is_recommend', 'g.cloud_supplier_id', 'g.delivery_rules_id',
  883. 'g.time_made_day', 'g.time_shelf_life',
  884. 'g.mch_id', 'g.mch_audit', 'g.mch_audit_time',
  885. 'g.cost_price', 'g.goods_no', 'g.goods_take_price', 'g.goods_send_profit', 'g.cloud_goods_id', 'g.brand_id', 'g.is_risk', 'g.accessories_image', 'g.cloud_inventory_id'];
  886. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_WORKER) {
  887. $select = array_merge($select, ['wge.desc']);
  888. }
  889. }
  890. $sort = '';
  891. $sort_warn_goods_timeout = 0;
  892. $warn_goods_timeout = self::warn_goods_timeout(get_store_id());
  893. if (isset($arr['warn_goods_timeout'])) {
  894. if($warn_goods_timeout){
  895. $sort_warn_goods_timeout = 1;
  896. $query->andWhere(['>', 'g.time_made_day', 0]);
  897. $query->andWhere(['<', '(g.time_made_day + g.time_shelf_life * 86400)', (time() + $warn_goods_timeout * 86400)]);
  898. }
  899. }
  900. if (($arr['warn_goods_timeout_begin_time'])) {
  901. $sort_warn_goods_timeout = 1;
  902. $query->andWhere(['>', 'g.time_made_day', 0]);
  903. $query->andWhere(['>=', '(g.time_made_day + g.time_shelf_life * 86400)', strtotime($arr['warn_goods_timeout_begin_time'])]);
  904. }
  905. if (($arr['warn_goods_timeout_end_time'])) {
  906. $sort_warn_goods_timeout = 1;
  907. $query->andWhere(['>', 'g.time_made_day', 0]);
  908. $query->andWhere(['<', '(g.time_made_day + g.time_shelf_life * 86400)', strtotime($arr['warn_goods_timeout_end_time']) + 86400]);
  909. }
  910. if($sort_warn_goods_timeout){
  911. $select = array_merge($select, ['(g.time_made_day + g.time_shelf_life * 86400) as sort_warn_goods_timeout']);
  912. $sort = 'sort_warn_goods_timeout asc';
  913. }
  914. if ((isset($arr['mch']) && $arr['mch'] == 1)) {
  915. if($arr['mch_id'] > 0){
  916. $query->andWhere(['g.mch_id' => $arr['mch_id']]);
  917. }else{
  918. $query->andWhere(['>', 'g.mch_id', 0]);
  919. $query->andWhere(['g.mch_id' => Mch::find()->select('id')->where(['store_id' => get_store_id(), 'is_delete' => 0])]);
  920. }
  921. if (isset($arr['mch_audit']) && $arr['mch_audit'] > -1) {
  922. $query->andWhere(['g.mch_audit' => $arr['mch_audit']]);
  923. }
  924. if ($arr['mch_audit_time_begin']) {
  925. $query->andWhere(['>=', 'mch_audit_time', strtotime($arr['mch_audit_time_begin'])]);
  926. }
  927. if ($arr['mch_audit_time_end']) {
  928. $query->andWhere(['<=', 'mch_audit_time', strtotime($arr['mch_audit_time_end'])]);
  929. }
  930. if (isset($arr['mch_common_cat_id']) && $arr['mch_common_cat_id'] > 0) {
  931. $query->andWhere(['g.mch_id' => Mch::find()->select('id')->where(['store_id' => get_store_id(), 'mch_common_cat_id' => $arr['mch_common_cat_id']])]);
  932. }
  933. }else{
  934. $query->andWhere(['g.mch_id' => 0]);
  935. }
  936. if (isset($arr['status']) && $arr['status'] > -1) {
  937. $query->andWhere([
  938. 'g.status' => $arr['status']
  939. ]);
  940. }
  941. if (!empty($arr['goods_no'])) {
  942. $query->andWhere([
  943. 'g.goods_no' => $arr['goods_no']
  944. ]);
  945. }
  946. //智配图片商品去除
  947. if (!empty($arr['is_accessories'])) {
  948. $query->andWhere(['OR', [
  949. 'g.accessories_image' => ''
  950. ], [
  951. 'IS', 'g.accessories_image', NULL
  952. ]
  953. ]);
  954. }
  955. if (!empty($arr['is_verify_card'])) {
  956. $query->andWhere([
  957. 'g.product_type' => 0,
  958. 'g.status' => 1
  959. ]);
  960. } else {
  961. if (isset($arr['product_type']) && in_array($arr['product_type'], VideoShopGoods::$validProductType)) {
  962. $query->andWhere([
  963. 'g.product_type' => $arr['product_type']
  964. ]);
  965. }else{
  966. //剔除掉积分商品
  967. $query->andWhere([
  968. 'g.product_type' => [VideoShopGoods::GOODS_TYPE_NORMAL,VideoShopGoods::GOODS_TYPE_DATE,VideoShopGoods::GOODS_TYPE_TIME,VideoShopGoods::GOODS_TYPE_VIRTUAL,VideoShopGoods::GOODS_TYPE_ADOPT]
  969. ]);
  970. }
  971. }
  972. //是否是云仓商品
  973. if (isset($arr['is_cloud']) && $arr['is_cloud'] ) {
  974. $query->andWhere([ '>', 'g.cloud_goods_id' , 0 ]);
  975. }
  976. //是否拼团商品
  977. if (isset($arr['is_pt']) && $arr['is_pt'] ) {
  978. $time = time();
  979. $pt_activity_id = PtActivity::find()->where(['is_delete' => 0, 'store_id' => get_store_id()])
  980. ->andWhere(['AND', ['<', 'start_time', $time], ['>', 'end_time', $time]])->select('id')
  981. ->column();
  982. $queryPt = PtActivityGoods::find()->alias('pag')->where(['pag.is_delete' => 0, 'g.status' => 1, 'g.is_delete' => 0])
  983. ->andWhere(['pag.activity_id' => $pt_activity_id])
  984. ->leftJoin(['g' => VideoShopGoods::tableName()], 'pag.goods_id = g.id')
  985. ->select('g.id');
  986. $query->andWhere(['g.id' => $queryPt]);
  987. $query->leftJoin(['pag' => PtActivityGoods::tableName()], 'g.id = pag.goods_id');
  988. $query->leftJoin(['pa' => PtActivity::tableName()], 'pa.id = pag.activity_id');
  989. $select = array_merge($select, ['pa.party_size', 'pa.party_type', 'pa.party_goods_count']);
  990. }
  991. // $query->leftJoin(['sp' => Supplier::tableName()], 'sp.cloud_supplier_id = g.cloud_supplier_id');
  992. //价格区间
  993. if (!empty($arr['price_type'])) {
  994. if ((int)$arr['price_type'] === 1) {
  995. if ($arr['low_price']) {
  996. $query->andWhere(['>=', 'g.cost_price', $arr['low_price']]);
  997. }
  998. if ($arr['high_price']) {
  999. $query->andWhere(['<=', 'g.cost_price', $arr['high_price']]);
  1000. }
  1001. }
  1002. if ((int)$arr['price_type'] === 2) {
  1003. if ($arr['low_price']) {
  1004. $query->andWhere(['>=', 'g.price', $arr['low_price']]);
  1005. }
  1006. if ($arr['high_price']) {
  1007. $query->andWhere(['<=', 'g.price', $arr['high_price']]);
  1008. }
  1009. }
  1010. }
  1011. if (isset($arr['low_num']) && $arr['low_num']) {
  1012. $query->andWhere(['>=', 'g.goods_num', $arr['low_num']]);
  1013. }
  1014. if (isset($arr['high_num']) && $arr['high_num']) {
  1015. $query->andWhere(['<=', 'g.goods_num', $arr['high_num']]);
  1016. }
  1017. if (isset($arr['supplier_id']) && $arr['supplier_id']) {
  1018. $query->andWhere(['g.cloud_supplier_id' => $arr['supplier_id']]);
  1019. }
  1020. if (isset($arr['delivery_rules_id']) && $arr['delivery_rules_id']) {
  1021. $query->andWhere(['g.delivery_rules_id' => $arr['delivery_rules_id']]);
  1022. }
  1023. if (isset($arr['name']) && !empty($arr['name'])) {
  1024. $query->andWhere([
  1025. 'or',
  1026. ['like', 'g.name', $arr['name']],
  1027. ['like', 'g.key_word', $arr['name']],
  1028. ]);
  1029. }
  1030. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_WORKER) {
  1031. $query->leftJoin(['wge' => WorkerGoodsExt::tableName()], 'g.id = wge.goods_id');
  1032. }
  1033. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_TIME) {
  1034. $query->leftJoin(['bge' => BookingGoodsExt::tableName()], 'g.id = bge.goods_id');
  1035. }
  1036. if (isset($arr['cat_id']) && $arr['cat_id'] > 0) {
  1037. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_WORKER) {
  1038. $query->andWhere(['wge.cat_id' => $arr['cat_id']]);
  1039. } else if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_TIME){
  1040. $query->andWhere(['bge.cat_id' => $arr['cat_id']]);
  1041. } else {
  1042. if ($arr['mch_id'] > 0) {
  1043. $query->leftJoin(['mgc' => MchGoodsCat::tableName()], 'g.id = mgc.goods_id')->andWhere([
  1044. 'mgc.cat_id' => MchCat::getCatId($arr['cat_id'])
  1045. ])->groupBy('mgc.goods_id');
  1046. } else {
  1047. $query->leftJoin(['gc' => GoodsCat::tableName()], 'g.id = gc.goods_id')->andWhere([
  1048. 'gc.cat_id' => Cat::getCatId($arr['cat_id'])
  1049. ])->groupBy('gc.goods_id');
  1050. }
  1051. }
  1052. }
  1053. //门店增加收银台 查询商品列表逻辑
  1054. if ($arr['md_id'] && $arr['md_id'] > 0) {
  1055. $md = Md::findOne($arr['md_id']);
  1056. if ($md && intval($md->is_single)) {
  1057. $query->leftJoin(['mg' => MdGoods::tableName()], 'g.id = mg.goods_id')->andWhere(['mg.md_id' => $arr['md_id'], 'mg.status' => 1]);
  1058. $select = array_merge($select, ['md_goods_price' => 'mg.price', 'md_goods_num' => 'mg.goods_num', 'md_goods_attr' => 'mg.attr']);
  1059. }
  1060. }
  1061. if (isset($arr['mch_cat_id']) && $arr['mch_cat_id'] > 0) {
  1062. $query->leftJoin(['mgc' => MchGoodsCat::tableName()], 'g.id = mgc.goods_id')->andWhere([
  1063. 'mgc.cat_id' => MchCat::getCatId($arr['mch_cat_id'])
  1064. ])->groupBy('mgc.goods_id');
  1065. }
  1066. // 根据入驻商查询 0 平台 -1 全部入驻商 >0 对应入驻商
  1067. // if (empty($arr['mch_id'])) {
  1068. // $query->andWhere(['g.mch_id' => 0]);
  1069. // } elseif(isset($arr['mch_id']) && $arr['mch_id'] == -1) {
  1070. // $query->andWhere([
  1071. // '>',
  1072. // 'g.mch_id',
  1073. // 0
  1074. // ]);
  1075. // } elseif (isset($arr['mch_id']) && $arr['mch_id'] > 0){
  1076. // $query->andWhere(['g.mch_id' => $arr['mch_id']]);
  1077. // }
  1078. // 获取入驻商待审核商品
  1079. if (isset($arr['is_verify'])) {
  1080. $query->andWhere([
  1081. 'g.is_verify' => $arr['is_verify']
  1082. ]);
  1083. }
  1084. if (isset($arr['is_league']) && $arr['is_league'] > -1) {
  1085. if ($arr['is_league'] == 1) {
  1086. $query->andWhere([
  1087. 'or',
  1088. ['>', 'goods_take_price', 0],
  1089. ['>', 'goods_send_profit', 0],
  1090. ]);
  1091. }else{
  1092. $query->andWhere([
  1093. 'and',
  1094. [
  1095. 'or',
  1096. ['goods_take_price' => 0],
  1097. ['goods_take_price' => null],
  1098. ],
  1099. [
  1100. 'or',
  1101. ['goods_send_profit' => 0],
  1102. ['goods_send_profit' => null],
  1103. ],
  1104. ]);
  1105. }
  1106. }
  1107. $query->select($select);
  1108. if (!empty($arr['sort'])) {
  1109. $query->orderBy(['g.sort' => $arr['sort'] == 'asc' ? SORT_ASC : SORT_DESC, 'g.id' => SORT_DESC]);
  1110. } else {
  1111. $query->orderBy(['g.id' => SORT_DESC]);
  1112. }
  1113. if($sort){
  1114. $query->orderBy($sort);
  1115. }
  1116. // return $query->createCommand()->getRawSql();
  1117. $pagination = pagination_make($query);
  1118. if (isset($arr['mch']) && $arr['mch'] == 1) {
  1119. $mchList = (new MchForm(['store_id' => get_store_id()]))->mchSelectList();
  1120. $mchCommonCatSelectList = (new MchForm(['store_id' => get_store_id()]))->mchCommonCatSelectList();
  1121. }
  1122. $list = $pagination['list'];
  1123. foreach($list as &$item) {
  1124. if (isset($arr['mch']) && $arr['mch'] == 1) {
  1125. $item['mch'] = $mchList['data'][$item['mch_id']];
  1126. $item['mch_common_cat'] = $mchCommonCatSelectList['data'][$item['mch']['mch_common_cat_id']];
  1127. $goods_cat = MchGoodsCat::find()->alias('mgc')
  1128. ->leftJoin(['mc' => MchCat::tableName()], 'mgc.cat_id=mc.id')
  1129. ->where([ 'mgc.goods_id' => $item['id'] ])
  1130. ->select(['mc.name'])
  1131. ->asArray()
  1132. ->all();
  1133. $item['mch_cat'] = $goods_cat;
  1134. }
  1135. $item['warehouse_name'] = $item['wh_name'].'-'.$item['whz_name'];
  1136. $item['timeout_day'] = $item['time_made_day'] ? date('Y-m-d', $item['time_made_day'] + 86400 * $item['time_shelf_life']) : '--';
  1137. $item['is_warn_goods_timeout'] = ($item['time_made_day'] && ($item['time_made_day'] + 86400 * $item['time_shelf_life']) < (time() + $warn_goods_timeout * 86400)) ? 1 : 0;
  1138. //品牌
  1139. $item['brand_name'] = self::getBrand($item['brand_id']) ?: '暂无品牌';
  1140. //门店增加收银台 查询商品列表逻辑
  1141. if ($arr['md_id'] && $arr['md_id'] > 0) {
  1142. $item['price'] = $item['md_goods_price'] ?: $item['price'];
  1143. $item['goods_num'] = $item['md_goods_num'] ?: $item['goods_num'];
  1144. $item['attr'] = $item['md_goods_attr'] ?: $item['attr'];
  1145. }
  1146. $delivery_rules = DeliveryRules::find()->where(['id' => $item['delivery_rules_id'], 'is_delete' => 0, 'store_id' => get_store_id()])->select('type, times, days')->asArray()->one();
  1147. if ($delivery_rules) {
  1148. $delivery_rules['times'] = (int)$delivery_rules['type'] === 1 ? '' : date("m月d日 H:i:s", $delivery_rules['times']);
  1149. }
  1150. $supplier = Supplier::findOne(['cloud_supplier_id'=>$item['cloud_supplier_id']]);
  1151. $item['supplier_name'] = $supplier->supplier_name ?: ($supplier->name ?: '');
  1152. $item['supplier_logo'] = $supplier->logo ?: '';
  1153. $item['supplier_phone'] = $supplier->phone ?: '';
  1154. $item['delivery_rules'] = $delivery_rules ?: null;
  1155. $goods_cat = [];
  1156. //如果是积分兑换商品
  1157. if (isset($arr['product_type']) && $arr['product_type'] == VideoShopGoods::GOODS_TYPE_INTEGRAL) {
  1158. $goods_cat = GoodsCat::find()->alias('gc')
  1159. ->leftJoin(['c' => NewIntegralCat::tableName()], 'gc.cat_id=c.id')
  1160. ->where([ 'gc.goods_id' => $item['id'] ])
  1161. ->select(['c.name'])
  1162. ->asArray()
  1163. ->all();
  1164. } elseif (isset($arr['product_type']) && $arr['product_type'] == VideoShopGoods::GOODS_TYPE_WORKER) {
  1165. $worker_goods_ext = WorkerGoodsExt::findOne(['goods_id' => $item['id']]);
  1166. if ($worker_goods_ext) {
  1167. $goods_cat = WorkerGoodsCat::find()->where(['id' => $worker_goods_ext->cat_id])->select('name')
  1168. ->asArray()->all();
  1169. }
  1170. } elseif (isset($arr['product_type']) && $arr['product_type'] == VideoShopGoods::GOODS_TYPE_TIME) {
  1171. $booking_goods_ext = BookingGoodsExt::findOne(['goods_id' => $item['id']]);
  1172. if ($booking_goods_ext) {
  1173. $goods_cat = BookingGoodsCat::find()->where(['id' => $booking_goods_ext->cat_id])->select('name')
  1174. ->asArray()->all();
  1175. }
  1176. } else {
  1177. $goods_cat = GoodsCat::find()->alias('gc')
  1178. ->leftJoin(['c' => Cat::tableName()], 'gc.cat_id=c.id')
  1179. ->where([ 'gc.goods_id' => $item['id'] ])
  1180. ->select(['c.name'])
  1181. ->asArray()
  1182. ->all();
  1183. }
  1184. $item['cat'] = $goods_cat;
  1185. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_WORKER) {
  1186. $item['order_num'] = OrderDetail::find()->where(['goods_id' => $item['id']])->groupBy('order_id')->count();
  1187. $item['sales'] = OrderDetail::find()->where(['goods_id' => $item['id']])->select('num')->sum('num');
  1188. }
  1189. if (intval($arr['product_type']) === VideoShopGoods::GOODS_TYPE_TIME) {
  1190. $item['order_num'] = OrderDetail::find()->where(['goods_id' => $item['id']])->groupBy('order_id')->count();
  1191. $item['sales'] = OrderDetail::find()->where(['goods_id' => $item['id']])->select('num')->sum('num');
  1192. }
  1193. }
  1194. unset($pagination['list']);
  1195. $book_goods_ids = self::checkBookGoods();
  1196. return [
  1197. 'q' => $query->createCommand()->getRawSql(),
  1198. 'code' => 0,
  1199. 'msg' => 'success',
  1200. 'book_goods_ids' => $book_goods_ids,
  1201. 'warn_goods_timeout' => $warn_goods_timeout,
  1202. 'data' => [
  1203. 'data' => $list,
  1204. 'pageNo' => $pagination['pageNo'],
  1205. 'totalCount' => $pagination['totalCount']
  1206. ]
  1207. ];
  1208. }
  1209. public static function getActivityList($arr = []){
  1210. // 先获取当前进行中的活动以及即将开始的活动
  1211. $query = MdGroupActivitiesGoods::find()->alias('mgag')
  1212. ->leftJoin(['mga'=>MdGroupActivities::tableName()], 'mgag.activities_id=mga.id')
  1213. ->where(['mgag.is_delete'=>0,'mga.is_delete'=>0,'mga.store_id'=>get_store_id()])
  1214. ->andWhere(['or',['and',['<','mga.start_time',time()],['>','mga.end_time',time()]],['and',['>=','mga.start_time',time()],['>=','mga.end_time',time()]]])
  1215. ->leftJoin(['g'=>VideoShopGoods::tableName()],'mgag.goods_id=g.id')
  1216. ->select(['g.id','g.name','g.cover_pic','g.original_price','price'=>'mgag.price','g.is_negotiable','g.delivery_rules_id','activity_id'=>'mga.id','activity_name'=>'mga.name']);
  1217. $result = pagination_make($query,true);
  1218. foreach($result['list'] as &$item){
  1219. $delivery_rules = DeliveryRules::find()->where(['id' => $item['delivery_rules_id'], 'is_delete' => 0, 'store_id' => get_store_id()])->select('type, times, days')->asArray()->one();
  1220. if ($delivery_rules) {
  1221. $delivery_rules['times'] = (int)$delivery_rules['type'] === 1 ? '' : date("m月d日 H:i:s", $delivery_rules['times']);
  1222. }
  1223. $item['delivery_rules'] = $delivery_rules ?: null;
  1224. }
  1225. return [
  1226. 'code'=>0,
  1227. 'data'=>[
  1228. 'data' => $result['list'],
  1229. 'pageNo' => $result['pageNo'],
  1230. 'totalCount' => $result['totalCount']
  1231. ]
  1232. ];
  1233. }
  1234. /**
  1235. * @param array $arr | status 状态 name 名称 cat_id 分类id mch_id 入驻商 is_verify 审核 select 查询数据
  1236. * @return array
  1237. */
  1238. public static function getFoodGoodsList ($arr = [])
  1239. {
  1240. $query = VideoShopGoods::find()->alias('g')
  1241. ->where(['g.store_id' => get_store_id(), 'g.is_delete' => 0])->andWhere(['not like', 'g.name', '当面付']);
  1242. if (isset($arr['status']) && $arr['status'] > -1) {
  1243. $query->andWhere([
  1244. 'g.status' => $arr['status']
  1245. ]);
  1246. }
  1247. if (isset($arr['product_type']) && in_array($arr['product_type'], [0, 1, 2])) {
  1248. $query->andWhere([
  1249. 'g.product_type' => $arr['product_type']
  1250. ]);
  1251. }
  1252. if (isset($arr['name']) && !empty($arr['name'])) {
  1253. $query->andWhere([
  1254. 'like',
  1255. 'g.name',
  1256. $arr['name']
  1257. ]);
  1258. }
  1259. if (isset($arr['cat_id']) && $arr['cat_id'] > 0) {
  1260. if ($arr['mch_id'] > 0) {
  1261. $query->leftJoin(['mgc' => MchGoodsCat::tableName()], 'g.id = mgc.goods_id')->andWhere([
  1262. 'mgc.cat_id' => MchCat::getCatId($arr['cat_id'])
  1263. ])->groupBy('mgc.goods_id');
  1264. } else {
  1265. $query->leftJoin(['gc' => GoodsCat::tableName()], 'g.id = gc.goods_id')->andWhere([
  1266. 'gc.cat_id' => Cat::getCatId($arr['cat_id'])
  1267. ])->groupBy('gc.goods_id');
  1268. }
  1269. }
  1270. if (isset($arr['mch_cat_id']) && $arr['mch_cat_id'] > 0) {
  1271. $query->leftJoin(['mgc' => MchGoodsCat::tableName()], 'g.id = mgc.goods_id')->andWhere([
  1272. 'mgc.cat_id' => MchCat::getCatId($arr['mch_cat_id'])
  1273. ])->groupBy('mgc.goods_id');
  1274. }
  1275. // 根据入驻商查询 0 平台 -1 全部入驻商 >0 对应入驻商
  1276. if (empty($arr['mch_id'])) {
  1277. $query->andWhere(['g.mch_id' => 0]);
  1278. } elseif(isset($arr['mch_id']) && $arr['mch_id'] == -1) {
  1279. $query->andWhere([
  1280. '>',
  1281. 'g.mch_id',
  1282. 0
  1283. ]);
  1284. } elseif (isset($arr['mch_id']) && $arr['mch_id'] > 0){
  1285. $query->andWhere(['g.mch_id' => $arr['mch_id']]);
  1286. }
  1287. // 获取入驻商待审核商品
  1288. if (isset($arr['is_verify'])) {
  1289. $query->andWhere([
  1290. 'g.is_verify' => $arr['is_verify']
  1291. ]);
  1292. }
  1293. if (!empty($arr['select'])) {
  1294. $select = $arr['select'];
  1295. } else {
  1296. $select = ['g.id', 'g.name', 'g.status', 'g.service',
  1297. 'g.updated_at', 'g.virtual_sales', 'g.is_verify', 'g.is_negotiable',
  1298. 'g.price', 'g.goods_num', 'g.sort' ,'g.cover_pic', 'g.original_price',
  1299. 'g.quick_purchase', 'g.attr', 'g.mch_id', 'g.detail', 'g.use_attr', 'g.product_type', 'g.is_recommend'];
  1300. }
  1301. $query->with(['mch'])->select($select)
  1302. ->orderBy(['g.sort' => SORT_ASC, 'g.id' => SORT_DESC]);
  1303. $pagination = pagination_make($query);
  1304. $pagination['data'] = $pagination['list'];
  1305. foreach($pagination['data'] as $k => $v) {
  1306. $goods_cat = GoodsCat::find()->alias('gc')
  1307. ->leftJoin(['c' => Cat::tableName()], 'gc.cat_id=c.id')
  1308. ->where([ 'gc.goods_id' => $v['id'] ])
  1309. ->select(['c.name'])
  1310. ->asArray()
  1311. ->all();
  1312. $pagination['data'][$k]['cat'] = $goods_cat;
  1313. }
  1314. unset($pagination['list']);
  1315. $book_goods_ids = self::checkBookGoods();
  1316. return [
  1317. 'code' => 0,
  1318. 'msg' => 'success',
  1319. 'book_goods_ids' => $book_goods_ids,
  1320. 'data' => $pagination
  1321. ];
  1322. }
  1323. /**
  1324. * 获取商品可选的规格列表
  1325. */
  1326. public function getAttrGroupList($is_pt = 0, $use_attr = 1, $is_platform = 0)
  1327. {
  1328. $attr_rows = json_decode($this->attr, true);
  1329. if (empty($attr_rows)) {
  1330. return [];
  1331. }
  1332. $attr_group_list = [];
  1333. foreach ($attr_rows as $attr_row) {
  1334. foreach ($attr_row['attr_list'] as $i => $attr) {
  1335. $attr_id = $attr['attr_id'];
  1336. $attr = Attr::findOne(['id' => $attr_id, 'is_delete' => 0]);
  1337. if (!$attr) {
  1338. continue;
  1339. }
  1340. $in_list = false;
  1341. foreach ($attr_group_list as $j => $attr_group) {
  1342. if ($attr_group->attr_group_id == $attr->attr_group_id) {
  1343. $attr_obj = (object)[
  1344. 'attr_id' => $attr->id,
  1345. 'attr_name' => $attr->attr_name,
  1346. ];
  1347. if (!in_array($attr_obj, $attr_group_list[$j]->attr_list)) {
  1348. $attr_group_list[$j]->attr_list[] = $attr_obj;
  1349. }
  1350. $in_list = true;
  1351. continue;
  1352. }
  1353. }
  1354. if (!$in_list) {
  1355. $attr_group = AttrGroup::findOne(['is_delete' => 0, 'id' => $attr->attr_group_id]);
  1356. if ($attr_group) {
  1357. $attr_group_list[] = (object)[
  1358. 'attr_group_id' => $attr_group->id,
  1359. 'attr_group_name' => $attr_group->attr_group_name,
  1360. 'attr_list' => [
  1361. (object)[
  1362. 'attr_id' => $attr->id,
  1363. 'attr_name' => $attr->attr_name,
  1364. ],
  1365. ],
  1366. ];
  1367. }
  1368. }
  1369. }
  1370. }
  1371. if ((int)$use_attr === 0) {
  1372. $attr_group_list = [
  1373. $attr_group_list[0]
  1374. ];
  1375. }
  1376. //判断是否为拼团产品
  1377. //拼团活动信息
  1378. if ($is_pt) {
  1379. $query = PtActivityGoods::find()->alias('pag')->where(['pag.is_delete' => 0, 'pa.is_delete' => 0, 'pa.store_id' => get_store_id()])
  1380. ->leftJoin(['pa' => PtActivity::tableName()], 'pag.activity_id = pa.id')
  1381. ->andWhere(['pag.goods_id' => $this->id])
  1382. ->select('pag.pt_price, pag.sale_num, pag.virtual_sales, pa.party_size, pa.party_type, pa.party_goods_count')
  1383. ->andWhere(['AND', ['<', 'pa.start_time', time()], ['>', 'pa.end_time', time()]]);
  1384. $query->andWhere(['OR', ['is_platform' => 1, 'is_platform_audit' => 1, 'status' => 1], ['is_platform' => 0]]);
  1385. $ptGoodsActivity = $query->asArray()->one();
  1386. if ($ptGoodsActivity) {
  1387. $attr_name = $ptGoodsActivity['party_size'] . "人团";
  1388. if($ptGoodsActivity['party_type'] == 1){
  1389. $attr_name = $ptGoodsActivity['party_goods_count'] . "个商品成团";
  1390. }
  1391. $pt_attr = [
  1392. [
  1393. "attr_group_id" => -1,
  1394. "attr_group_name" => "拼团",
  1395. "attr_list" => [
  1396. [
  1397. "attr_id" => -1,
  1398. "attr_name" => $attr_name
  1399. ]
  1400. ]
  1401. ]
  1402. ];
  1403. $attr_group_list = array_values(array_merge($pt_attr, $attr_group_list));
  1404. }
  1405. }
  1406. return $attr_group_list;
  1407. }
  1408. /**
  1409. * 获取商品分类
  1410. * @param $goods
  1411. * @return array
  1412. */
  1413. public static function getCatList($goods)
  1414. {
  1415. $cat_list = [];
  1416. $cat = GoodsCat::findAll(['goods_id' => $goods->id, 'store_id' => $goods->store_id, 'is_delete' => 0]);
  1417. if ($cat) {
  1418. foreach ($cat as $index => $value) {
  1419. $cat_name = Cat::findOne(['id' => $value->cat_id, 'store_id' => $goods->store_id]);
  1420. $cat_list[$index]['cat_id'] = $value->cat_id;
  1421. $cat_list[$index]['cat_name'] = $cat_name->name;
  1422. }
  1423. } else {
  1424. $cat_name = Cat::findOne(['id' => $goods->cat_id]);
  1425. $cat_list[0]['cat_id'] = $goods->cat_id;
  1426. $cat_list[0]['cat_name'] = $cat_name->name;
  1427. }
  1428. return $cat_list;
  1429. }
  1430. /**
  1431. * 获取商品总库存
  1432. * @param int $id 商品id
  1433. */
  1434. public function getNum($id = null)
  1435. {
  1436. $goods = null;
  1437. if (!$id) {
  1438. $goods = $this;
  1439. } else {
  1440. $goods = static::findOne($id);
  1441. if (!$goods) {
  1442. return 0;
  1443. }
  1444. }
  1445. $attr = $goods->attr;
  1446. if (get_md_id()) {
  1447. $md_goods = MdGoods::findOne(['goods_id' => $id ?: $goods->id, 'md_id' => get_md_id()]);
  1448. if ($md_goods) {
  1449. $attr = $md_goods->attr;
  1450. }
  1451. }
  1452. if ((int)$goods->product_type === 2) {
  1453. return $goods->service_book_num;
  1454. }
  1455. if ((int)$goods->product_type === 4) {
  1456. return $goods->goods_num;
  1457. }
  1458. if (!$attr) {
  1459. return 0;
  1460. }
  1461. $num = 0;
  1462. $attr_rows = json_decode($attr, true);
  1463. foreach ($attr_rows as $attr_row) {
  1464. $num += intval($attr_row['num']);
  1465. }
  1466. return $num;
  1467. }
  1468. /**
  1469. * 库存增加操作
  1470. */
  1471. public function numAdd($attr_id_list, $num, $reset = 0)
  1472. {
  1473. if(!is_array($attr_id_list[0])){
  1474. $attr_id_list = [
  1475. ['attr_id_list' => $attr_id_list, 'num' => $num]
  1476. ];
  1477. }
  1478. $_attr = $this->attr;
  1479. $is_md = false;
  1480. if (get_md_id()) {
  1481. $md_goods = MdGoods::findOne(['goods_id' => $this->id, 'md_id' => get_md_id()]);
  1482. if ($md_goods) {
  1483. $_attr = $md_goods->attr;
  1484. $is_md = true;
  1485. }
  1486. }
  1487. $attr_group_list = json_decode($_attr);
  1488. $add_attr_num = false;
  1489. foreach($attr_id_list as $item){
  1490. $num = $item['num'];
  1491. sort($item['attr_id_list']);
  1492. foreach ($attr_group_list as $i => $attr_group) {
  1493. $group_attr_id_list = [];
  1494. foreach ($attr_group->attr_list as $attr) {
  1495. array_push($group_attr_id_list, $attr->attr_id);
  1496. }
  1497. sort($group_attr_id_list);
  1498. if (!array_diff($item['attr_id_list'], $group_attr_id_list)) {
  1499. if($reset){
  1500. $attr_group_list[$i]->num = intval($num);
  1501. }else{
  1502. $attr_group_list[$i]->num = intval($attr_group_list[$i]->num) + $num;
  1503. }
  1504. $add_attr_num = true;
  1505. break;
  1506. }
  1507. }
  1508. }
  1509. if (!$add_attr_num) {
  1510. return false;
  1511. }
  1512. if (!$is_md) {
  1513. $this->attr = json_encode($attr_group_list, JSON_UNESCAPED_UNICODE);
  1514. if ($this->attr) {
  1515. $attr_rows = json_decode($this->attr, true);
  1516. $goods_num = 0;
  1517. foreach ($attr_rows as $attr_row) {
  1518. $goods_num += intval($attr_row['num']);
  1519. }
  1520. $this->goods_num = $goods_num;
  1521. }
  1522. $this->save();
  1523. } else {
  1524. // 门店商品逻辑
  1525. $md_goods->attr = json_encode($attr_group_list, JSON_UNESCAPED_UNICODE);
  1526. if ($md_goods->attr) {
  1527. $attr_rows = json_decode($md_goods->attr, true);
  1528. $goods_num = 0;
  1529. foreach ($attr_rows as $attr_row) {
  1530. $goods_num += intval($attr_row['num']);
  1531. }
  1532. $md_goods->goods_num = $goods_num;
  1533. }
  1534. $md_goods->save();
  1535. }
  1536. return true;
  1537. }
  1538. /**
  1539. * 库存减少操作
  1540. * @param array $attr_id_list eg. [1,4,2]
  1541. */
  1542. public function numSub($attr_id_list, $num)
  1543. {
  1544. if(!is_array($attr_id_list[0])){
  1545. $attr_id_list = [
  1546. ['attr_id_list' => $attr_id_list, 'num' => $num]
  1547. ];
  1548. }
  1549. $_attr = $this->attr;
  1550. $is_md = false;
  1551. if (get_md_id()) {
  1552. $md_goods = MdGoods::findOne(['goods_id' => $this->id, 'md_id' => get_md_id()]);
  1553. if ($md_goods) {
  1554. $_attr = $md_goods->attr;
  1555. $is_md = true;
  1556. }
  1557. }
  1558. $attr_group_list = json_decode($_attr);
  1559. $sub_attr_num = false;
  1560. foreach($attr_id_list as $item){
  1561. $num = $item['num'];
  1562. sort($item['attr_id_list']);
  1563. foreach ($attr_group_list as $i => $attr_group) {
  1564. $group_attr_id_list = [];
  1565. foreach ($attr_group->attr_list as $attr) {
  1566. array_push($group_attr_id_list, $attr->attr_id);
  1567. }
  1568. sort($group_attr_id_list);
  1569. if (!array_diff($item['attr_id_list'], $group_attr_id_list)) {
  1570. if ($num > intval($attr_group_list[$i]->num)) {
  1571. return false;
  1572. }
  1573. $attr_group_list[$i]->num = intval($attr_group_list[$i]->num) - $num;
  1574. $sub_attr_num = true;
  1575. break;
  1576. }
  1577. }
  1578. }
  1579. if (!$sub_attr_num) {
  1580. return false;
  1581. }
  1582. if (!$is_md) {
  1583. $this->attr = json_encode($attr_group_list, JSON_UNESCAPED_UNICODE);
  1584. if ($this->attr) {
  1585. $attr_rows = json_decode($this->attr, true);
  1586. $goods_num = 0;
  1587. foreach ($attr_rows as $attr_row) {
  1588. $goods_num += intval($attr_row['num']);
  1589. }
  1590. $this->goods_num = $goods_num;
  1591. }
  1592. $this->save();
  1593. } else {
  1594. $md_goods->attr = json_encode($attr_group_list, JSON_UNESCAPED_UNICODE);
  1595. if ($md_goods->attr) {
  1596. $attr_rows = json_decode($md_goods->attr, true);
  1597. $goods_num = 0;
  1598. foreach ($attr_rows as $attr_row) {
  1599. $goods_num += intval($attr_row['num']);
  1600. }
  1601. $md_goods->goods_num = $goods_num;
  1602. }
  1603. $md_goods->save();
  1604. }
  1605. return true;
  1606. }
  1607. /**
  1608. * 库存增加操作
  1609. */
  1610. public static function numAddStatic($goods_id, $attr_id_list, $num, $reset = 0)
  1611. {
  1612. $goods = VideoShopGoods::findOne($goods_id);
  1613. if (!$goods) {
  1614. return false;
  1615. }
  1616. return $goods->numAdd($attr_id_list, $num, $reset);
  1617. }
  1618. /**
  1619. * 库存减少操作
  1620. */
  1621. public static function numSubStatic($goods_id, $attr_id_list, $num)
  1622. {
  1623. $goods = VideoShopGoods::findOne($goods_id);
  1624. if (!$goods) {
  1625. return false;
  1626. }
  1627. return $goods->numSub($attr_id_list, $num);
  1628. }
  1629. /**
  1630. * 获取商品组图
  1631. * @return \yii\db\ActiveQuery
  1632. */
  1633. public function getGoodsPicList()
  1634. {
  1635. return $this->hasMany(GoodsPic::className(), ['goods_id' => 'id'])->where(['is_delete' => 0]);
  1636. }
  1637. /**
  1638. * 获取入驻商
  1639. * @return \yii\db\ActiveQuery
  1640. */
  1641. public function getMch()
  1642. {
  1643. return $this->hasMany(Mch::className(), ['id' => 'mch_id'])->select(['id', 'name', 'logo', 'service_tel', 'is_delete']);
  1644. }
  1645. public function getMchCatList()
  1646. {
  1647. $cat_list = [];
  1648. $cat = MchGoodsCat::findAll(['goods_id' => $this->id]);
  1649. if ($cat) {
  1650. foreach ($cat as $index => $value) {
  1651. $cat_name = MchCat::findOne(['id' => $value->cat_id]);
  1652. $cat_list[] = $cat_name->name;
  1653. }
  1654. } else {
  1655. $cat_list[] = "";
  1656. }
  1657. return implode(',', $cat_list);
  1658. }
  1659. public static function getGoodsPicStatic($goods_id, $index = 0)
  1660. {
  1661. $goods = VideoShopGoods::findOne($goods_id);
  1662. if (!$goods) {
  1663. return null;
  1664. }
  1665. return $goods->getGoodsPic($index);
  1666. }
  1667. /**
  1668. * 获取商品销量
  1669. */
  1670. public function getSalesVolume()
  1671. {
  1672. $cacheKey = 'getSalesVolume' . $this->id;
  1673. $cacheVal = cache()->get($cacheKey);
  1674. if($cacheVal){
  1675. return $cacheVal;
  1676. }
  1677. $res = OrderDetail::find()->alias('od')
  1678. ->select('SUM(od.num) AS sales_volume')
  1679. ->leftJoin(['o' => Order::tableName()], 'od.order_id=o.id')
  1680. ->where(['od.is_delete' => 0, 'od.goods_id' => $this->id, 'o.is_delete' => 0, 'o.is_pay' => 1,])
  1681. ->asArray()->one();
  1682. $v = empty($res['sales_volume']) ? 0 : intval($res['sales_volume']);
  1683. if($v > 300){
  1684. cache()->set($cacheKey, $v, 3 * 60);
  1685. }
  1686. return $v;
  1687. }
  1688. /**
  1689. * 获取商品销量
  1690. */
  1691. public function getSalesVolumeVideoShopShare()
  1692. {
  1693. $cacheKey = 'getSalesVolumeVideoShopShare' . $this->id;
  1694. $cacheVal = cache()->get($cacheKey);
  1695. if($cacheVal){
  1696. return $cacheVal;
  1697. }
  1698. $res = OrderDetail::find()->alias('od')
  1699. ->select('SUM(od.num) AS sales_volume')
  1700. ->leftJoin(['o' => Order::tableName()], 'od.order_id=o.id')
  1701. ->leftJoin(['v' => VideoShopOrderExt::tableName()], 'v.order_id=o.id')
  1702. ->where(['od.is_delete' => 0, 'od.goods_id' => $this->id, 'o.is_delete' => 0, 'o.is_pay' => 1,])
  1703. ->andWhere('isnull(v.id)')
  1704. ->asArray()->one();
  1705. $v = empty($res['sales_volume']) ? 0 : intval($res['sales_volume']);
  1706. if($v > 300){
  1707. cache()->set($cacheKey, $v, 3 * 60);
  1708. }
  1709. return $v;
  1710. }
  1711. public static function getGoodsNum($goods = null){
  1712. $types = [
  1713. VideoShopGoods::GOODS_TYPE_DATE,
  1714. ];
  1715. if(!$goods){
  1716. return [
  1717. 'code' => 1,
  1718. 'data' => '参数错误',
  1719. ];
  1720. }
  1721. if(!in_array($goods->product_type, $types)){
  1722. $nums = 0;
  1723. }
  1724. if ($goods->product_type == VideoShopGoods::GOODS_TYPE_DATE) {
  1725. $stime = mktime(0, 0, 0, date('m') - 1, 1);
  1726. $endtime = mktime(0, 0, 0, date('m') + 2, 1);
  1727. $query = OrderDetail::find()->alias('od')->leftJoin(['o' => Order::tableName()], 'o.id = od.order_id')
  1728. ->where([
  1729. 'od.goods_id' => $goods->id,
  1730. 'o.trade_status' => [
  1731. Order::ORDER_FLOW_DEFAULT,
  1732. Order::ORDER_FLOW_NO_SEND,
  1733. Order::ORDER_FLOW_SEND,
  1734. Order::ORDER_FLOW_CONFIRM,
  1735. ],
  1736. ]);
  1737. $query->andWhere(['>', 'o.created_at', $stime]);
  1738. $list = $query->all();
  1739. $order = [];
  1740. $nums = [];
  1741. $goodsNum = $goods->getNum();
  1742. foreach ($list as $item) {
  1743. $attr = json_decode($item['attr'], true);
  1744. foreach ($attr as $iattr) {
  1745. $order[$iattr['date']]+=$item['num'];
  1746. }
  1747. }
  1748. for($i = time(); $i < $endtime; $i+=86400){
  1749. $date = date('Y-m-d', $i);
  1750. $book_price = $goods->price;
  1751. $newGoodsNum = $goodsNum;
  1752. if (!empty($goods->service_book_desc)) {
  1753. $service_book_desc = json_decode($goods->service_book_desc, true);
  1754. foreach ($service_book_desc as $value) {
  1755. if (strtotime($value['date']) === strtotime($date)) {
  1756. $goodsNum = $value['num'];
  1757. $book_price = $value['price'];
  1758. }
  1759. }
  1760. }
  1761. $num = $goodsNum - $order[$date];
  1762. $nums[] = [
  1763. 'date' => $date,
  1764. 'num' => $num > 0 ? $num : 0,
  1765. 'price' => $book_price
  1766. ];
  1767. $goodsNum = $newGoodsNum;
  1768. }
  1769. }
  1770. return [
  1771. 'code' => 0,
  1772. 'data' => $nums,
  1773. ];
  1774. }
  1775. /**
  1776. * 获取商品卡券
  1777. * @param null $id
  1778. * @return array
  1779. */
  1780. public static function getGoodsCard($id = null)
  1781. {
  1782. return [];
  1783. if (!$id) {
  1784. return [];
  1785. }
  1786. //商品卡券
  1787. $goods_card_list = GoodsCard::find()->alias('gc')->where(['gc.is_delete' => 0, 'goods_id' => $id])
  1788. ->leftJoin(Card::tableName() . ' c', 'c.id=gc.card_id')->select([
  1789. 'gc.card_id', 'c.name', 'c.pic_url', 'gc.goods_id', 'c.content'
  1790. ])->asArray()->all();
  1791. foreach ($goods_card_list as $index => $value) {
  1792. $goods_card_list[$index]['id'] = $value['card_id'];
  1793. $goods_card_list[$index]['goods_id'] = $id;
  1794. }
  1795. return $goods_card_list;
  1796. }
  1797. /**
  1798. * @param $user User
  1799. * @param $goods_id
  1800. * @return false|null|string
  1801. * 查找指定用户指定商品购买数量
  1802. */
  1803. public static function getBuyNum($user, $goods_id)
  1804. {
  1805. $goodsNum = OrderDetail::find()->alias('od')->innerJoin(['o' => Order::tableName()], 'o.id=od.order_id')
  1806. ->where([
  1807. 'od.goods_id' => $goods_id, 'store_id' => $user->store_id, 'o.user_id' => $user->id,
  1808. 'o.is_delete' => 0, 'o.is_show' => 1
  1809. ])->andWhere(['<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL])->andWhere([
  1810. 'or',
  1811. ['o.is_pay' => 1],
  1812. ['o.pay_type' => Order::PAY_TYPE_COD]
  1813. ])->select('SUM(od.num) num')->scalar();
  1814. return $goodsNum;
  1815. }
  1816. /**
  1817. * @param $saas SaasUser
  1818. * @param $goods_id
  1819. * @return false|null|string
  1820. * 查找指定用户指定商品购买数量
  1821. */
  1822. public static function getSaasBuyNum($saas, $goods_id)
  1823. {
  1824. $goodsNum = OrderDetail::find()->alias('od')->innerJoin(['o' => Order::tableName()], 'o.id=od.order_id')
  1825. ->where([
  1826. 'od.goods_id' => $goods_id,'o.saas_id' => $saas->id,
  1827. 'o.is_delete' => 0, 'o.is_show' => 1
  1828. ])->andWhere(['<>', 'o.trade_status', Order::ORDER_FLOW_CANCEL])->andWhere([
  1829. 'or',
  1830. ['o.is_pay' => 1],
  1831. ['o.pay_type' => Order::PAY_TYPE_COD]
  1832. ])->select('SUM(od.num) num')->scalar();
  1833. return $goodsNum;
  1834. }
  1835. /**
  1836. * 根据规格获取商品的库存及规格价格信息
  1837. * @param array $attr_id_list 规格id列表 eg. [1,4,9]
  1838. * @return array|null eg.
  1839. */
  1840. public function getAttrInfo($attr_id_list)
  1841. {
  1842. sort($attr_id_list);
  1843. // 门店逻辑
  1844. $attr = $this->attr;
  1845. $price = $this->price;
  1846. if (get_md_id()) {
  1847. $md_goods = MdGoods::findOne(['goods_id' => $this->id, 'md_id' => get_md_id()]);
  1848. if ($md_goods) {
  1849. $attr = $md_goods->attr;
  1850. $price = $md_goods->price;
  1851. }
  1852. }
  1853. $attr_rows = json_decode($attr, true);
  1854. if (empty($attr_rows)) {
  1855. return null;
  1856. }
  1857. foreach ($attr_rows as $i => $attr_row) {
  1858. $key = [];
  1859. foreach ($attr_row['attr_list'] as $j => $attr) {
  1860. $key[] = $attr['attr_id'];
  1861. }
  1862. sort($key);
  1863. if (!array_diff($attr_id_list, $key)) {
  1864. if (!$attr_rows[$i]['price']) {
  1865. $attr_rows[$i]['price'] = $price;
  1866. }
  1867. return $attr_rows[$i];
  1868. }
  1869. }
  1870. return null;
  1871. }
  1872. /**
  1873. * 减满
  1874. */
  1875. public static function cutFull($goodsList)
  1876. {
  1877. // 将商品ID相同的商品合并
  1878. $newGoodsList = [];
  1879. foreach ($goodsList as $row) {
  1880. $rowArray = (array) $row;
  1881. if (isset($newGoodsList[$rowArray['goods_id']])) {
  1882. $newGoodsList[$rowArray['goods_id']]['num'] += $rowArray['num'];
  1883. $newGoodsList[$rowArray['goods_id']]['weight'] += $rowArray['weight'] * $rowArray['num'];
  1884. $newGoodsList[$rowArray['goods_id']]['price'] += $rowArray['price'];
  1885. } else {
  1886. $rowArray['weight'] = $rowArray['weight'] * $rowArray['num'];
  1887. $newGoodsList[$rowArray['goods_id']] = $rowArray;
  1888. }
  1889. }
  1890. $resGoodsList = [];
  1891. foreach ($newGoodsList as $val) {
  1892. if ($val['full_cut']) {
  1893. $full_cut = json_decode($val['full_cut'], true);
  1894. } else {
  1895. $full_cut = [
  1896. 'pieces' => 0,
  1897. 'forehead' => 0,
  1898. ];
  1899. }
  1900. if ((empty($full_cut['pieces']) || $val['num'] < ($full_cut['pieces'] ?: 0)) && (empty((float)$full_cut['forehead']) || $val['price'] < ((float)$full_cut['forehead'] ?: 0))) {
  1901. $resGoodsList[] = $val;
  1902. }
  1903. }
  1904. return $resGoodsList;
  1905. }
  1906. public function getGoodsPic($index = 0)
  1907. {
  1908. $list = $this->goodsPicList;
  1909. if (!$list) {
  1910. return null;
  1911. }
  1912. return isset($list[$index]) ? $list[$index] : null;
  1913. }
  1914. public function getCatList1()
  1915. {
  1916. return $this->hasMany(GoodsCat::className(), ['goods_id' => 'id'])->where(['store_id' => get_store_id(), 'is_delete' => 0]);
  1917. }
  1918. public function getCat()
  1919. {
  1920. return $this->hasOne(Cat::className(), ['id' => 'cat_id'])->where(['store_id' => get_store_id()]);
  1921. }
  1922. public static function getBrand($brand_id = 0)
  1923. {
  1924. if ($brand_id < 1) {
  1925. return '';
  1926. }
  1927. $brand = GoodsBrand::findOne(['id' => $brand_id]);
  1928. return $brand->brand_name ?: '';
  1929. }
  1930. // 规格组
  1931. public function getAttrData()
  1932. {
  1933. if ($this->isNewRecord) {
  1934. return [];
  1935. }
  1936. if (!$this->use_attr) {
  1937. return [];
  1938. }
  1939. if (!$this->attr) {
  1940. return [];
  1941. }
  1942. $attr_group_list = [];
  1943. $attr_data = json_decode($this->attr, true);
  1944. foreach ($attr_data as $i => $attr_data_item) {
  1945. foreach ($attr_data[$i]['attr_list'] as $j => $attr_list) {
  1946. $attr_group = $this->getAttrGroupByAttId($attr_data[$i]['attr_list'][$j]['attr_id']);
  1947. if ($attr_group) {
  1948. $in_list = false;
  1949. foreach ($attr_group_list as $k => $exist_attr_group) {
  1950. if ($exist_attr_group['attr_group_name'] == $attr_group->attr_group_name) {
  1951. $attr_item = [
  1952. 'attr_id' => $attr_data[$i]['attr_list'][$j]['attr_id'],
  1953. 'attr_name' => $attr_data[$i]['attr_list'][$j]['attr_name'],
  1954. ];
  1955. if (!in_array($attr_item, $attr_group_list[$k]['attr_list'])) {
  1956. $attr_group_list[$k]['attr_list'][] = $attr_item;
  1957. }
  1958. $in_list = true;
  1959. }
  1960. }
  1961. if (!$in_list) {
  1962. $attr_group_list[] = [
  1963. 'attr_group_name' => $attr_group->attr_group_name,
  1964. 'attr_list' => [
  1965. [
  1966. 'attr_id' => $attr_data[$i]['attr_list'][$j]['attr_id'],
  1967. 'attr_name' => $attr_data[$i]['attr_list'][$j]['attr_name'],
  1968. ],
  1969. ],
  1970. ];
  1971. }
  1972. }
  1973. }
  1974. }
  1975. return $attr_group_list;
  1976. }
  1977. /**
  1978. * Undocumented function
  1979. *
  1980. * @Author LGL 24963@qq.com
  1981. * @DateTime 2021-03-02
  1982. * @desc:
  1983. * @param [type] $att_id
  1984. * @return void
  1985. */
  1986. public function getAttrGroupByAttId($att_id)
  1987. {
  1988. $cache_key = 'get_attr_group_by_attr_id_' . $att_id;
  1989. $attr_group = cache()->get($cache_key);
  1990. if ($attr_group) {
  1991. return $attr_group;
  1992. }
  1993. $attr_group = AttrGroup::find()->alias('ag')
  1994. ->where(['ag.id' => Attr::find()->select('attr_group_id')->distinct()->where(['id' => $att_id])])
  1995. ->limit(1)->one();
  1996. if (!$attr_group) {
  1997. return $attr_group;
  1998. }
  1999. cache()->set($cache_key, $attr_group, 10);
  2000. return $attr_group;
  2001. }
  2002. public function getCheckedAttrData()
  2003. {
  2004. if ($this->isNewRecord) {
  2005. return [];
  2006. }
  2007. if (!$this->use_attr) {
  2008. return [];
  2009. }
  2010. if (!$this->attr) {
  2011. return [];
  2012. }
  2013. $attr_data = json_decode($this->attr, true);
  2014. foreach ($attr_data as $i => $attr_data_item) {
  2015. if (!isset($attr_data[$i]['no'])) {
  2016. $attr_data[$i]['no'] = '';
  2017. }
  2018. if (!isset($attr_data[$i]['pic'])) {
  2019. $attr_data[$i]['pic'] = '';
  2020. }
  2021. foreach ($attr_data[$i]['attr_list'] as $j => $attr_list) {
  2022. $attr_group = $this->getAttrGroupByAttId($attr_data[$i]['attr_list'][$j]['attr_id']);
  2023. $attr_data[$i]['attr_list'][$j]['attr_group_name'] = $attr_group ? $attr_group->attr_group_name : null;
  2024. }
  2025. }
  2026. return $attr_data;
  2027. }
  2028. public function getGoodsCover()
  2029. {
  2030. if ($this->cover_pic) {
  2031. return $this->cover_pic;
  2032. }
  2033. $pic = $this->getGoodsPic(0);
  2034. if ($pic) {
  2035. return $pic->pic_url;
  2036. }
  2037. return null;
  2038. }
  2039. public function getCats()
  2040. {
  2041. return $this->hasMany(Cat::className(), ['id' => 'cat_id'])
  2042. ->via('gc');
  2043. }
  2044. /**
  2045. * @return array
  2046. */
  2047. public static function getDefaultAttr($store_id)
  2048. {
  2049. $default_attr_name = '默认';
  2050. $default_attr_group_name = '规格';
  2051. $attr = Attr::findOne([
  2052. 'attr_name' => $default_attr_name,
  2053. 'is_delete' => 0,
  2054. 'is_default' => 1,
  2055. ]);
  2056. $attr_group = null;
  2057. if (!$attr) {
  2058. $attr_group = AttrGroup::findOne([
  2059. 'attr_group_name' => $default_attr_group_name,
  2060. 'is_delete' => 0,
  2061. ]);
  2062. if (!$attr_group) {
  2063. $attr_group = new AttrGroup();
  2064. $attr_group->store_id = $store_id;
  2065. $attr_group->attr_group_name = $default_attr_group_name;
  2066. $attr_group->is_delete = 0;
  2067. $attr_group->save(false);
  2068. }
  2069. $attr = new Attr();
  2070. $attr->attr_group_id = $attr_group->id;
  2071. $attr->attr_name = $default_attr_name;
  2072. $attr->is_delete = 0;
  2073. $attr->is_default = 1;
  2074. $attr->save(false);
  2075. } else {
  2076. $attr_group = AttrGroup::findOne($attr->attr_group_id);
  2077. }
  2078. return [$attr, $attr_group];
  2079. }
  2080. public static function checkBookGoods() {
  2081. return [];
  2082. $goods_book = VideoShopGoods::find()->alias('g')->leftJoin(['gb' => GoodsBook::tableName()], 'g.id=gb.goods_id')
  2083. ->where(['g.is_delete' => 0, 'g.status' => 1, 'g.store_id' => get_store_id()])
  2084. ->andWhere(['in', 'g.product_type', [1, 2]])->select('g.product_type, g.id, gb.date_book, gb.service_book')->asArray()->all();
  2085. if (empty($goods_book)) {
  2086. return [];
  2087. }
  2088. $book_goods_ids = [];
  2089. $today = strtotime(date('Y-m-d', time()));
  2090. foreach ($goods_book as $book) {
  2091. // 酒店预约商品
  2092. if ($book['product_type'] == self::GOODS_TYPE_DATE) {
  2093. $date_book = Json::decode($book['date_book']);
  2094. $book_date_arr = array_column($date_book, 'date');
  2095. if (empty($book_date_arr)) {
  2096. $book_goods_ids[] = $book['id'];
  2097. continue;
  2098. }
  2099. $count = 0;
  2100. foreach ($book_date_arr as $value) {
  2101. if (strtotime($value) > $today) {
  2102. $count ++;
  2103. }
  2104. }
  2105. if ($count <= 1) {
  2106. $book_goods_ids[] = $book['id'];
  2107. }
  2108. }
  2109. // 服务预约商品
  2110. if ($book['product_type'] == self::GOODS_TYPE_TIME) {
  2111. $service_book = Json::decode($book['service_book']);
  2112. $service_date_arr = array_column($service_book['data'], 'date');
  2113. if (empty($service_date_arr)) {
  2114. $book_goods_ids[] = $book['id'];
  2115. continue;
  2116. }
  2117. $count = 0;
  2118. foreach ($service_date_arr as $value) {
  2119. if (strtotime($value) > $today) {
  2120. $count ++;
  2121. }
  2122. }
  2123. if ($count <= 1) {
  2124. $book_goods_ids[] = $book['id'];
  2125. }
  2126. }
  2127. }
  2128. return $book_goods_ids;
  2129. }
  2130. /**
  2131. * 添加可选择的抖品商品的商品列表
  2132. */
  2133. public static function getGoodsList($arr, $is_video_goods = false) {
  2134. $query = VideoShopGoods::find()->alias('g')
  2135. ->where(['g.is_delete' => 0, 'g.md_food_id' => 0, 'g.status' => 1])
  2136. ->andWhere(['not like', 'g.name', '当面付'])->andWhere(['in', 'g.product_type', [0]]);
  2137. if (isset($arr['store_id']) && !empty($arr['store_id'])) {
  2138. $query->andWhere(['g.store_id' => get_store_id()]);
  2139. }
  2140. if (isset($arr['name']) && !empty($arr['name'])) {
  2141. $query->andWhere([
  2142. 'like',
  2143. 'g.name',
  2144. $arr['name']
  2145. ]);
  2146. }
  2147. // if (isset($arr['status']) && $arr['status'] != -1) {
  2148. // $query->andWhere(['g.status' => $arr['status']]);
  2149. // }
  2150. if ($is_video_goods || !empty($arr['goods_id'])) {
  2151. $query->andWhere(['in', 'id', $arr['goods_id']]);
  2152. }
  2153. if (!empty($arr['select'])) {
  2154. $select = $arr['select'];
  2155. } else {
  2156. $select = ['g.id', 'g.name', 'g.status', 'g.service',
  2157. 'g.updated_at', 'g.virtual_sales', 'g.is_verify', 'g.is_negotiable',
  2158. 'g.price', 'g.goods_num', 'g.sort' ,'g.cover_pic', 'g.original_price',
  2159. 'g.quick_purchase', 'g.attr', 'g.mch_id', 'g.detail', 'g.use_attr', 'g.product_type', 'g.is_recommend'];
  2160. }
  2161. $query->select($select)
  2162. ->orderBy(['g.sort' => SORT_ASC, 'g.id' => SORT_DESC]);
  2163. $pagination = pagination_make($query);
  2164. $pagination['data'] = $pagination['list'];
  2165. foreach($pagination['data'] as $k => $v) {
  2166. $goods_cat = GoodsCat::find()->alias('gc')
  2167. ->leftJoin(['c' => Cat::tableName()], 'gc.cat_id=c.id')
  2168. ->where([ 'gc.goods_id' => $v['id'] ])
  2169. ->select(['c.name'])
  2170. ->asArray()
  2171. ->all();
  2172. $pagination['data'][$k]['cat'] = $goods_cat;
  2173. if ($is_video_goods) {
  2174. $video_goods = VideoGoods::findOne(['store_id' => get_store_id(), 'goods_id' => $v['id'], 'is_delete' => 0]);
  2175. $pagination['data'][$k]['video_goods_id'] = $video_goods->id;
  2176. $pagination['data'][$k]['status'] = $video_goods->status;
  2177. }
  2178. }
  2179. unset($pagination['list']);
  2180. return [
  2181. 'code' => 0,
  2182. 'msg' => 'success',
  2183. 'data' => $pagination
  2184. ];
  2185. }
  2186. public static function warn_goods_timeout($store_id){
  2187. $conf = Option::get(OptionSetting::STORE_WARN_GOODS_TIMEOUT, $store_id, 'store', '0')['value'];
  2188. return $conf;
  2189. }
  2190. public static function warn_goods_timeout_save($store_id, $conf){
  2191. $set = Option::set(OptionSetting::STORE_WARN_GOODS_TIMEOUT, $conf, $store_id, 'store');
  2192. return [
  2193. 'code'=>$set ? 0 : 1,
  2194. 'msg'=>$set ? '保存成功' : '保存失败',
  2195. ];
  2196. }
  2197. }