From 1895a0fbd9f20493b768f61e5ef5a86e50e4831e Mon Sep 17 00:00:00 2001 From: wanghai Date: Fri, 5 Jun 2026 19:33:52 +0800 Subject: [PATCH] 4.6.3 --- .gitignore | 8 +++++ composer.json | 2 +- database/migrations/Version20260602100000.php | 26 ++++++++++++++++ routes/api/companys.php | 6 +++- .../Services/AftersalesService.php | 3 +- .../Http/Api/V1/Action/Companys.php | 28 +++++++---------- .../Entities/Activities.php | 31 +++++++++++++++++++ .../Http/Api/V1/Action/Activity.php | 6 ++-- .../Repositories/ActivitiesRepository.php | 4 +-- .../Services/EmployeesService.php | 26 ++++------------ .../Export/AftersalesRecordExportService.php | 2 +- .../Services/AppsCenter/AppsCenterService.php | 2 +- 12 files changed, 99 insertions(+), 45 deletions(-) create mode 100644 database/migrations/Version20260602100000.php diff --git a/.gitignore b/.gitignore index e37f97a..e3a3226 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,11 @@ doc/ .tasks/ storage/csv storage/excel + +.docker-dev/ + +# 本地 Docker 开发(种子数据、补丁脚本等,勿提交) +docker-dev/seed-*.sql +docker-dev/patch-*.sql +docker-dev/extract-weapp-staging.py +docker-compose.override.yml diff --git a/composer.json b/composer.json index 590aab0..cc96c29 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "laravel/lumen", - "version": "4.6.2", + "version": "4.6.3", "description": "The Laravel Lumen Framework.", "keywords": [ "framework", diff --git a/database/migrations/Version20260602100000.php b/database/migrations/Version20260602100000.php new file mode 100644 index 0000000..71be50d --- /dev/null +++ b/database/migrations/Version20260602100000.php @@ -0,0 +1,26 @@ +abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('ALTER TABLE employee_purchase_activities ADD list_pic VARCHAR(255) DEFAULT \'\' NOT NULL COMMENT \'活动列表海报\''); + } + + /** + * @param Schema $schema + */ + public function down(Schema $schema): void + { + } +} diff --git a/routes/api/companys.php b/routes/api/companys.php index 85a379b..a9dde7f 100644 --- a/routes/api/companys.php +++ b/routes/api/companys.php @@ -37,11 +37,15 @@ $api->version('v1', function($api) { $api->get('/company/applications', ['name' => '获取授权应用', 'as' => 'company.application.list', 'uses'=>'Companys@getApplications']); $api->get('/company/usercenter/authorizeurl', ['name' => '用户中心授权连接', 'as' => 'company.usercenter.authorizeurl.get', 'uses'=>'Companys@getUsercenterOuthorizeurl']); - $api->get('/company/usercenter/login', ['name' => '用户中心登录', 'as' => 'company.usercenter.login', 'uses'=>'Companys@loginUsercenter']); + $api->post('/company/usercenter/login', ['name' => '用户中心登录', 'as' => 'company.usercenter.login', 'uses'=>'Companys@loginUsercenter']); $api->get('/company/appcenter/goods', ['name' => '获取应用中心商品', 'as' => 'company.appcenter.goods.get', 'uses'=>'Companys@getAppcenterGoods']); $api->get('/company/appcenter/url', ['name' => '获取应用中心URL地址', 'as' => 'company.appcenter.url.get', 'uses'=>'Companys@getAppcenterUrl']); }); + $api->group(['namespace' => 'CompanysBundle\Http\Api\V1\Action'], function($api) { + $api->post('/company/appcenter/bind/{company_id}', ['name' => '绑定应用中心', 'as' => 'company.appcenter.bind', 'uses'=>'Companys@bindAppcenter']); + }); + $api->group(['namespace' => 'CompanysBundle\Http\Api\V1\Action', 'middleware' => ['api.auth', 'activated', 'shoplog'], 'providers' => 'jwt'], function($api) { $api->get('/company/resources', ['name' => '获取当前可用资源包列表', 'as' => 'company.resources', 'uses'=>'Companys@getResourceList']); $api->get('/companys/setting', ['name' => '获取商品配置信息', 'as' => 'companys.setting', 'uses'=>'Companys@getCompanySetting']); diff --git a/src/AftersalesBundle/Services/AftersalesService.php b/src/AftersalesBundle/Services/AftersalesService.php index 1f68b90..50b72a2 100644 --- a/src/AftersalesBundle/Services/AftersalesService.php +++ b/src/AftersalesBundle/Services/AftersalesService.php @@ -2042,7 +2042,8 @@ class AftersalesService ->from('aftersales_detail', 'ad') ->leftJoin('ad', 'aftersales', 'a', 'ad.aftersales_bn = a.aftersales_bn'); - $row = 'a.aftersales_bn,a.order_id,ad.item_bn,ad.item_name,ad.num,a.aftersales_type,a.aftersales_status,a.create_time,ad.refund_fee,a.progress,a.description,a.reason,a.refuse_reason,a.memo,ad.distributor_id,ad.company_id,a.memo,a.distributor_remark'; + // $row = 'a.aftersales_bn,a.order_id,ad.item_bn,ad.item_name,ad.num,a.aftersales_type,a.aftersales_status,a.create_time,ad.refund_fee,a.progress,a.description,a.reason,a.refuse_reason,a.memo,ad.distributor_id,ad.company_id,a.memo,a.distributor_remark'; + $row = 'a.aftersales_bn,a.order_id,ad.item_bn,ad.item_name,ad.num,a.aftersales_type,a.aftersales_status,a.create_time,ad.refund_fee,a.progress,a.description,a.reason,a.refuse_reason,ad.distributor_id,ad.company_id,a.distributor_remark'; $criteria = $this->getFilter($filter, $criteria); diff --git a/src/CompanysBundle/Http/Api/V1/Action/Companys.php b/src/CompanysBundle/Http/Api/V1/Action/Companys.php index 2c12ddd..0976e4f 100644 --- a/src/CompanysBundle/Http/Api/V1/Action/Companys.php +++ b/src/CompanysBundle/Http/Api/V1/Action/Companys.php @@ -681,14 +681,14 @@ class Companys extends BaseController return $this->response->array(['status' => true]); } - public function getUsercenterOuthorizeurl() + public function getUsercenterOuthorizeurl(Request $request) { - $callback = rtrim(config('common.shop_admin_url'), '/') . '/setting/ShangPai/usercenter'; + $callback = rtrim(config('common.shop_admin_url'), '/') . '/applications/shopex/appcenter'; $data = array( 'response_type' => 'code', 'client_id' => config('common.prism_key'), 'redirect_uri' => $callback, - 'view' => 'oauth_usercenter' + 'view' => 'ydsaas_iframe_login', ); $query = http_build_query($data); $shopexUrl = config('common.openapi_shopex_url'); @@ -705,7 +705,7 @@ class Companys extends BaseController return $this->response->array($data); } - public function getAppcenterUrl() + public function getAppcenterUrl(Request $request) { $companyId = app('auth')->user()->get('company_id'); $shopexUid = $this->companysService->getPassportUidByCompanyId($companyId); @@ -725,23 +725,19 @@ class Companys extends BaseController } $appsCenterService = new AppsCenterService(); - $callback = $appsCenterService->buildAppcenterUrl([ + $url = $appsCenterService->buildAppcenterUrl([ 'channel' => config('common.appcenter_channel'), 'shopexid' => $shopexUid, 'sys_node_id' => $nodeId, - 'callback' => rtrim(config('common.shop_admin_url'), '/'), + 'identity' => rtrim(config('common.certi_base_url'), '/') . '/api/company/appcenter/bind/'.$companyId, ], $token); - $data = array( - 'response_type' => 'code', - 'client_id' => config('common.prism_key'), - 'redirect_uri' => $callback, - 'view' => 'oauth_usercenter' - ); - $query = http_build_query($data); - $shopexUrl = config('common.openapi_shopex_url'); - $url = "{$shopexUrl}/oauth/authorize?{$query}"; - return $this->response->array(['url' => $url]); } + + public function bindAppcenter($company_id, Request $request) + { + // todo 绑定逻辑待确认 + return $this->response->array(['status' => true]); + } } diff --git a/src/EmployeePurchaseBundle/Entities/Activities.php b/src/EmployeePurchaseBundle/Entities/Activities.php index 55e236c..8577cb5 100644 --- a/src/EmployeePurchaseBundle/Entities/Activities.php +++ b/src/EmployeePurchaseBundle/Entities/Activities.php @@ -96,6 +96,13 @@ class Activities */ private $share_pic; + /** + * @var string + * + * @ORM\Column(name="list_pic", type="string", options={"comment":"活动列表海报", "default": ""}) + */ + private $list_pic = ''; + /** * @var json_array * @@ -399,6 +406,30 @@ class Activities return $this->share_pic; } + /** + * Set listPic. + * + * @param string $listPic + * + * @return Activities + */ + public function setListPic($listPic) + { + $this->list_pic = $listPic; + + return $this; + } + + /** + * Get listPic. + * + * @return string + */ + public function getListPic() + { + return $this->list_pic; + } + /** * Set enterpriseId. * diff --git a/src/EmployeePurchaseBundle/Http/Api/V1/Action/Activity.php b/src/EmployeePurchaseBundle/Http/Api/V1/Action/Activity.php index 01371f8..a8a7549 100644 --- a/src/EmployeePurchaseBundle/Http/Api/V1/Action/Activity.php +++ b/src/EmployeePurchaseBundle/Http/Api/V1/Action/Activity.php @@ -105,7 +105,7 @@ class Activity extends Controller $companyId = $authInfo['company_id']; $distributor_id = $authInfo['distributor_id']; $operator_id = $authInfo['operator_id']; - $params = $request->all('name', 'title', 'pages_template_id', 'pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'passphrase_enterprises'); + $params = $request->all('name', 'title', 'pages_template_id', 'pic', 'list_pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'passphrase_enterprises'); $params['company_id'] = $companyId; // 处理布尔值参数:支持字符串 'true'/'1' 和整数 1/0 $params['if_relative_join'] = isset($params['if_relative_join']) && ($params['if_relative_join'] === 'true' || $params['if_relative_join'] === '1' || $params['if_relative_join'] === 1 || $params['if_relative_join'] === true) ? 1 : 0; @@ -117,6 +117,7 @@ class Activity extends Controller 'title' => ['required', '请输入活动标题'], 'pages_template_id' => ['required', '请选择活动首页关联模版'], 'pic' => ['required', '请上传活动图片'], + 'list_pic' => ['required', '请上传活动列表海报'], 'share_pic' => ['required', '请上传活动分享图片'], 'enterprise_id' => ['required', '请选择参与企业'], 'display_time' => ['required', '请选择活动预热时间'], @@ -530,7 +531,7 @@ class Activity extends Controller $companyId = $authInfo['company_id']; $distributor_id = $authInfo['distributor_id']; $operator_id = $authInfo['operator_id']; - $params = $request->all('name', 'title', 'pages_template_id', 'pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'passphrase_enterprises'); + $params = $request->all('name', 'title', 'pages_template_id', 'pic', 'list_pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'passphrase_enterprises'); // 与 createActivity 一致:JSON 常传整数 1/0 或布尔,勿仅用 === '1'(否则 if_relative_join 恒为 0,亲友配置保存后不生效) $params['if_relative_join'] = isset($params['if_relative_join']) && ($params['if_relative_join'] === 'true' || $params['if_relative_join'] === '1' || $params['if_relative_join'] === 1 || $params['if_relative_join'] === true) ? 1 : 0; $params['if_share_limitfee'] = isset($params['if_share_limitfee']) && ($params['if_share_limitfee'] === 'true' || $params['if_share_limitfee'] === '1' || $params['if_share_limitfee'] === 1 || $params['if_share_limitfee'] === true) ? 1 : 0; @@ -554,6 +555,7 @@ class Activity extends Controller 'title' => ['required', '请输入活动标题'], 'pages_template_id' => ['required', '请选择活动首页关联模版'], 'pic' => ['required', '请上传活动图片'], + 'list_pic' => ['required', '请上传活动列表海报'], 'share_pic' => ['required', '请上传活动分享图片'], 'enterprise_id' => ['required', '请选择参与企业'], 'display_time' => ['required', '请选择活动预热时间'], diff --git a/src/EmployeePurchaseBundle/Repositories/ActivitiesRepository.php b/src/EmployeePurchaseBundle/Repositories/ActivitiesRepository.php index bc3587e..0ea5fe3 100644 --- a/src/EmployeePurchaseBundle/Repositories/ActivitiesRepository.php +++ b/src/EmployeePurchaseBundle/Repositories/ActivitiesRepository.php @@ -25,7 +25,7 @@ use MembersBundle\Services\MemberService; class ActivitiesRepository extends EntityRepository { public $table = 'employee_purchase_activities'; - public $cols = ['id', 'company_id', 'distributor_id', 'operator_id', 'name', 'title', 'pages_template_id', 'pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'status', 'if_share_store', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'created', 'updated']; + public $cols = ['id', 'company_id', 'distributor_id', 'operator_id', 'name', 'title', 'pages_template_id', 'pic', 'list_pic', 'share_pic', 'enterprise_id', 'display_time', 'employee_begin_time', 'employee_end_time', 'employee_limitfee', 'if_relative_join', 'invite_limit', 'relative_begin_time', 'relative_end_time', 'if_share_limitfee', 'relative_limitfee', 'minimum_amount', 'close_modify_hours_after_activity', 'status', 'if_share_store', 'price_display_config', 'is_discount_description_enabled', 'discount_description', 'is_passphrase_enabled', 'created', 'updated']; /** * 新增 @@ -438,7 +438,7 @@ class ActivitiesRepository extends EntityRepository $companyId = $filter['company_id']; $userId = $filter['user_id']; $now = time(); - $subQuery = "SELECT ac.id,ac.company_id,ac.pic,ac.name,ac.title,ac.pages_template_id,ac.display_time,ac.employee_begin_time,ac.employee_end_time,ac.employee_limitfee,ac.if_relative_join,ac.invite_limit,ac.relative_begin_time,ac.relative_end_time,ac.if_share_limitfee,ac.relative_limitfee,ac.minimum_amount,ac.status,ac.if_share_store,ac.created,ac.updated,ac.price_display_config,ac.is_discount_description_enabled,ac.discount_description,ac.is_passphrase_enabled,et.auth_type AS auth_type,ep.enterprise_id,ep.user_id,1 AS is_employee,0 AS is_relative,et.name AS rel_enterprise FROM employee_purchase_activities ac LEFT JOIN employee_purchase_activity_enterprises ae ON ac.id=ae.activity_id LEFT JOIN employee_purchase_employees ep ON ae.enterprise_id=ep.enterprise_id LEFT JOIN employee_purchase_enterprises et ON ae.enterprise_id=et.id WHERE ac.company_id={$companyId} AND ep.user_id={$userId} AND ac.status IN ('active', 'pending') AND et.disabled=0 AND ac.display_time<{$now} AND (ac.employee_end_time>{$now} OR ac.relative_end_time>{$now}) UNION SELECT ac.id,ac.company_id,ac.pic,ac.name,ac.title,ac.pages_template_id,ac.display_time,ac.employee_begin_time,ac.employee_end_time,ac.employee_limitfee,ac.if_relative_join,ac.invite_limit,ac.relative_begin_time,ac.relative_end_time,ac.if_share_limitfee,ac.relative_limitfee,ac.minimum_amount,ac.status,ac.if_share_store,ac.created,ac.updated,ac.price_display_config,ac.is_discount_description_enabled,ac.discount_description,ac.is_passphrase_enabled,et.auth_type AS auth_type,re.enterprise_id,re.user_id,0 AS is_employee,1 AS is_relative,et.name AS rel_enterprise FROM employee_purchase_activities ac LEFT JOIN employee_purchase_relatives re ON ac.id=re.activity_id LEFT JOIN employee_purchase_enterprises et ON re.enterprise_id=et.id WHERE ac.company_id={$companyId} AND re.user_id={$userId} AND ac.status IN ('active', 'pending') AND et.disabled=0 AND ac.display_time<{$now} AND ac.relative_end_time>{$now}"; + $subQuery = "SELECT ac.id,ac.company_id,ac.pic,ac.list_pic,ac.name,ac.title,ac.pages_template_id,ac.display_time,ac.employee_begin_time,ac.employee_end_time,ac.employee_limitfee,ac.if_relative_join,ac.invite_limit,ac.relative_begin_time,ac.relative_end_time,ac.if_share_limitfee,ac.relative_limitfee,ac.minimum_amount,ac.status,ac.if_share_store,ac.created,ac.updated,ac.price_display_config,ac.is_discount_description_enabled,ac.discount_description,ac.is_passphrase_enabled,et.auth_type AS auth_type,ep.enterprise_id,ep.user_id,1 AS is_employee,0 AS is_relative,et.name AS rel_enterprise FROM employee_purchase_activities ac LEFT JOIN employee_purchase_activity_enterprises ae ON ac.id=ae.activity_id LEFT JOIN employee_purchase_employees ep ON ae.enterprise_id=ep.enterprise_id LEFT JOIN employee_purchase_enterprises et ON ae.enterprise_id=et.id WHERE ac.company_id={$companyId} AND ep.user_id={$userId} AND ac.status IN ('active', 'pending') AND et.disabled=0 AND ac.display_time<{$now} AND (ac.employee_end_time>{$now} OR ac.relative_end_time>{$now}) UNION SELECT ac.id,ac.company_id,ac.pic,ac.list_pic,ac.name,ac.title,ac.pages_template_id,ac.display_time,ac.employee_begin_time,ac.employee_end_time,ac.employee_limitfee,ac.if_relative_join,ac.invite_limit,ac.relative_begin_time,ac.relative_end_time,ac.if_share_limitfee,ac.relative_limitfee,ac.minimum_amount,ac.status,ac.if_share_store,ac.created,ac.updated,ac.price_display_config,ac.is_discount_description_enabled,ac.discount_description,ac.is_passphrase_enabled,et.auth_type AS auth_type,re.enterprise_id,re.user_id,0 AS is_employee,1 AS is_relative,et.name AS rel_enterprise FROM employee_purchase_activities ac LEFT JOIN employee_purchase_relatives re ON ac.id=re.activity_id LEFT JOIN employee_purchase_enterprises et ON re.enterprise_id=et.id WHERE ac.company_id={$companyId} AND re.user_id={$userId} AND ac.status IN ('active', 'pending') AND et.disabled=0 AND ac.display_time<{$now} AND ac.relative_end_time>{$now}"; $conn = app('registry')->getConnection('default'); $qb = $conn->createQueryBuilder(); $qb = $qb->select('count(*) as _count')->from('('.$subQuery.')', 't'); diff --git a/src/EmployeePurchaseBundle/Services/EmployeesService.php b/src/EmployeePurchaseBundle/Services/EmployeesService.php index df1bde7..284c1b1 100644 --- a/src/EmployeePurchaseBundle/Services/EmployeesService.php +++ b/src/EmployeePurchaseBundle/Services/EmployeesService.php @@ -904,26 +904,12 @@ EOF; 'member_mobile' => $memberMobile !== '' ? $memberMobile : ($memberEmail !== '' ? $memberEmail : (string) $userId), 'distributor_id' => $enterpriseInfo['distributor_id'], ]; - switch ($enterpriseInfo['auth_type']) { - case 'email': - if ($memberEmail === '') { - throw new ResourceException('请先绑定邮箱'); - } - $data['name'] = $memberEmail; - $data['email'] = $memberEmail; - break; - case 'no_verify': - $mob = $memberMobile !== '' ? $memberMobile : (string) $userId; - $data['name'] = '用户-'.substr($mob, -4); - $data['mobile'] = $mob; - break; - default: - if ($memberMobile === '') { - throw new ResourceException('请先绑定手机号'); - } - $data['name'] = $memberMobile; - $data['mobile'] = $memberMobile; - break; + // 口令已验过即建档:身份由口令确认,不沿用企业 email/mobile 白名单对会员资料的约束 + $mob = $memberMobile !== '' ? $memberMobile : (string) $userId; + $data['name'] = '用户-'.substr($mob, -4); + $data['mobile'] = $mob; + if ($memberEmail !== '') { + $data['email'] = $memberEmail; } $this->entityRepository->create($data); diff --git a/src/EspierBundle/Services/Export/AftersalesRecordExportService.php b/src/EspierBundle/Services/Export/AftersalesRecordExportService.php index 55e258a..11a00c7 100644 --- a/src/EspierBundle/Services/Export/AftersalesRecordExportService.php +++ b/src/EspierBundle/Services/Export/AftersalesRecordExportService.php @@ -52,7 +52,7 @@ class AftersalesRecordExportService implements ExportFileInterface 'description' => '申请描述', 'reason' => '申请售后原因', 'refuse_reason' => '拒绝原因', - 'memo' => '售后备注', + // 'memo' => '售后备注', 'salesman_name' => '导购', 'order_holder' => '订单分类', 'supplier_name' => '来源供应商', diff --git a/src/ThirdPartyBundle/Services/AppsCenter/AppsCenterService.php b/src/ThirdPartyBundle/Services/AppsCenter/AppsCenterService.php index 23bfbd2..31b5cf2 100644 --- a/src/ThirdPartyBundle/Services/AppsCenter/AppsCenterService.php +++ b/src/ThirdPartyBundle/Services/AppsCenter/AppsCenterService.php @@ -50,7 +50,7 @@ class AppsCenterService $query = [ 'shopexid' => (string) $params['shopexid'], 'sys_node_id' => (string) $params['sys_node_id'], - 'callback' => (string) $params['callback'], + 'identity' => (string) $params['identity'], 'embed' => '1', 'nonce' => bin2hex(random_bytes(8)), 'timestamp' => (string) time(),