HappinessCashierOrder.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <?php
  2. namespace addons\Happiness\common\models;
  3. use addons\MiniMall\common\enums\RedisKeyEnum;
  4. use addons\TeamLeader\common\models\UserPartitionRelationship;
  5. use common\components\export\CsvTool;
  6. use common\enums\DownloadEnum;
  7. use common\enums\OrderStatusEnum;
  8. use common\enums\RabbitMqEnum;
  9. use common\enums\StatusEnum;
  10. use common\helpers\ArrayHelper;
  11. use common\helpers\StringHelper;
  12. use common\models\base\BaseActiveRecord;
  13. use common\models\common\Download;
  14. use common\models\user\User;
  15. use Yii;
  16. use Exception;
  17. /**
  18. * This is the model class for table "qimall_addons_happiness_cashier_order".
  19. *
  20. * @property int $id
  21. * @property int $mall_id
  22. * @property int $store_id 门店id
  23. * @property int $user_id 会员id
  24. * @property string $order_no 订单编号
  25. * @property int $pay_time 付款时间
  26. * @property int $pay_status 支付状态
  27. * @property float $money 应付金额
  28. * @property float $pay_money 实付金额
  29. * @property int|null $payment_type 支付类型
  30. * @property float $amount_received 实收金额
  31. * @property float $service_money 服务费
  32. * @property string $remark 备注
  33. * @property string $extra 额外信息:例如优惠信息,渠道分红,经销分红
  34. * @property int $status 状态[0禁用 1启用 -1删除]
  35. * @property int $created_at 创建时间
  36. * @property int $updated_at 修改时间
  37. */
  38. class HappinessCashierOrder extends BaseActiveRecord
  39. {
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public static function tableName()
  44. {
  45. return '{{%addons_happiness_cashier_order}}';
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function rules()
  51. {
  52. return [
  53. [['mall_id', 'store_id', 'user_id', 'pay_status', 'pay_time', 'payment_type', 'status', 'created_at', 'updated_at'], 'integer'],
  54. [['money', 'pay_money', 'amount_received', 'service_money'], 'number'],
  55. [['order_no'], 'string', 'max' => 100],
  56. [['remark', 'extra'], 'string', 'max' => 255],
  57. ];
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function attributeLabels()
  63. {
  64. return [
  65. 'id' => 'ID',
  66. 'mall_id' => 'Mall ID',
  67. 'store_id' => '门店id',
  68. 'user_id' => '会员id',
  69. 'order_no' => '订单编号',
  70. 'pay_status' => '支付状态',
  71. 'pay_time' => '付款时间',
  72. 'money' => '应付金额',
  73. 'pay_money' => '实付金额',
  74. 'payment_type' => '支付类型',
  75. 'amount_received' => '实收金额',
  76. 'service_money' => '服务费',
  77. 'remark' => '备注',
  78. 'extra' => '额外信息:例如优惠信息,渠道分红,经销分红',
  79. 'status' => '状态[0禁用 1启用 -1删除]',
  80. 'created_at' => '创建时间',
  81. 'updated_at' => '修改时间',
  82. ];
  83. }
  84. public static function fieldsList($is_true=false)
  85. {
  86. $data= [
  87. 'user_id' => '会员ID',
  88. 'nickname' => '昵称',
  89. 'pay_time' => '付款时间',
  90. 'money' => '应付金额',
  91. 'pay_money' => '实付金额',
  92. 'extra' => '优惠信息',
  93. 'amount_received' => '实收金额',
  94. 'remark' => '备注',
  95. ];
  96. if($is_true){
  97. $data['store_name'] = '门店名称';
  98. }
  99. return $data;
  100. }
  101. public function getStore()
  102. {
  103. return $this->hasOne(HappinessStore::class, ['id' => 'store_id']);
  104. }
  105. /**
  106. * 异步导出至下载中心
  107. * @DateTime 2021-11-12 16:01:25
  108. * @param array $data
  109. * @copyright: Copyright (c) 2020 广东七件事集团
  110. */
  111. public static function exportHandle(array $data)
  112. {
  113. $download_id = $data['download_id'] ?? 0;
  114. $download = Download::findOne(['id' => $download_id]);
  115. if ($download) {
  116. try {
  117. $params = json_decode($download->params, true);
  118. $filename = $download->name;
  119. $type = $download->type;
  120. $model = self::find();
  121. $model->where(['mall_id' => $params['mall_id']]);
  122. $model->andWhere(['store_id' => $params['store_id']]);
  123. if (!empty($params['start'])) $model->andWhere(['>=', 'pay_time', strtotime($params['start'])]);
  124. if (!empty($params['end'])) $model->andWhere(['<=', 'pay_time', strtotime($params['end'])]);
  125. if (!empty($params['min'])) $model->andWhere(['>=', 'pay_money', $params['min']]);
  126. if (!empty($params['max'])) $model->andWhere(['<=', 'pay_money', $params['max']]);
  127. if (!empty($params['keyword'])) {
  128. $user_list = User::lists(['where' => [['mall_id' => $params['mall_id']], [
  129. 'or',
  130. ['like', 'username', $params['keyword']],
  131. ['like', 'nickname', $params['keyword']],
  132. ]], 'select' => 'id']);
  133. $user_ids = array_column($user_list, 'id');
  134. $model->andWhere(['in', 'user_id', $user_ids]);
  135. }
  136. $model->with(['user']);
  137. $fields = $params['fields'];
  138. $fields_arr = self::fieldsList();
  139. $have_select_field_arr = [];
  140. foreach ($fields as $value) {
  141. $have_select_field_arr[] = $fields_arr[$value];
  142. }
  143. $csv = new CsvTool();
  144. $csv->filename = $filename;
  145. $csv->file_dirname = DownloadEnum::getTypeStorageDirMap($type);
  146. $csv->export_mode = CsvTool::EXPORT_MODE_ASYNC;
  147. $csv->header = $have_select_field_arr;
  148. foreach ($model->batch() as $orders) {
  149. // $users 是一个包含100条或小于100条用户表数据的数组
  150. empty($csv->header) && $csv->header = array_keys($orders[0]);
  151. $csv->data = array_map(function ($order) use ($fields) {
  152. $row = [];
  153. foreach ($fields as $field) {
  154. if ($field == 'nickname') {
  155. $row[] = $order['user']['nickname'];
  156. } else if ($field == 'extra') {
  157. $extra = json_decode($order['extra'], true);
  158. $extra_content = '';
  159. $row[] = $extra_content;
  160. } else if ($field == 'pay_time') {
  161. $row[] = !empty($order['pay_time']) ? date('Y-m-d H:i:s', $order['pay_time']) : '';
  162. } else {
  163. if ((isset($order[$field]))) $row[] = $order[$field];
  164. }
  165. }
  166. return $row;
  167. }, $orders);
  168. $csv->export();
  169. }
  170. $url = $csv->upload($params['mall_id'], $csv->relative_filename);
  171. $download->status = 2;
  172. $download->url = $url;
  173. $download->num = $csv->line_num;
  174. $download->size = $csv->file_size;
  175. $res = $download->save();
  176. return true;
  177. } catch (\PHPUnit\Util\Exception $e) {
  178. $download->status = 3;
  179. self::setStaticError($e->getMessage());
  180. return false;
  181. }
  182. }
  183. }
  184. public function getUser()
  185. {
  186. return $this->hasOne(User::class, ['id' => 'user_id']);
  187. }
  188. public function getDetail()
  189. {
  190. return $this->hasMany(HappinessCashierOrderDetail::class, ['cashier_order_id' => 'id']);
  191. }
  192. public static function setData(array $params)
  193. {
  194. try {
  195. if (!empty($params['id'])) {
  196. $model = self::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]);
  197. if (empty($model)) throw new \Exception('商品不存在或已删除');
  198. } else {
  199. $model = new self();
  200. $model->loadDefaultValues();
  201. }
  202. if (!$model->load($params, '')) throw new \Exception($model->getErrorMessage());
  203. if (!$model->save()) throw new \Exception($model->getErrorMessage());
  204. return $model;
  205. } catch (\Exception $e) {
  206. self::$static_error = $e->getMessage();
  207. return false;
  208. }
  209. }
  210. //生成收银台订单
  211. public static function createOrder($data)
  212. {
  213. $t = Yii::$app->db->beginTransaction();
  214. try {
  215. $params['order_no'] = StringHelper::generateOrderNo('C');
  216. $order_trade_info[] = [
  217. 'order_no' => $params['order_no'],
  218. 'amount' => $data['money'],
  219. 'title' => $data['title'],
  220. 'notify_class' => 'addons\Happiness\common\logic\notify\CashierNotify',
  221. 'order_type' => 'cashier_order',
  222. ];
  223. //创建订单
  224. $params['pay_status'] = OrderStatusEnum::NOT_PAY;
  225. $params['service_money'] = 0;
  226. $params['amount_received'] = 0;
  227. $params['money']=0;
  228. $params['pay_money'] = $data['money'];
  229. $params['store_id'] = $data['store_id'];
  230. $params['mall_id'] = $data['mall_id'];
  231. $params['user_id'] = $data['user_id'];
  232. $store_cashier_order = self::setData($params);
  233. if ($store_cashier_order == false) throw new \Exception(self::getStaticError());
  234. $res = \Yii::$app->services->pay->createTrade($params['mall_id'], $params['user_id'], $order_trade_info);
  235. if ($res == false) throw new \Exception('生成支付流水失败');
  236. //生成支付流水
  237. $arr['transaction'] = $res;
  238. $t->commit();
  239. return $arr;
  240. } catch (\Exception $e) {
  241. $t->rollBack();
  242. self::$static_error = $e->getMessage();
  243. return false;
  244. }
  245. }
  246. public static function pay($params)
  247. {
  248. try {
  249. $trans = Yii::$app->db->beginTransaction();
  250. $model = self::findOne(['id' => $params['id'], 'status' => [StatusEnum::ENABLED]]);
  251. if (empty($model)) throw new \Exception('订单不存在或已删除');
  252. if ($model->pay_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理,无法进行支付');
  253. if ($model->pay_status == StatusEnum::ENABLED) throw new Exception('订单已支付,请不要重复支付');
  254. $model->payment_type = $params['pay_type'];
  255. $model->pay_status = StatusEnum::ENABLED;
  256. $model->amount_received = $model->pay_money;
  257. $model->pay_time = time();
  258. $res = $model->save();
  259. if ($res === false) throw new Exception('修改订单失败:' . $model->getErrorMessage());
  260. //HappinessCashierOrderDetail::updateAll(['order_status' => OrderStatusEnum::ACCOMPLISH],
  261. // ['cashier_order_id' => $model['id'], 'order_status' => OrderStatusEnum::NOT_PAY]);
  262. $trans->commit();
  263. // 触发订单支付事件,事务提交完成后触发
  264. //$event = new CashierOrderPaidEvent($model['mall_id']);
  265. //$order['id'] = $model['id'];
  266. //$order['operator_id'] = $params['operator_id'] ?? 0;
  267. //$order['operator_name'] = $params['operator_name'] ?? '';
  268. //Yii::$app->services->events->dispatch($event, $order, $event->listeners);
  269. } catch (\Exception $e) {
  270. self::$static_error = $e->getMessage();
  271. return false;
  272. }
  273. }
  274. public static function scanCode($params)
  275. {
  276. try {
  277. $add_user_data = [
  278. 'mall_id' => $params['mall_id'],
  279. 'user_id' => $params['user_id'],
  280. 'store_id' => $params['store_id'],
  281. ];
  282. $res = HappinessStoreUser::setData($add_user_data);
  283. if ($res == false) throw new \Exception('添加店铺会员失败');
  284. $store = HappinessStore::getOne([['id' => $params['store_id']]]);
  285. if (empty($params['user']['parent_id']) && !empty($store['scan_code_bind'])) {
  286. $user_id = $params['user_id'];
  287. $parent_id = $store['user_id'];
  288. $param = [
  289. 'user_id' => $user_id,
  290. 'parent_id' => $parent_id,
  291. ];
  292. $parent = User::getOne([['id' => $parent_id]]);
  293. $user = $params['user'];
  294. if($user['id']!=$parent_id){
  295. $parent_id_arr = UserPartitionRelationship::getParentIdArr($store['user_id']);
  296. if(!in_array($user['id'],$parent_id_arr)){
  297. $user->parent_id = $parent_id;
  298. $user->second_parent_id = $parent['parent_id'] ?? 0;
  299. $user->third_parent_id = $parent['second_parent_id'] ?? 0;
  300. $res = $user->save();
  301. if ($res === false) throw new $user->getErrorMessage();
  302. $param['is_admin'] = 0;
  303. $param['ip'] = ArrayHelper::get_client_ip();
  304. $param['operator_user_id'] = $param['user_id'];
  305. $res = \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK_CHANGE_RELATIONSHIP, RabbitMqEnum::CHANGE_RELATIONSHIP_QUEUE, $param, UserPartitionRelationship::class, 'changeRelationship');
  306. if ($res === false) throw new \PHPUnit\Util\Exception(UserPartitionRelationship::getStaticError());
  307. }
  308. }
  309. }
  310. return ['id' => $store['id'], 'store_name' => $store['store_name'], 'logo_img' => $store['logo_img']];
  311. } catch (\Exception $e) {
  312. self::$static_error = $e->getMessage();
  313. return false;
  314. }
  315. }
  316. public static function close($params,$force = false)
  317. {
  318. $trans = Yii::$app->db->beginTransaction();
  319. try {
  320. $cond = ['mall_id' => $params['mall_id'], 'status' => [StatusEnum::ENABLED]];
  321. if (isset($params['id'])) {
  322. $cond['id'] = $params['id'];
  323. } else {
  324. $cond['order_no'] = $params['order_no'];
  325. }
  326. isset($params['user_id']) && $cond['user_id'] = $params['user_id'];
  327. $model = self::findOne($cond);
  328. if (empty($model)) throw new Exception('订单不存在或已删除');
  329. // 判断订单是否已经被关闭
  330. if ($model->status == StatusEnum::DELETE) throw new Exception('订单已经关闭');
  331. // 判断是否是未支付的订单
  332. if ($force == false && $model->pay_status != OrderStatusEnum::NOT_PAY) throw new Exception('订单已经被处理');
  333. $model->status = StatusEnum::DELETE;
  334. if (!$model->save()) throw new Exception($model->getErrorMessage());
  335. $trans->commit();
  336. return true;
  337. } catch (\Exception $e) {
  338. $trans->rollBack();
  339. self::$static_error = $e->getMessage();
  340. return false;
  341. }
  342. }
  343. }