cardModel = new WxCard(); $this->bindModel = new WxCardBind(); } private function card_get($card_id) { $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/get', [ "card_id" => $card_id, ]); /** * { "errcode": 0, "errmsg": "ok", "card": { "card_type": "MEMBER_CARD", "member_card": { "base_info": { "id": "pBolB1m7MANGetesAPo8LpdJVeYk", "logo_url": "http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZ/0", "code_type": "CODE_TYPE_TEXT", "brand_name": "海底捞", "title": "海底捞会员卡3", "date_info": { "type": "DATE_TYPE_PERMANENT" }, "color": "#63b359", "notice": "使用时向服务员出示此券", "service_phone": "020-88888888", "description": "不可与其他优惠同享", "location_id_list": [], "get_limit": 3, "can_give_friend": true, "use_custom_code": false, "status": "CARD_STATUS_VERIFY_OK", "sku": { "quantity": 49999999, "total_quantity": 50000000 }, "create_time": 1661329877, "update_time": 1661329908, "custom_url_name": "立即使用", "custom_url": "http://weixin.qq.com", "custom_url_sub_title": "6个汉字tips", "promotion_url": "http://www.qq.com", "promotion_url_name": "营销入口1", "need_push_on_view": true, "area_code_list": [] }, "supply_bonus": true, "supply_balance": false, "prerogative": "test_prerogative", "activate_url": "http://www.qq.com", "discount": 10, "custom_cell1": { "name": "使用入口2", "tips": "激活后显示", "url": "http://www.qq.com" }, "auto_activate": false, "wx_activate": true, "custom_field1": { "name_type": "FIELD_NAME_TYPE_LEVEL", "url": "http://www.qq.com" }, "bonus_rule": { "cost_money_unit": 100, "increase_bonus": 1, "max_increase_bonus": 200, "init_increase_bonus": 10, "cost_bonus_unit": 5, "reduce_money": 100, "least_money_to_use_bonus": 1000, "max_reduce_bonus": 50 }, "background_pic_url": "https://mmbiz.qlogo.cn/mmbiz/", "wx_activate_after_submit": false, "advanced_info": { "time_limit": [ { "type": "MONDAY", "begin_hour": 0, "begin_minute": 10, "end_hour": 10, "end_minute": 59 }, { "type": "HOLIDAY" } ], "text_image_list": [ { "image_url": "http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sjpiby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0", "text": "此菜品精选食材,以独特的烹饪方法,最大程度地刺激食 客的味蕾" }, { "image_url": "http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sj piby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0", "text": "此菜品迎合大众口味,老少皆宜,营养均衡" } ], "business_service": [ "BIZ_SERVICE_FREE_WIFI", "BIZ_SERVICE_WITH_PET", "BIZ_SERVICE_FREE_PARK", "BIZ_SERVICE_DELIVER" ], "consume_share_card_list": [], "abstract": { "abstract": "微信餐厅推出多种新季菜品,期待您的光临", "icon_url_list": [ "http://mmbiz.qpic.cn/mmbiz/p98FjXy8LacgHxp3sJ3vn97bGLz0ib0Sfz1bjiaoOYA027iasqSG0sjpiby4vce3AtaPu6cIhBHkt6IjlkY9YnDsfw/0" ] }, "use_condition": { "accept_category": "鞋类", "reject_category": "阿迪达斯", "can_use_with_other_discount": true }, "share_friends": false } } } } */ \Yii::error([__METHOD__, $card_id, $res]); return $res; } private function card_membercard_userinfo_get($code, $card_id) { $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/membercard/userinfo/get', [ "card_id" => $card_id, "code" => $code, ]); /** * { "errcode": 0, "errmsg": "ok", "openid": "oBolB1pon-jHiNVRZ8fgD8NMfxHg", "nickname": "xxx", "membership_number": "916992940983", "bonus": 3000, "sex": "MALE", "user_info": { "common_field_list": [ { "name": "USER_FORM_INFO_FLAG_MOBILE", "value": "12111111111", "value_list": [] } ], "custom_field_list": [] }, "user_card_status": "NORMAL", "has_active": true } */ \Yii::error([__METHOD__, $code, $card_id, $res]); return $res; } private function card_membercard_updateuser($param) { $json = '{ "code": "555075127057", "card_id": "pBolB1m7MANGetesAPo8LpdJVeYk", "record_bonus": "消费30元,获得3积分", "bonus": 3000, "add_bonus": 30, "notify_optional": { "is_notify_bonus": true, } }'; $icard = json_decode($json, true); $icard['code'] = $param['code']; $icard['card_id'] = $param['card_id']; $icard['record_bonus'] = $param['record_bonus']; $icard['bonus'] = $param['bonus']; $icard['add_bonus'] = $param['add_bonus']; $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/membercard/updateuser', $icard); /** * { "errcode": 0, "errmsg": "ok", "result_bonus": 3000, "result_balance": 0, "openid": "oBolB1pon-jHiNVRZ8fgD8NMfxHg" } */ \Yii::error([__METHOD__, $param, $icard, $res]); return $res; } private function card_membercard_activate_geturl($card_id) { $json = '{ "card_id": "pBolB1m7MANGetesAPo8LpdJVeYk", }'; $icard = json_decode($json, true); $icard['card_id'] = $card_id; $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/membercard/activate/geturl', $icard); /** * { "errcode": 0, "errmsg": "ok", "url": "https://mp.weixin.qq.com/bizmall/activatemembercard?action=preshow&&encrypt_card_id=QjjuuGjJMbUHVOF8Me5raozNfHEGeVP6Um31MiJDw7pxLas%2Bvp%2FXRXS%2FT%2BRNUVMh&biz=MzU5NDYxOTE0Mg%3D%3D#wechat_redirect" } */ \Yii::error([__METHOD__, $res]); return $res; } private function card_membercard_activateuserform_set($card_id) { $json = '{ "card_id": "pBolB1m7MANGetesAPo8LpdJVeYk", "required_form": { "can_modify": false, "common_field_id_list": [ "USER_FORM_INFO_FLAG_MOBILE" ] } }'; $icard = json_decode($json, true); $icard['card_id'] = $card_id; $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/membercard/activateuserform/set', $icard); /** * { "errcode": 0, "errmsg": "ok" } */ \Yii::error([__METHOD__, $res]); return $res; } private function card_create(&$wx_materials, $param, $store_id) { $form = new WechatConfigForm(); $form->store_id = $store_id; $form->type = 1; $conf = $form->getConfig(); $mini_user_name = $conf['data']['mini']['gh_wechat_app_id']; $mini_page = '/pages/my/my'; $json = '{ "card": { "card_type": "MEMBER_CARD", "member_card": { "wx_activate":true, "auto_activate": false, "wx_activate_after_submit" : false, "background_pic_url": "https://mmbiz.qlogo.cn/mmbiz/", "base_info": { "logo_url": "http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZ/0", "brand_name": "海底捞", "code_type": "CODE_TYPE_TEXT", "title": "海底捞会员卡5", "color": "Color010", "notice": "使用时向服务员出示此券", "service_phone": "020-88888888", "description": "\n不可与其他优惠同享\n", "date_info": { "type": "DATE_TYPE_PERMANENT" }, "sku": { "quantity": 50000000 }, "get_limit": 1, "use_custom_code": false, "can_give_friend": false, "use_all_locations": true, "custom_url_name": "会员中心", "custom_url": "http://weixin.qq.com", "custom_app_brand_user_name": "' . $mini_user_name . '@app", "custom_app_brand_pass":"' . $mini_page . '", "custom_url_sub_title": "查询更多信息" }, "advanced_info": { "abstract": { "abstract": "微信餐厅推出多种新季菜品,期待您的光临" } }, "supply_bonus": true, "supply_balance": false, "prerogative": "特权说明" } } }'; $icard = json_decode($json, true); $background_pic_url = $this->wxUploadImage($param['background_pic_url']); if (isset($background_pic_url['code']) && $background_pic_url['code'] === 1) { return $background_pic_url; } $logo_url = $this->wxUploadImage($param['logo_url']); if (isset($logo_url['code']) && $logo_url['code'] === 1) { return $logo_url; } $wx_materials[] = $background_pic_url['media_id']; $wx_materials[] = $logo_url['media_id']; $icard['card']['member_card']['background_pic_url'] = $background_pic_url['url']; $icard['card']['member_card']['base_info']['logo_url'] = $logo_url['url']; $icard['card']['member_card']['base_info']['brand_name'] = $param['brand_name']; $icard['card']['member_card']['base_info']['title'] = $param['title']; $icard['card']['member_card']['base_info']['service_phone'] = $param['service_phone']; $icard['card']['member_card']['base_info']['description'] = $param['description']; $icard['card']['member_card']['advanced_info']['abstract']['abstract'] = $param['abstract']; $param['text_image_list'] && $icard['card']['member_card']['advanced_info']['text_image_list'] = $param['text_image_list']; $icard['card']['member_card']['prerogative'] = $param['prerogative']; $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/create', $icard); /** * [ 'errcode' => 0, 'errmsg' => 'ok', 'card_id' => 'pBolB1i00fKL6dqh8ojvMqPAJXfg', ] */ \Yii::error([__METHOD__, $res]); return $res; } private function card_update(&$wx_materials, $param) { $json = '{ "card_id": "ph_gmt7cUVrlRk8swPwx7aDyF-pg", "member_card": { "background_pic_url": "https://mmbiz.qlogo.cn/mmbiz/0?wx_fmt=jpeg", "base_info": { "title": "海底捞会员卡5", "logo_url": "http:\/\/www.supadmin.cn\/uploads\/allimg\/120216\/1_120216214725_1.jpg", "color": "Color010", "notice": "使用时向服务员出示此券", "service_phone": "020-88888888", "description": "\n不可与其他优惠同享\n" }, "prerogative": "" } }'; $icard = json_decode($json, true); $background_pic_url = $this->wxUploadImage($param['background_pic_url']); if (isset($background_pic_url['code']) && $background_pic_url['code'] === 1) { return $background_pic_url; } $logo_url = $this->wxUploadImage($param['logo_url']); if (isset($logo_url['code']) && $logo_url['code'] === 1) { return $logo_url; } $wx_materials[] = $background_pic_url['media_id']; $wx_materials[] = $logo_url['media_id']; $icard['card_id'] = $param['card_id']; $icard['member_card']['background_pic_url'] = $background_pic_url['url']; $icard['member_card']['base_info']['logo_url'] = $logo_url['url']; $icard['member_card']['base_info']['title'] = $param['title']; $icard['member_card']['base_info']['service_phone'] = $param['service_phone']; $icard['member_card']['base_info']['description'] = $param['description']; $icard['member_card']['prerogative'] = $param['prerogative']; $api = $this->wechat_mp->card; $res = $api->httpPostJson('/card/update', $icard); /** * { "errcode":0, "errmsg":"ok", "send_check":true } */ \Yii::error([__METHOD__, $res]); return $res; } //获取卡参数 public function getUrl($card_id) { $res = [ 'code' => 0, 'msg' => 'ok', 'encrypt_card_id' => '', 'biz' => '', 'url' => '', ]; $wxres = $this->card_membercard_activate_geturl($card_id); if($wxres['errcode'] == 0 && !empty($wxres['url'])){ $arr = parse_url($wxres['url']); parse_str($arr['query'], $query); $res['encrypt_card_id'] = $query['encrypt_card_id']; $res['biz'] = $query['biz']; $res['url'] = $wxres['url']; $res['card_id'] = $card_id; } return $res; } //获取卡参数 public function getUrlByStoreId($store_id) { $card = $this->getCardInfoByStoreId($store_id); if(!$card){ return [ 'code' => 1, 'msg' => '未找到卡信息', ]; } $card_id = $card->card_id; return $this->getUrl($card_id); } //获取会员 public function getUser($code, $card_id) { $res = [ 'code' => 1, 'msg' => 'faild', ]; $wxres = $this->card_membercard_userinfo_get($code, $card_id); $res['data'] = $wxres; if($wxres['errcode'] == 0){ $res['code'] = 0; $res['msg'] = 'ok'; } return $res; } //获取会员手机号 public function getPhone($code, $card_id) { $wxres = $this->card_membercard_userinfo_get($code, $card_id); if($wxres['errcode'] == 0 && is_array($wxres['user_info']['common_field_list'])){ foreach ($wxres['user_info']['common_field_list'] as $item) { if($item['name'] == 'USER_FORM_INFO_FLAG_MOBILE'){ return $item['value']; } } } return ''; } //绑卡 public function bindSaas($code, $card_id, $openid, $OuterStr) { $phone = $this->getPhone($code, $card_id); if($phone){ $cardInfo = $this->getCardInfo($card_id); if(!$cardInfo){ \yii::error([__METHOD__, '系统中没有找到会员卡', $phone, $card_id]); return [ 'code' => 1, 'message' => '系统中没有找到会员卡', ]; } $user = User::findOne(['store_id' => $cardInfo->store_id, 'binding' => $phone]); if(!$user){ \yii::error([__METHOD__, '领卡手机号在系统中没有找到会员', $phone, $cardInfo]); return [ 'code' => 1, 'message' => '领卡手机号在系统中没有找到会员', ]; } $hasBind = $this->getBind($card_id, $user->id); if($hasBind){ \yii::error([__METHOD__, '当前会员已经绑定过此会员卡', $card_id, $user->id, $hasBind]); return [ 'code' => 1, 'message' => '当前会员已经绑定过此会员卡', ]; } $save = $this->saveBind([ 'store_id' => $cardInfo->store_id, 'card_id' => $card_id, 'code' => $code, 'phone' => $phone, 'openid' => $openid, 'user_id' => $user->id, 'outer_str' => $OuterStr, ]); if($save && $user->integral){ $res = $this->updateUser($this->getBind($card_id, $user->id), [ "record_bonus" => "首次同步系统积分", "bonus" => $user->integral, "add_bonus" => 0, ]); return $res; } }else{ \yii::error([__METHOD__, '没有查到手机号', $code, $card_id]); return [ 'code' => 1, 'message' => '没有查到手机号', ]; } return [ 'code' => 1, 'message' => '失败', ]; } //获取卡列表 public function getCardList($params = [], $store_id = 0) { $query = $this->cardModel::find()->where(['is_delete' => 0]); if(isset($params['card_store_id']) && $params['card_store_id'] > 0){ $query->andWhere(['store_id' => $params['card_store_id']]); } if(!empty($params['card_id'])){ $query->andWhere(['card_id' => $params['card_id']]); } if(!empty($params['title'])){ $query->andWhere(['title' => $params['title']]); } if(!empty($params['brand_name'])){ $query->andWhere(['brand_name' => $params['brand_name']]); } if($store_id > 0){ $query->andWhere(['store_id' => $store_id]); } $query->orderBy('id DESC'); $data = pagination_make($query); foreach ($data['list'] as &$item) { $wxRes = $this->card_get($item['card_id']); $item['wxRes'] = $wxRes; } return [ 'code' => 0, 'msg' => 'ok', 'data' => $data, 'store_list' => Store::nameList(), ]; } //获取卡信息 public function getCardInfo($card_id) { $card = $this->cardModel::findOne(['card_id' => $card_id]); return $card; } //获取卡信息 public function getCardInfoByStoreId($store_id) { $card = $this->cardModel::findOne(['store_id' => $store_id, 'is_delete' => 0]); return $card; } //保存卡 public function saveCardInfo($wx_materials, $card_id, $param, $store_id = 0) { $model = $this->cardModel; $card = $model->findOne(['card_id' => $card_id]); if($card){ $model = $card; $materials = json_decode($model->wx_materials, true); if($materials){ $wx_materials = array_merge($materials, $wx_materials); } $model->title = $param['title']; $model->logo_url = $param['logo_url']; $model->background_pic_url = $param['background_pic_url']; $model->prerogative = $param['prerogative']; $model->wx_materials = json_encode($wx_materials); $save = $model->save(); \Yii::error($model->getErrors()); return $save; } $model->card_id = $card_id; $store_id > 0 && $model->store_id = $store_id; $model->title = $param['title']; $model->brand_name = $param['brand_name']; $model->logo_url = $param['logo_url']; $model->background_pic_url = $param['background_pic_url']; $model->prerogative = $param['prerogative']; $model->wx_materials = json_encode($wx_materials); $save = $model->save(); \Yii::error($model->getErrors()); return $save; } //获取绑卡列表查询条件 private function getBindListQuery($params = [], $store_id = 0) { $query = $this->bindModel::find()->where(['b.is_delete' => 0]); $query->alias('b')->leftJoin(['c' => $this->cardModel->tableName()], 'b.card_id = c.card_id')->andWhere(['c.is_delete' => 0]); if(isset($params['card_store_id']) && $params['card_store_id'] > 0){ $query->andWhere(['b.store_id' => $params['card_store_id']]); } if(!empty($params['card_id'])){ $query->andWhere(['b.card_id' => $params['card_id']]); } if(!empty($params['code'])){ $query->andWhere(['b.code' => $params['code']]); } if(!empty($params['phone'])){ $query->andWhere(['b.phone' => $params['phone']]); } if($store_id > 0){ $query->andWhere(['b.store_id' => $store_id]); $storeCard = $this->getCardInfoByStoreId($store_id); $query->andWhere(['b.card_id' => $storeCard['card_id']]); } return $query; } //获取绑卡列表 public function getBindList($params = [], $store_id = 0) { $query = $this->getBindListQuery($params, $store_id); $query->orderBy('id DESC'); $data = pagination_make($query); foreach ($data['list'] as &$item) { $user = User::findOne($item['user_id']); $item['nickname'] = $user->nickname; $item['avatar_url'] = $user->avatar_url; } return [ 'code' => 0, 'msg' => 'ok', 'data' => $data, 'sql' => $query->createCommand()->getRawSql(), 'store_list' => Store::nameList(), ]; } //获取绑卡ID列表 public function getBindIdList($params = [], $store_id = 0) { $query = $this->getBindListQuery($params, $store_id); $query->select('b.id'); $list = $query->column(); return $list; } //获取绑卡信息 public function getBind($card_id, $user_id) { $bind = $this->bindModel::findOne([ 'card_id' => $card_id, 'user_id' => $user_id, ]); return $bind; } //获取绑卡信息 public function getBindById($id) { $bind = $this->bindModel::findOne($id); return $bind; } //获取绑卡信息 public function getBindByUserId($user_id, $store_id) { $card = $this->getCardInfoByStoreId($store_id); if(!$card){ return false; } $card_id = $card->card_id; return $this->getBind($card_id, $user_id); } //绑卡 public function saveBind($param) { $model = $this->bindModel; $model->attributes = $param; $save = $model->save(); \Yii::error($model->getErrors()); return $save; } //创建卡 public function addCard($param, $store_id = 0) { $hasCard = $this->getCardInfoByStoreId($store_id); if($hasCard){ return [ 'code' => 1, 'msg' => '当前已存在会员卡,创建新卡之前请删除旧卡:' . $hasCard->title, ]; } $wx_materials = []; $wxres = $this->card_create($wx_materials, $param, $store_id); if (isset($wxres['code']) && $wxres['code'] === 1) { return $wxres; } if($wxres['errcode'] == 0 && !empty($wxres['card_id'])){ $card_id = $wxres['card_id']; $wxres = $this->card_membercard_activateuserform_set($card_id); if($wxres['errcode'] == 0){ $res = $this->saveCardInfo($wx_materials, $card_id, $param, $store_id); if($res){ return [ 'code' => 0, 'msg' => '成功', ]; } } } $this->wxDelMaterial($wx_materials); if($wxres['errcode'] > 0){ return [ 'code' => $wxres['errcode'], 'msg' => $wxres['errmsg'], ]; } return [ 'code' => 1, 'msg' => '操作失败', ]; } //修改卡 public function updateCard($param, $store_id = 0) { $wx_materials = []; $wxres = $this->card_update($wx_materials, $param); if (isset($wxres['code']) && $wxres['code'] === 1) { return $wxres; } if($wxres['errcode'] == 0){ $card_id = $param['card_id']; $res = $this->saveCardInfo($wx_materials, $card_id, $param, $store_id); if($res){ return [ 'code' => 0, 'msg' => '成功', ]; } } $this->wxDelMaterial($wx_materials); if($wxres['errcode'] > 0){ return [ 'code' => $wxres['errcode'], 'msg' => $wxres['errmsg'], ]; } return [ 'code' => 1, 'msg' => '操作失败', ]; } //删除卡 public function deleteCard($card_id) { $card = $this->getCardInfo($card_id); $card->is_delete = 1; $res = $card->save(); if($res){ $wx_materials = json_decode($card->wx_materials, true); if($wx_materials){ $this->wxDelMaterial($wx_materials); } return [ 'code' => 0, 'msg' => '成功', ]; } return [ 'code' => 1, 'msg' => '操作失败', ]; } //修改会员积分 public function updateUserBonus($bind, $param) { $res = AccountLog::saveLog($bind->user_id, $param['add_bonus'], AccountLog::TYPE_INTEGRAL, AccountLog::LOG_TYPE_INCOME, 0, 0, $param['record_bonus']); if($res){ return [ 'code' => 0, 'msg' => '成功', ]; } return [ 'code' => 1, 'msg' => '操作失败', ]; } //修改会员信息 public function updateUser($bind, $param) { // $param = [ // "record_bonus" => "首次同步系统积分", // "bonus" => $user->integral, // "add_bonus" => 0, // ]; $param['card_id'] = $bind->card_id; $param['code'] = $bind->code; $wxres = $this->card_membercard_updateuser($param); if($wxres['errcode'] == 0){ return [ 'code' => 0, 'msg' => '成功', ]; } return [ 'code' => $wxres['errcode'], 'msg' => $wxres['errmsg'], ]; } //批量修改会员信息 public function batchUpdateUserBonus($bind_ids, $param) { $okCount = 0; $count = 100; $count = 1; $chunk = array_chunk($bind_ids, $count); foreach($chunk as $ids){ $queue = queue_push(new WxBonusJob(['bind_ids' => $ids, 'param' => $param])); if($queue){ $okCount += count($ids); } } if($okCount > 0){ return [ 'code' => 0, 'msg' => '操作成功,入队列数量:' . $okCount, ]; } return [ 'code' => 1, 'msg' => '操作失败', ]; } }