Ordervoucher.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models\alipay;
  8. use app\modules\admin\models\AlipayThirdForm;
  9. use app\models\ActivityOrdervoucher;
  10. use app\models\AlipayVoucherCodeTask;
  11. use app\models\AlipayVoucherCode;
  12. use app\models\Coupon;
  13. use app\models\CouponAutoSend;
  14. use app\models\User;
  15. use app\models\Store;
  16. use app\models\SaasUser;
  17. use app\models\UserCoupon;
  18. use yii\base\Model;
  19. use yii\data\Pagination;
  20. class Ordervoucher extends Model
  21. {
  22. public $activity_ordervoucher_id;
  23. public $mini_id;
  24. public $alipay_activity_id;
  25. public $store_id;
  26. public $pageSize = 5;
  27. public $page = 1;
  28. public $publish_start_time;
  29. public $publish_end_time;
  30. public $status;
  31. public $user_id;
  32. /**
  33. * {@inheritdoc}
  34. */
  35. public function rules()
  36. {
  37. return [
  38. [['store_id', 'mini_id', 'page', 'pageSize'], 'integer'],
  39. [['publish_start_time', 'publish_end_time', 'status', 'user_id'], 'safe'],
  40. ];
  41. }
  42. public function search() {
  43. $query = ActivityOrdervoucher::find();
  44. $query->andWhere(['mini_id' => $this->mini_id, 'is_delete' => 0]);
  45. $this->publish_end_time && $query->andWhere(['<=', 'publish_start_time', $this->publish_end_time]);
  46. $this->publish_start_time && $query->andWhere(['>=', 'publish_end_time', $this->publish_start_time]);
  47. intval($this->status) && $query->andWhere(['status' => $this->status]);
  48. $count = $query->count();
  49. $pagination = new Pagination(['totalCount' => $count, 'pageSize' => $this->pageSize, 'page' => $this->page - 1]);
  50. $list = $query->limit($pagination->limit)->offset($pagination->offset)->orderBy('id DESC')->all();
  51. $newList = [];
  52. foreach ($list as $item) {
  53. $alipayRes = $this->queryAlipayOV($item->alipay_activity_id);
  54. if($alipayRes['code'] == 0){
  55. $status = 0;
  56. if($alipayRes['data']->activity_status == 'ACTIVE'){
  57. $status = 1;
  58. }
  59. if($alipayRes['data']->activity_status == 'FINISHED'){
  60. $status = 2;
  61. }
  62. if($status != intval($item->status)){
  63. $item->status = $status;
  64. $item->save();
  65. }
  66. }
  67. $newList[] = array_merge($item->attributes, (array)$alipayRes['data']);
  68. }
  69. return [
  70. 'code' => 0,
  71. 'msg' => 'ok',
  72. 'count' => $count,
  73. 'data' => $newList,
  74. ];
  75. }
  76. public function queryAlipayOV($activity_id = 0) {
  77. $form = new AlipayThirdForm();
  78. $form->mini_id = $this->mini_id;
  79. $res = $form->AlipayMarketingActivityOrdervoucherQuery($activity_id);
  80. return $res;
  81. }
  82. //创建商家券活动
  83. public function remove() {
  84. $condition = [
  85. 'mini_id' => $this->mini_id,
  86. 'alipay_activity_id' => $this->alipay_activity_id,
  87. ];
  88. $model = ActivityOrdervoucher::findOne($condition);
  89. if(!$model){
  90. return [
  91. 'code' => 1,
  92. 'msg' => '参数错误',
  93. ];
  94. }
  95. $model->is_delete = 1;
  96. if(!$model->save()){
  97. return [
  98. 'code' => 1,
  99. 'msg' => '操作失败',
  100. ];
  101. }
  102. return [
  103. 'code' => 0,
  104. 'msg' => 'ok',
  105. ];
  106. }
  107. //创建商家券活动
  108. public function create($coupon_id = 0, $params = []) {
  109. $coupon = Coupon::findOne($coupon_id);
  110. if(!$coupon){
  111. return [
  112. 'code' => 1,
  113. 'msg' => '优惠券id错误',
  114. ];
  115. }
  116. $t = \Yii::$app->db->beginTransaction();
  117. $activity = new ActivityOrdervoucher();
  118. $activity->mini_id = $this->mini_id;
  119. $activity->store_id = $this->store_id;
  120. $activity->coupon_id = $coupon_id;
  121. $activity->publish_start_time = $params['publish_start_time'];
  122. $activity->publish_end_time = $params['publish_end_time'];
  123. if(!$activity->save()){
  124. $t->rollBack();
  125. return [
  126. 'code' => 1,
  127. 'msg' => $activity->errors[0],
  128. ];
  129. }
  130. $form = new AlipayThirdForm();
  131. $form->mini_id = $this->mini_id;
  132. $biz_content = [];
  133. $biz_content = $this->modelToBiz($coupon, $biz_content);
  134. $biz_content['customer_guide']['voucher_use_guide']['mini_app_path'] = $params['mini_app_path'];
  135. $biz_content['publish_start_time'] = $params['publish_start_time'];
  136. $biz_content['publish_end_time'] = $params['publish_end_time'];
  137. $res = $form->AlipayMarketingActivityOrdervoucherCreate($biz_content);
  138. if($res['code'] !== 0){
  139. $t->rollBack();
  140. return $res;
  141. }
  142. $activity_id = $res['data']->activity_id;
  143. $activity->alipay_activity_id = $activity_id;
  144. $activity->save();
  145. $t->commit();
  146. return $res;
  147. }
  148. public function modelToBiz($coupon, $biz_content = []) {
  149. // $biz_content = [
  150. // 'publish_start_time' => $coupon['name'],
  151. // 'publish_end_time' => $coupon['name'],
  152. // ];
  153. $biz_content['activity_name'] = $coupon['name'];
  154. $biz_content['code_mode'] = 'MERCHANT_UPLOAD';
  155. $biz_content['voucher_type'] = 'FIX_VOUCHER';
  156. $biz_content['out_biz_no'] = date('Y-m-dH:i:s') . rand(100000, 999999);
  157. $biz_content['belong_merchant_info'] = [
  158. 'business_type' => 'ISV_FOR_MERCHANT',
  159. 'merchant_id_type' => 'PID',
  160. 'merchant_id' => '0',
  161. ];
  162. $biz_content['voucher_display_info'] = [
  163. 'voucher_description' => $coupon['rule'] . ' ',
  164. ];
  165. if($coupon['expire_type'] == 1){
  166. $biz_content['voucher_use_rule'] = [
  167. 'voucher_valid_period' => [
  168. 'type' => 'RELATIVE',
  169. 'valid_days_after_receive' => $coupon['expire_day'],
  170. 'valid_end_time' => $coupon['end_time'],
  171. ]
  172. ];
  173. }
  174. if($coupon['expire_type'] == 2){
  175. $biz_content['voucher_use_rule'] = [
  176. 'voucher_valid_period' => [
  177. 'type' => 'ABSOLUTE',
  178. 'valid_begin_time' => date('Y-m-d H:i:s', $coupon['begin_time']),
  179. 'valid_end_time' => date('Y-m-d H:i:s', $coupon['end_time']),
  180. ]
  181. ];
  182. }
  183. $biz_content['voucher_use_rule']['voucher_available_scope'] = [
  184. 'voucher_available_type' => 'CITY_CODE',
  185. 'order_voucher_available_city_code' => [
  186. 'all_city' => true,
  187. ],
  188. ];
  189. //满减
  190. if($coupon['discount_type'] == 2){
  191. $biz_content['voucher_type'] = 'FIX_VOUCHER';
  192. $biz_content['voucher_use_rule']['fix_voucher'] = [
  193. 'amount' => $coupon['sub_price'],
  194. ];
  195. if(intval($coupon['min_price']) > 0){
  196. $biz_content['voucher_use_rule']['fix_voucher']['floor_amount'] = $coupon['min_price'];
  197. }
  198. }
  199. //折扣
  200. if($coupon['discount_type'] == 1){
  201. $biz_content['voucher_type'] = 'DISCOUNT_VOUCHER';
  202. $biz_content['voucher_use_rule']['discount_voucher'] = [
  203. 'discount' => $coupon['discount'],
  204. 'ceiling_amount' => 5000.00,
  205. ];
  206. if(intval($coupon['min_price']) > 0){
  207. $biz_content['voucher_use_rule']['discount_voucher']['floor_amount'] = $coupon['min_price'];
  208. }
  209. }
  210. $biz_content['voucher_send_rule'] = [
  211. 'voucher_quantity' => 0,
  212. ];
  213. $biz_content['customer_guide'] = [
  214. 'voucher_use_guide' => [
  215. 'offline_code_use_guide' => true,
  216. 'mini_app_use_guide' => true,
  217. 'mini_app_id' => '',
  218. 'mini_app_path' => '',
  219. ],
  220. ];
  221. return $biz_content;
  222. }
  223. //创建商家券券码
  224. public function createCodes($count = 100) {
  225. if($count > 1000 || $count < 1){
  226. return [
  227. 'code' => 1,
  228. 'msg' => '单次最大生成1000 个,最少1个',
  229. ];
  230. }
  231. $t = \Yii::$app->db->beginTransaction();
  232. try{
  233. $ordercoucher = ActivityOrdervoucher::findOne($this->activity_ordervoucher_id);
  234. // var_dump($ordercoucher);
  235. if(!$ordercoucher || !$ordercoucher->alipay_activity_id){
  236. $t->rollBack();
  237. return [
  238. 'code' => 1,
  239. 'msg' => '商家券活动不存在',
  240. ];
  241. }
  242. $task = new AlipayVoucherCodeTask();
  243. $task->store_id = $this->store_id;
  244. $task->mini_id = $this->mini_id;
  245. $task->activity_ordervoucher_id = $this->activity_ordervoucher_id;
  246. if(!$task->save()){
  247. $t->rollBack();
  248. return [
  249. 'code' => 1,
  250. 'msg' => $task->errors[0],
  251. ];
  252. }
  253. $codes = $this->randCodes($count);
  254. $data = [];
  255. foreach ($codes as $code) {
  256. $data[] = [$this->store_id, $this->mini_id, $task->activity_ordervoucher_id, $code];
  257. }
  258. $count = \Yii::$app->db->createCommand()->batchInsert(AlipayVoucherCode::tableName(), ['store_id', 'mini_id', 'activity_ordervoucher_id', 'voucher_code'], $data)->execute();
  259. if(!$count){
  260. $t->rollBack();
  261. return [
  262. 'code' => 1,
  263. 'msg' => '操作失败',
  264. ];
  265. }
  266. $form = new AlipayThirdForm();
  267. $form->mini_id = $this->mini_id;
  268. $res = $form->AlipayMarketingActivityOrdervoucherCodedeposit($ordercoucher->alipay_activity_id, $codes, microtime(true));
  269. if($res['code'] !== 0){
  270. $t->rollBack();
  271. return $res;
  272. }
  273. $task->is_upload = 1;
  274. $task->save();
  275. } catch (\Exception $e){
  276. $t->rollBack();
  277. return [
  278. 'code' => 1,
  279. 'msg' => $e->getMessage(),
  280. ];
  281. }
  282. $t->commit();
  283. return $res;
  284. }
  285. private function randCodes($count = 100) {
  286. $codes = [];
  287. $mtime = str_replace('.', '', microtime(true));
  288. $irand = 1000;
  289. for($i = 0; $i < $count; $i++){
  290. $irand += rand(1, 8);
  291. $rand = 'ov' . $this->mini_id . $mtime . $irand;
  292. $codes[] = $rand;
  293. }
  294. return $codes;;
  295. }
  296. //更新券数量
  297. public function refresh() {
  298. $form = new AlipayThirdForm();
  299. $form->mini_id = $this->mini_id;
  300. $res = $form->AlipayMarketingActivityOrdervoucherCodecount($this->alipay_activity_id);
  301. $count = 0;
  302. if($res['code'] == 0){
  303. $count = $res['data']->success_count;
  304. }else{
  305. return $res;
  306. }
  307. if(!$count){
  308. return [
  309. 'code' => 1,
  310. 'msg' => '已经导入的券码数量是0',
  311. ];
  312. }
  313. $form = new AlipayThirdForm();
  314. $form->mini_id = $this->mini_id;
  315. $biz_content = [
  316. 'activity_id' => $this->alipay_activity_id,
  317. 'voucher_quantity' => $count,
  318. 'out_biz_no' => microtime(true),
  319. ];
  320. $res = $form->AlipayMarketingActivityOrdervoucherAppend($biz_content);
  321. return $res;
  322. }
  323. public function use($submit = 0, $ov = '', $total_price = 100) {
  324. try {
  325. $alipay_code = AlipayVoucherCode::findOne(['voucher_code' => $ov, 'store_id' => $this->store_id, 'mini_id' => $this->mini_id, 'status' => 0]);
  326. if (empty($alipay_code)) {
  327. \Yii::error([__METHOD__, $ov, $this->store_id, $this->mini_id]);
  328. throw new \Exception('商家券券码错误');
  329. }
  330. $activity_ordervoucher = ActivityOrdervoucher::findOne([$alipay_code->activity_ordervoucher_id]);
  331. $coupon = Coupon::findOne($activity_ordervoucher['coupon_id']);
  332. if (empty($coupon)) {
  333. \Yii::error([__METHOD__, $ov, $this->store_id, $this->mini_id]);
  334. throw new \Exception('系统券未找到.');
  335. }
  336. if($total_price < $coupon['min_price']){
  337. throw new \Exception('不满足优惠券的最低消费');
  338. }
  339. if ($coupon['discount_type'] == 1) {
  340. $sub_price = doubleval($total_price * $coupon['discount'] / 10);
  341. } else {
  342. $sub_price = doubleval($coupon['sub_price']);
  343. }
  344. if(!$submit){
  345. return [
  346. 'code' => 0,
  347. 'ov' => $ov,
  348. 'coupon' => $coupon,
  349. 'total_price' => $total_price,
  350. 'sub_price' => $sub_price,
  351. ];
  352. }
  353. $user_coupon = UserCoupon::findOne(['voucher_code_id' => $alipay_code['id']]);
  354. if ($user_coupon) {
  355. $user_coupon->is_use = 1;
  356. $user_coupon->save();
  357. }
  358. $order_voucher = ActivityOrdervoucher::findOne($alipay_code->activity_ordervoucher_id);
  359. if (empty($order_voucher)) {
  360. \Yii::error([__METHOD__, $ov, $this->store_id, $this->mini_id]);
  361. throw new \Exception('商家券活动未找到');
  362. }
  363. $data = [
  364. 'activity_id' => $order_voucher->alipay_activity_id,
  365. 'biz_dt' => date('Y-m-d H:i:s'),
  366. 'voucher_code' => $alipay_code->voucher_code,
  367. 'trade_channel' => 'OTHER_TRADE_CHANNEL',
  368. 'total_fee' => $total_price,
  369. ];
  370. $form = new AlipayThirdForm();
  371. $result = $form->AlipayMarketingActivityOrdervoucherUse($data);
  372. $file_name = \Yii::$app->runtimePath . '/logs/app_order_voucherUse.log';
  373. file_put_contents($file_name, "\r\n" . '[核销结果推送][' . date('Y-m-d H:i:s') . ']['.$ov.']' . json_encode($result), FILE_APPEND);
  374. if ($result['code'] === 0) {
  375. $alipay_code->status = 1;
  376. $alipay_code->clerk_saas_id = $this->user_id;
  377. $alipay_code->total_price = $total_price;
  378. $alipay_code->sub_price = $sub_price;
  379. $alipay_code->save();
  380. $result['ov'] = $ov;
  381. $result['coupon'] = $coupon;
  382. $result['total_price'] = $total_price;
  383. $result['sub_price'] = $sub_price;
  384. }
  385. return $result;
  386. } catch (\Exception $e) {
  387. \Yii::error([__METHOD__, $e, $this->store_id, $this->mini_id]);
  388. return [
  389. 'code' => 1,
  390. 'msg' => '操作失败。' . $e->getMessage()
  391. ];
  392. }
  393. }
  394. }