From 08e1c72cdd61b81aea21c7cb1b0998f5eb7efa4a Mon Sep 17 00:00:00 2001 From: chenping Date: Mon, 27 Apr 2026 10:19:05 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E6=8A=96?= =?UTF-8?q?=E5=BA=97=E4=BC=98=E5=85=88=E5=8F=91=E8=B4=A7=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=20=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E6=8A=96=E5=BA=97?= =?UTF-8?q?=E4=BC=98=E8=B4=A8=E5=BF=AB=E9=80=92=E5=AF=B9=E6=8E=A5=20?= =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E6=8A=96=E5=BA=97=E5=8A=A0?= =?UTF-8?q?=E4=BB=B7=E5=8F=91=E9=A1=BA=E4=B8=B0=E5=AF=B9=E6=8E=A5=20?= =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=E6=8A=96=E5=BA=97=E9=A1=BA?= =?UTF-8?q?=E4=B8=B0=E5=8C=85=E9=82=AE=E6=94=AF=E6=8C=81=E5=8D=8F=E5=95=86?= =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E7=89=A9=E6=B5=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/base/defined.php | 9 + app/base/lib/shell/buildin.php | 6 + app/crm/view/admin/gift/rule_edit_apply.html | 2 +- app/entermembercenter/lib/stat.php | 251 ++++++++++++++++++ .../matrix/aikucun/request/electron.php | 12 +- app/erpapi/lib/router/mapping.php | 5 +- .../lib/shop/matrix/luban/response/order.php | 26 +- .../shop/matrix/taobao/request/delivery.php | 11 +- .../shop/matrix/tmall/request/delivery.php | 11 +- .../response/plugins/order/orderextend.php | 4 + .../response/plugins/order/orderlabels.php | 48 ++-- .../lib/shop/response/process/shopbee.php | 111 ++++++++ app/erpapi/lib/shop/response/shopbee.php | 45 ++++ app/ome/dbschema/refund_apply.php | 2 +- app/ome/lib/auth/config.php | 11 + app/ome/lib/bill/label.php | 6 + app/ome/lib/order.php | 223 ++++++++++++---- .../admin/order/confirm/receiver_info.html | 2 +- app/omeanalysts/lib/finder/ome/goods.php | 9 +- app/setup/controller/default.php | 5 + .../admin/delivery/package/add_items.html | 2 +- .../admin/delivery/process_consign_index.html | 4 +- app/wmsmgr/desktop.xml | 2 +- config/deploy.xml | 2 +- 24 files changed, 703 insertions(+), 106 deletions(-) create mode 100644 app/entermembercenter/lib/stat.php create mode 100644 app/erpapi/lib/shop/response/process/shopbee.php create mode 100644 app/erpapi/lib/shop/response/shopbee.php diff --git a/app/base/defined.php b/app/base/defined.php index 4d5138ac..f6a1465e 100644 --- a/app/base/defined.php +++ b/app/base/defined.php @@ -99,6 +99,15 @@ $constants = array( // 奇门API接口 'QIMEN_URL' => 'https://qimen.api.taobao.com/top/router/qm', + + // 开源安装统计(上报 gwnextapi;未设置环境变量时用默认密钥;环境变量显式设为空字符串可关闭上报) + 'OPEN_SOURCE_STAT_SECRET_OMS' => getenv('OPEN_SOURCE_STAT_SECRET_OMS') !== false + ? getenv('OPEN_SOURCE_STAT_SECRET_OMS') + : 'K9mN2xPq5RwT8yLz4CvB7', + 'OPEN_SOURCE_STAT_PRODUCT' => getenv('OPEN_SOURCE_STAT_PRODUCT') ?: 'oms', + 'OPEN_SOURCE_STAT_REPORT_URL' => getenv('OPEN_SOURCE_STAT_REPORT_URL') ?: 'https://gwnextapi.shopex.cn/usercenter/open_source/stat/report', + 'OPEN_SOURCE_STAT_HTTP_TIMEOUT' => (int) (getenv('OPEN_SOURCE_STAT_HTTP_TIMEOUT') ?: 20), + 'OPEN_SOURCE_STAT_SENTINEL_NAME' => getenv('OPEN_SOURCE_STAT_SENTINEL_NAME') ?: '.opensource_install_stat_reported', ); $constants_ext = array(); diff --git a/app/base/lib/shell/buildin.php b/app/base/lib/shell/buildin.php index 07421f26..1e784403 100644 --- a/app/base/lib/shell/buildin.php +++ b/app/base/lib/shell/buildin.php @@ -243,6 +243,12 @@ EOF; $this->install_app_by_install_queue($applist, $options); $this->command_install_demodata('demodata'); + + try { + kernel::single('entermembercenter_stat')->reportInstall(); + } catch (Throwable $e) { + // 安装统计上报失败不阻断 install_product + } } var $command_install_demodata = "安装初始化数据"; diff --git a/app/crm/view/admin/gift/rule_edit_apply.html b/app/crm/view/admin/gift/rule_edit_apply.html index 3aa3aac5..cbe6c5c3 100644 --- a/app/crm/view/admin/gift/rule_edit_apply.html +++ b/app/crm/view/admin/gift/rule_edit_apply.html @@ -44,7 +44,7 @@  <{help}> - <{t}>触发节点:
1、审核订单,是默认方式当订单被审核时赠送赠品;
2、订单完成,是订单完成发货之后进行补发赠送赠品;
需要填写延迟几天,系统自动创建补发类型的订单,进行补发赠品给顾客;<{/t}> + <{t}>触发节点:
1、审核订单,是默认方式当订单被审核时赠送赠品;
2、订单完成,是接收平台订单完成发货状态之后进行补发赠送赠品;
需要填写延迟几天,系统自动创建补发类型的订单,进行补发赠品给顾客;<{/t}> <{/help}>
diff --git a/app/entermembercenter/lib/stat.php b/app/entermembercenter/lib/stat.php new file mode 100644 index 00000000..2f501f5a --- /dev/null +++ b/app/entermembercenter/lib/stat.php @@ -0,0 +1,251 @@ +sentinelPath(); + if ($sentinel && is_file($sentinel)) { + return; + } + + $params = $this->buildParams(); + $params['sign'] = $this->sign($params, $secret); + + $body = json_encode($params, JSON_UNESCAPED_SLASHES); + if ($body === false) { + return; + } + + $url = defined('OPEN_SOURCE_STAT_REPORT_URL') ? trim((string) OPEN_SOURCE_STAT_REPORT_URL) : ''; + if ($url === '') { + return; + } + $timeout = defined('OPEN_SOURCE_STAT_HTTP_TIMEOUT') ? (int) OPEN_SOURCE_STAT_HTTP_TIMEOUT : 20; + if ($timeout < 1) { + $timeout = 20; + } + + $ok = $this->postJson($url, $body, $timeout); + if ($ok && $sentinel) { + @file_put_contents($sentinel, (string) time(), LOCK_EX); + } + } + + /** + * @param array $params payload without sign + * @param string $secret + * @return string uppercase md5 + */ + public function sign(array $params, $secret) + { + unset($params['sign']); + ksort($params, SORT_STRING); + $s = ''; + foreach ($params as $k => $v) { + if ($v === null) { + continue; + } + if (is_bool($v)) { + $v = $v ? 1 : 0; + } + $s .= $k . (is_array($v) ? json_encode($v, JSON_UNESCAPED_SLASHES) : $v); + } + + return strtoupper(md5($secret . $s . $secret)); + } + + private function buildParams() + { + $product = defined('OPEN_SOURCE_STAT_PRODUCT') ? (string) OPEN_SOURCE_STAT_PRODUCT : 'oms'; + + return array( + 'product' => $product, + 'instance_id' => $this->detectInstanceId(), + 'version' => $this->detectVersion(), + 'timestamp' => time(), + 'is_docker' => $this->detectDocker() ? 1 : 0, + 'is_vm' => $this->detectVm() ? 1 : 0, + ); + } + + private function sentinelPath() + { + if (!defined('ROOT_DIR')) { + return null; + } + $dir = defined('DATA_DIR') ? DATA_DIR : (ROOT_DIR . '/data'); + if (!is_dir($dir)) { + @mkdir($dir, 0775, true); + } + + $name = defined('OPEN_SOURCE_STAT_SENTINEL_NAME') ? trim((string) OPEN_SOURCE_STAT_SENTINEL_NAME) : '.opensource_install_stat_reported'; + if ($name === '' || strpos($name, '/') !== false || strpos($name, "\0") !== false) { + $name = '.opensource_install_stat_reported'; + } + + return $dir . '/' . $name; + } + + private function detectVersion() + { + if (!class_exists('base_setup_config')) { + return '0.0.0'; + } + try { + $info = base_setup_config::deploy_info(); + if (!empty($info['ver'])) { + return (string) $info['ver']; + } + } catch (Exception $e) { + // ignore + } + + return '0.0.0'; + } + + private function detectInstanceId() + { + if (PHP_OS_FAMILY === 'Linux' || stripos(PHP_OS, 'Linux') !== false) { + $glob = @glob('/sys/class/net/*/address'); + if (is_array($glob)) { + foreach ($glob as $path) { + if (strpos($path, '/lo/') !== false) { + continue; + } + $raw = @trim((string) @file_get_contents($path)); + if ($raw !== '' && strcasecmp($raw, '00:00:00:00:00:00') !== 0) { + return strtolower(str_replace('-', ':', $raw)); + } + } + } + } + + $host = function_exists('php_uname') ? php_uname('n') : 'unknown'; + $root = defined('ROOT_DIR') ? ROOT_DIR : __DIR__; + + return md5($host . '|' . $root); + } + + private function detectDocker() + { + if (@is_file('/.dockerenv')) { + return true; + } + if (@is_readable('/proc/1/cgroup')) { + $c = @file_get_contents('/proc/1/cgroup'); + if ($c !== false && strpos($c, 'docker') !== false) { + return true; + } + } + + return false; + } + + private function detectVm() + { + $paths = array( + '/sys/class/dmi/id/product_name', + '/sys/class/dmi/id/sys_vendor', + ); + foreach ($paths as $p) { + if (!@is_readable($p)) { + continue; + } + $t = strtolower((string) @file_get_contents($p)); + if ($t === '') { + continue; + } + if (preg_match('/vmware|virtualbox|kvm|qemu|xen|parallels|microsoft corporation|bochs|innotek/', $t)) { + return true; + } + } + + return false; + } + + /** + * @param string $url + * @param string $body + * @param int $timeoutSec + * @return bool true if HTTP 2xx + */ + private function postJson($url, $body, $timeoutSec) + { + if (function_exists('curl_init')) { + $ch = curl_init($url); + if ($ch === false) { + return false; + } + curl_setopt_array($ch, array( + CURLOPT_POST => true, + CURLOPT_HTTPHEADER => array('Content-Type: application/json'), + CURLOPT_POSTFIELDS => $body, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => $timeoutSec, + CURLOPT_CONNECTTIMEOUT => min(10, $timeoutSec), + CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_SSL_VERIFYHOST => 2, + )); + $resp = curl_exec($ch); + $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + return $code >= 200 && $code < 300; + } + + $ctx = stream_context_create(array( + 'http' => array( + 'method' => 'POST', + 'header' => "Content-Type: application/json\r\nConnection: close\r\n", + 'content' => $body, + 'timeout' => $timeoutSec, + 'ignore_errors' => true, + ), + 'ssl' => array( + 'verify_peer' => true, + 'verify_peer_name' => true, + ), + )); + $resp = @file_get_contents($url, false, $ctx); + if ($resp === false) { + return false; + } + if (isset($http_response_header[0]) && preg_match('#\s(\d{3})\s#', $http_response_header[0], $m)) { + $code = (int) $m[1]; + + return $code >= 200 && $code < 300; + } + + return false; + } +} diff --git a/app/erpapi/lib/logistics/matrix/aikucun/request/electron.php b/app/erpapi/lib/logistics/matrix/aikucun/request/electron.php index 2b69df2b..d2dccd02 100644 --- a/app/erpapi/lib/logistics/matrix/aikucun/request/electron.php +++ b/app/erpapi/lib/logistics/matrix/aikucun/request/electron.php @@ -15,19 +15,15 @@ * limitations under the License. */ /** - * @author ykm 2015-12-15 - * @describe 淘宝请求电子面单类 + * @author ykm 2026-03 + * @describe 爱库存电子面单 */ class erpapi_logistics_matrix_aikucun_request_electron extends erpapi_logistics_request_electron { protected $directNum = 1; - /** - * bufferRequest - * @return mixed 返回值 - */ - - public function bufferRequest(){ + public function bufferRequest($sdf) + { return $this->directNum; } diff --git a/app/erpapi/lib/router/mapping.php b/app/erpapi/lib/router/mapping.php index b12b8054..a30430c1 100644 --- a/app/erpapi/lib/router/mapping.php +++ b/app/erpapi/lib/router/mapping.php @@ -78,10 +78,11 @@ class erpapi_router_mapping 'store.item.skus.add' => 'shop.goods.add', 'ome.reissue.query' => 'shop.reissue.query', 'ome.reissue.cancel' => 'shop.reissue.cancel', - 'qimen.taobao.erp.order.add' => 'qimen.order.add', - 'qimen.taobao.erp.order.update' => 'qimen.order.update', 'ome.shopbee.fxordermsg' => 'shop.bookingrefund.fxordermsg', // 供销供应商订单信息同步 'ome.reshipping.add' => 'shop.reshipping.add', + 'ome.order.tagchange' => 'shop.shopbee.tagchange', + 'qimen.taobao.erp.order.add' => 'qimen.order.add', + 'qimen.taobao.erp.order.update' => 'qimen.order.update', ); public static $_rsp_nodetype_mapping = array( diff --git a/app/erpapi/lib/shop/matrix/luban/response/order.php b/app/erpapi/lib/shop/matrix/luban/response/order.php index 49e294a4..4994dd6e 100644 --- a/app/erpapi/lib/shop/matrix/luban/response/order.php +++ b/app/erpapi/lib/shop/matrix/luban/response/order.php @@ -270,9 +270,27 @@ class erpapi_shop_matrix_luban_response_order extends erpapi_shop_response_order if($this->_ordersdf['extend_field']['sku_order_tag_ui']){ foreach ($this->_ordersdf['extend_field']['sku_order_tag_ui'] as $oid => $skuVal) { foreach ($skuVal as $sk => $sv) { - if ($sv['key'] == 'sf_free_shipping') { - $this->_ordersdf['sf_free_shipping'] = 'true'; - break; + $sv['extra'] = is_string($sv['extra']) ? json_decode($sv['extra'], true) : []; + switch ($sv['key']) { + case 'sf_free_shipping': + $this->_ordersdf['sf_free_shipping'] = 'true'; + break; + case 'PriorityDelivery': + if ($sv['extra'] && $sv['extra']['suggestDeliveryUnix']) { + $this->_ordersdf['latest_delivery_time'] = $sv['extra']['suggestDeliveryUnix']; + } + break; + case 'high_quality_express': + if ($sv['extra'] && $sv['extra']['express_company_code']) { + $this->_ordersdf['biz_delivery_code'] = json_encode(is_string($sv['extra']['express_company_code']) ? [$sv['extra']['express_company_code']] : $sv['extra']['express_company_code']); + } + break; + case 'paid_shunfeng_express': + case 'paid_shunfeng_express_tk': + + $this->_ordersdf['shipping_name'] = 'SF'; + $this->_ordersdf['assign_express_code'] = 'SF'; + break; } } } @@ -280,7 +298,7 @@ class erpapi_shop_matrix_luban_response_order extends erpapi_shop_response_order if ($this->_ordersdf['sf_free_shipping'] == 'true') { $dly = app::get('ome')->model('dly_corp')->db_dump([ - 'type|in' => ['shunfeng', 'shunfengkuaiyun'], + 'type|in' => ['shunfeng', 'shunfengkuaiyun','SF'], 'disabled' => 'false', ]); if ($dly){ diff --git a/app/erpapi/lib/shop/matrix/taobao/request/delivery.php b/app/erpapi/lib/shop/matrix/taobao/request/delivery.php index 6ecf32f3..dab04b78 100644 --- a/app/erpapi/lib/shop/matrix/taobao/request/delivery.php +++ b/app/erpapi/lib/shop/matrix/taobao/request/delivery.php @@ -148,8 +148,15 @@ class erpapi_shop_matrix_taobao_request_delivery extends erpapi_shop_request_del } } + // 判断订单是否编辑过商品 + //@todo:只有平台子订单 oid 被删除且不存在对应未删除商品时,才算编辑过商品; + $isModifyGoods = false; + if ($sdf['orderinfo']['is_modify'] == 'true') { + $isModifyGoods = kernel::single('ome_order')->isOrderGoodsModified($sdf['orderinfo']['order_id']); + } + //[部分拆单 OR 多包裹]订单没有编辑过商品,按拆单子单回写 - if(($sdf['is_split'] == 1 || $is_packages) && $sdf['orderinfo']['is_modify'] != 'true') { + if(($sdf['is_split'] == 1 || $is_packages) && !$isModifyGoods) { //按多包裹 if($packageInfo){ $param['packages'] = json_encode($packageInfo['packages']); @@ -171,7 +178,7 @@ class erpapi_shop_matrix_taobao_request_delivery extends erpapi_shop_request_del $param['consign_type'] = 0; //订单编辑过商品 - if($sdf['orderinfo']['is_modify'] == 'true'){ + if($isModifyGoods){ //注销oid_list子订单列表 unset($param['oid_list']); diff --git a/app/erpapi/lib/shop/matrix/tmall/request/delivery.php b/app/erpapi/lib/shop/matrix/tmall/request/delivery.php index bca9946a..373ef21a 100644 --- a/app/erpapi/lib/shop/matrix/tmall/request/delivery.php +++ b/app/erpapi/lib/shop/matrix/tmall/request/delivery.php @@ -153,8 +153,15 @@ class erpapi_shop_matrix_tmall_request_delivery extends erpapi_shop_request_deli } } + // 判断订单是否编辑过商品 + //@todo:只有平台子订单 oid 被删除且不存在对应未删除商品时,才算编辑过商品; + $isModifyGoods = false; + if ($sdf['orderinfo']['is_modify'] == 'true') { + $isModifyGoods = kernel::single('ome_order')->isOrderGoodsModified($sdf['orderinfo']['order_id']); + } + //[部分拆单 OR 多包裹]订单没有编辑过商品,按拆单子单回写 - if(($sdf['is_split'] == 1 || $is_packages) && $sdf['orderinfo']['is_modify'] != 'true') { + if(($sdf['is_split'] == 1 || $is_packages) && !$isModifyGoods) { //按多包裹 if($packageInfo){ $param['packages'] = json_encode($packageInfo['packages']); @@ -176,7 +183,7 @@ class erpapi_shop_matrix_tmall_request_delivery extends erpapi_shop_request_deli $param['consign_type'] = 0; //订单编辑过商品 - if($sdf['orderinfo']['is_modify'] == 'true'){ + if($isModifyGoods){ //注销oid_list子订单列表 unset($param['oid_list']); diff --git a/app/erpapi/lib/shop/response/plugins/order/orderextend.php b/app/erpapi/lib/shop/response/plugins/order/orderextend.php index 2160812f..1f878be2 100644 --- a/app/erpapi/lib/shop/response/plugins/order/orderextend.php +++ b/app/erpapi/lib/shop/response/plugins/order/orderextend.php @@ -117,6 +117,10 @@ class erpapi_shop_response_plugins_order_orderextend extends erpapi_shop_respons } } } + + if ($platform->_ordersdf['assign_express_code'] && is_string($platform->_ordersdf['assign_express_code'])) { + $extend['assign_express_code'] = $platform->_ordersdf['assign_express_code']; + } // 抖店顺丰包邮,指定快递编码 if ($platform->_ordersdf['sf_free_shipping']) { diff --git a/app/erpapi/lib/shop/response/plugins/order/orderlabels.php b/app/erpapi/lib/shop/response/plugins/order/orderlabels.php index 6c285a62..5d39761c 100644 --- a/app/erpapi/lib/shop/response/plugins/order/orderlabels.php +++ b/app/erpapi/lib/shop/response/plugins/order/orderlabels.php @@ -32,21 +32,39 @@ class erpapi_shop_response_plugins_order_orderlabels extends erpapi_shop_respons foreach ($platform->_ordersdf['extend_field']['sku_order_tag_ui'] as $oid => $skuVal) { // 商品单标签,只要有一个商品是顺丰包邮,则整单打顺丰包邮的标签 foreach ($skuVal as $sk => $sv) { - if ($sv['key'] == 'sf_free_shipping') { - $labels[] = [ - 'label_code' => 'sf_free_shipping', - // 'label_name' => '顺丰包邮', - ]; - break; - } - } - // 全款预售 - foreach ($skuVal as $sk => $sv) { - if ($sv['key'] == 'pre_sale_label') { - $labels[] = [ - 'label_code' => 'SOMS_FULLPAY_PRESALE', - ]; - break; + + switch ($sv['key']) { + case 'sf_free_shipping': + $labels[] = [ + 'label_code' => 'sf_free_shipping', + ]; + break; + case 'pre_sale_label': + $labels[] = [ + 'label_code' => 'SOMS_FULLPAY_PRESALE', + ]; + break; + case 'PriorityDelivery': + $labels[] = [ + 'label_code' => 'priority_delivery', + ]; + break; + case 'high_quality_express': + $labels[] = [ + 'label_code' => 'SOMS_HIGH_EXPRESS', + ]; + case 'paid_shunfeng_express': + $labels[] = [ + 'label_code' => 'SOMS_PAID_EXPRESS', + 'label_value' => 0x0001, + ]; + break; + case 'paid_shunfeng_express_tk': + $labels[] = [ + 'label_code' => 'SOMS_PAID_EXPRESS', + 'label_value' => 0x0002, + ]; + break; } } } diff --git a/app/erpapi/lib/shop/response/process/shopbee.php b/app/erpapi/lib/shop/response/process/shopbee.php new file mode 100644 index 00000000..0007315b --- /dev/null +++ b/app/erpapi/lib/shop/response/process/shopbee.php @@ -0,0 +1,111 @@ + 'fail', 'msg' => '参数不完整'); + } + + + switch ($params['tag_key']) { + case 'sku_logistics_extra_info': + return $this->_handleShowSFFreeShippingTag($params['order_id'], $params['tag_info']); + case 'shop_priority_delivery': + return $this->_handleShopPriorityDelivery($params['order_id'], $params['tag_info']); + } + + + + return array('rsp' => 'succ', 'msg' => '顺丰包邮标与白名单已更新'); + } + + /** + * 处理顺丰包邮标签与白名单 + * @param int $orderId + * @return array + */ + private function _handleShowSFFreeShippingTag($orderId, $tagInfo) + { + $ModifyInfo = $tagInfo['ModifyInfo'] ?? ''; + if (is_string($ModifyInfo)) { + $ModifyInfo = json_decode($ModifyInfo, true); + } + + $HighQualityExpressInfo = $tagInfo['HighQualityExpressInfo'] ?? ''; + if (is_string($HighQualityExpressInfo)) { + $HighQualityExpressInfo = json_decode($HighQualityExpressInfo, true); + } + + // 打顺丰包邮标签 + if ($tagInfo['ShowHighQualityExpressTag'] == 1){ + $err = null; + kernel::single('ome_bill_label')->markBillLabel($orderId, '', 'sf_free_shipping', 'order', $err, 0, $tagInfo); + + // 更新order_extend表white_delivery_cps + $orderExtendMdl = app::get('ome')->model('order_extend'); + + $upData = [ + 'assign_express_code' => 'SF', + ]; + + if (is_array($ModifyInfo) && $ModifyInfo['support_all_delivery'] == 1){ + $upData['assign_express_code'] = ''; + } + + $orderExtendMdl->update( + $upData, + array('order_id' => $orderId) + ); + } + + // 打优质快递标签 + if ($HighQualityExpressInfo && $HighQualityExpressInfo['enable'] == 1){ + $err = null; + kernel::single('ome_bill_label')->markBillLabel($orderId, '', 'SOMS_HIGH_EXPRESS', 'order', $err, 0, $tagInfo); + + if ($HighQualityExpressInfo['express_company_code']){ + $biz_delivery_code = is_string($HighQualityExpressInfo['express_company_code']) ? [$HighQualityExpressInfo['express_company_code']] : $HighQualityExpressInfo['express_company_code']; + $orderExtendMdl->update( + [ + 'biz_delivery_code' => json_encode($biz_delivery_code), + ], + ['order_id' => $orderId] + ); + } + } + } + + /** + * 处理优先发货标签 + * @param int $orderId + * @return array + */ + private function _handleShopPriorityDelivery($orderId, $tagInfo) + { + if ($tagInfo['isShow'] != 1) { + return array('rsp' => 'succ', 'msg' => '无需处理'); + } + + // 打顺丰包邮标签 + $err = null; + kernel::single('ome_bill_label')->markBillLabel($orderId, '', 'priority_delivery', 'order', $err, 0, $tagInfo); + + + if ($tagInfo['suggestDeliveryUnix']) { + // 更新order_extend表latest_delivery_time + $orderExtendMdl = app::get('ome')->model('order_extend'); + + $upData = [ + 'latest_delivery_time' => $tagInfo['suggestDeliveryUnix'], + ]; + + $orderExtendMdl->update($upData, ['order_id' => $orderId]); + } + + return array('rsp' => 'succ', 'msg' => '优先发货标已打'); + } +} diff --git a/app/erpapi/lib/shop/response/shopbee.php b/app/erpapi/lib/shop/response/shopbee.php new file mode 100644 index 00000000..73053397 --- /dev/null +++ b/app/erpapi/lib/shop/response/shopbee.php @@ -0,0 +1,45 @@ +__apilog['title'] = '订单标签变更'; + $this->__apilog['original_bn'] = $params['tid']; + + // tag_key加个白名单,目前只支持sku_logistics_extra_info + $white_list = ['sku_logistics_extra_info', 'shop_priority_delivery']; + if (!in_array($params['tag_key'], $white_list)) { + $this->__apilog['result']['msg'] = '不支持的标签类型'; + return false; + } + + $shop_id = $this->__channelObj->channel['shop_id']; + $order_bn = $params['tid']; + if (!$order_bn) { + $this->__apilog['result']['msg'] = '订单号(tid)为空'; + return false; + } + $order = $this->getOrder('order_id,order_bn', $shop_id, $order_bn); + if (!$order) { + $this->__apilog['result']['msg'] = '订单不存在'; + return false; + } + + $tagInfoRaw = $params['tag_info'] ? json_decode($params['tag_info'], true) : []; + + $sdf = [ + 'order_id' => $order['order_id'], + 'order_bn' => $order['order_bn'], + 'shop_id' => $this->__channelObj->channel['shop_id'], + 'tag_key' => $params['tag_key'], + 'tag_info' => $tagInfoRaw ?? [], + ]; + + return $sdf; + } +} diff --git a/app/ome/dbschema/refund_apply.php b/app/ome/dbschema/refund_apply.php index 592e5298..f409f925 100644 --- a/app/ome/dbschema/refund_apply.php +++ b/app/ome/dbschema/refund_apply.php @@ -415,7 +415,7 @@ $db['refund_apply'] = array( 'idx_abnormal_status' => array('columns' => array('abnormal_status')), 'idx_oid' => array('columns' => array('oid')), - 'idx_bn' => array('columns' => array('bn')), + 'idx_bn' => array('columns' => array('bn(255)')), 'idx_bool_type' => array('columns'=>array('bool_type')), 'idx_tag_type' => array('columns'=>array('tag_type')), 'ind_source_status' => array( diff --git a/app/ome/lib/auth/config.php b/app/ome/lib/auth/config.php index b1c0c4d3..a75e550b 100644 --- a/app/ome/lib/auth/config.php +++ b/app/ome/lib/auth/config.php @@ -128,6 +128,17 @@ class ome_auth_config 'node_id' => '节点', ), ), + 'b2b' => + array( + 'label' => 'B2B', + 'desc' => 'B2B平台对接', + 'params' => + array( + 'b2b_url' => 'API地址', + 'b2b_response_secret' => 'RESPONSE SECRET', + 'node_id' => '节点', + ), + ), ); foreach (ome_shop_type::get_shop_type() as $key => $value) { diff --git a/app/ome/lib/bill/label.php b/app/ome/lib/bill/label.php index a565eb9f..4f1760ff 100644 --- a/app/ome/lib/bill/label.php +++ b/app/ome/lib/bill/label.php @@ -53,6 +53,8 @@ class ome_bill_label 'SOMS_IMEI' => ['label_name' => '发货必传IMEI码', 'label_color' => 'Gold', 'label_to_delivery' => true], 'SOMS_SERIALNUMBER' => ['label_name' => '发货必传SN码', 'label_color' => 'Gold', 'label_to_delivery' => true], 'SOMS_EXPRESS_MUST' => ['label_name' => '自选快递', 'label_color' => 'CornflowerBlue'], + 'SOMS_HIGH_EXPRESS' => ['label_name' => '优质快递', 'label_color' => 'GoldenRod'], + 'SOMS_PAID_EXPRESS' => ['label_name' => '加价快递', 'label_color' => 'LightCoral'], 'SOMS_HOST' => ['label_name' => '达人', 'label_color' => 'Darkorange'], 'SOMS_LOTTERY' => ['label_name' => '抽奖', 'label_color' => 'GoldenRod'], 'SOMS_GNJY' => ['label_name' => '国内集运', 'label_color' => 'OliveDrab'], @@ -183,6 +185,10 @@ class ome_bill_label 'SOMS_PICKUP' => [ 0x0001 => ['label_name' => '官方'], ], + 'SOMS_PAID_EXPRESS' => [ + 0x0001 => ['label_name' => '加价选顺丰标准'], + 0x0002 => ['label_name' => '加价选顺丰特快'], + ], ]; // // 单据类型对应的model,可用于检测bill_id是否有效 diff --git a/app/ome/lib/order.php b/app/ome/lib/order.php index 151fb18d..1856d22f 100644 --- a/app/ome/lib/order.php +++ b/app/ome/lib/order.php @@ -2395,7 +2395,6 @@ class ome_order { //data $data = $params['sdfdata']; $order_id = $data['order_id']; - $order_bn = $data['order_bn']; if(empty($order_id)){ $error_msg = '没有订单信息'; return false; @@ -2457,7 +2456,7 @@ class ome_order { } //订单对应发货单(合并发货单对应多个订单号) - $sql = "SELECT b.order_id FROM sdb_ome_delivery AS a LEFT JOIN sdb_ome_delivery_order AS b ON (a.delivery_id=b.delivery_id) + $sql = "SELECT b.order_id FROM sdb_ome_delivery AS a LEFT JOIN sdb_ome_delivery_order AS b ON (a.delivery_id=b.delivery_id) WHERE a.delivery_id=".$delivery_id." AND (a.parent_id=0 OR a.is_bind='true') AND a.disabled='false' AND a.status='ready'"; $tempList = $deliveryObj->db->select($sql); if(empty($tempList)){ @@ -2471,35 +2470,64 @@ class ome_order { $order_ids[] = $val['order_id']; } - //[兼容]虚拟物流单号 - $corpInfo = array(); + // 物流公司ID + $logi_id = ($deliveryInfo['logi_id'] ? $deliveryInfo['logi_id'] : 1); + + // 获取物流公司 if(empty($deliveryInfo['logi_no'])){ - //默认读取仓库关联的第一个物流公司 - $sql = "SELECT a.*, b.name FROM sdb_ome_branch_corp AS a LEFT JOIN sdb_ome_dly_corp AS b ON a.corp_id=b.corp_id WHERE a.branch_id=". $branch_id; + // 优先获取虚拟物流公司 + $sql = "SELECT * FROM sdb_ome_dly_corp WHERE `type`='virtual_delivery'"; $corpInfo = $deliveryObj->db->selectrow($sql); - //物流公司ID - $deliveryInfo['logi_id'] = $corpInfo['corp_id']; + // 获取发货单上指定的物流公司 + if(empty($corpInfo) && $deliveryInfo['logi_id']){ + $sql = "SELECT * FROM sdb_ome_dly_corp WHERE corp_id=". $deliveryInfo['logi_id']; + $corpInfo = $deliveryObj->db->selectrow($sql); + } - //物流单号 - $logi_no = 'V'.uniqid(); - $deliveryInfo['logi_no'] = $logi_no; + // 默认读取仓库关联的第一个物流公司 + if(empty($corpInfo)){ + $sql = "SELECT a.*, b.name FROM sdb_ome_branch_corp AS a LEFT JOIN sdb_ome_dly_corp AS b ON a.corp_id=b.corp_id WHERE a.branch_id=". $branch_id; + $corpInfo = $deliveryObj->db->selectrow($sql); + } + + // 获取第一个物流公司 + if(empty($corpInfo)){ + $sql = "SELECT * FROM `sdb_ome_dly_corp` WHERE `type` NOT IN('o2o_pickup', 'o2o_ship')"; + $corpInfo = $deliveryObj->db->selectrow($sql); + } + + //物流公司ID + $logi_id = ($corpInfo['corp_id'] ? $corpInfo['corp_id'] : 1); } + // 获取物流公司信息 + $sql = "SELECT * FROM sdb_ome_dly_corp WHERE corp_id=". $logi_id; + $corpInfo = $deliveryObj->db->selectrow($sql); + + // 生成唯一性的物流单号 + $logi_no = 'V'.uniqid(); + + // 物流公司名称 + $logi_name = ($corpInfo['name'] ? $corpInfo['name'] : '默认物流公司'); + + //默认使用_商品重量 + $weight = ($deliveryInfo['net_weight'] ? $deliveryInfo['net_weight'] : 0); + $weight = floatval($weight); + //开启事务 $deliveryObj->db->beginTransaction(); - //默认使用_商品重量 - $weight = ($deliveryInfo['net_weight'] ? $deliveryInfo['net_weight'] : 0); + // 更新ome发货单单物流信息和打印状态 + $sql = "UPDATE sdb_ome_delivery SET stock_status='true',deliv_status='true',expre_status='true',verify='true',weight='". $weight ."'"; + $sql .= ",print_status=1,logi_id=". $logi_id .",logi_name='". $logi_name ."'"; - //更新ome发货单单物流信息和打印状态 - if($corpInfo){ - $sql = "UPDATE sdb_ome_delivery SET stock_status='true',deliv_status='true',expre_status='true',verify='true',weight='". $weight ."'"; - $sql .= ",print_status=1,logi_id=". $corpInfo['corp_id'] .",logi_name='". $corpInfo['name'] ."',logi_no='". $logi_no ."' WHERE delivery_id=". $delivery_id; - }else{ - $sql = "UPDATE sdb_ome_delivery SET stock_status='true',deliv_status='true',expre_status='true',verify='true',weight='". $weight ."',print_status=1 - WHERE delivery_id=". $delivery_id; + // logi_no + if(empty($deliveryInfo['logi_no'])){ + $sql .= ", logi_no='". $logi_no ."'"; } + + $sql .= " WHERE delivery_id=". $delivery_id; $deliveryObj->db->exec($sql); //更新订单打印状态 @@ -2509,62 +2537,67 @@ class ome_order { $update_order['order_id'] = $order_id; $update_order['print_finish'] = 'true'; $update_order['print_status'] = 7; - $update_order['logi_id'] = $deliveryInfo['logi_id']; - $update_order['logi_no'] = $deliveryInfo['logi_no']; + $update_order['logi_id'] = $logi_id; + $update_order['logi_no'] = $logi_no; + $orderObj->save($update_order); } //是否自有仓储 - $is_selfWms = false; $wms_id = $branchLib->getWmsIdById($branch_id); $is_selfWms = $channelLib->isSelfWms($wms_id); - //自动发货流程 + // 自有仓储发货单信息 + $wmsDlyInfo = []; if($is_selfWms){ - //变更wms发货单打印状态物流信息 $wmsDlyInfo = $wmsDlyObj->dump(array('outer_delivery_bn'=>$deliveryInfo['delivery_bn']), 'delivery_id'); - if($wmsDlyInfo){ - $dlyData = array(); - $dlyData['logi_id'] = $deliveryInfo['logi_id']; - $dlyData['logi_name'] = $deliveryInfo['logi_name']; - $dlyData['weight'] = $weight; - $dlyData['print_status'] = 7;//已打印 - - $dly_result = $wmsDlyObj->update($dlyData, array('delivery_id'=>$wmsDlyInfo['delivery_id'])); - - $sql = "UPDATE sdb_wms_delivery_bill SET logi_no='". $logi_no ."' WHERE delivery_id=". $wmsDlyInfo['delivery_id']; - $deliveryObj->db->exec($sql); - } + } + + // 自动发货流程 + if($wmsDlyInfo){ + // 更新wms发货单打印状态物流信息 + $dlyData = array(); + $dlyData['logi_id'] = $logi_id; + $dlyData['logi_name'] = $logi_name; + $dlyData['weight'] = $weight; + $dlyData['print_status'] = 7;//已打印 + + // update wms_delivery + $wmsDlyObj->update($dlyData, array('delivery_id'=>$wmsDlyInfo['delivery_id'])); + + // update wms_delivery_bill + $sql = "UPDATE sdb_wms_delivery_bill SET logi_no='". $logi_no ."' WHERE delivery_id=". $wmsDlyInfo['delivery_id']; + $deliveryObj->db->exec($sql); //触发wms自动发货流程 foreach ($order_ids as $ordKey => $order_id) { - $result = $this->wmsConsignDelivery($order_id, $logi_no, $weight); + $result = $this->wmsConsignDelivery($order_id, $logi_no, $weight, $error_msg); if(!$result){ //回滚事务 $deliveryObj->db->rollBack(); - $error_msg = 'WMS发货单发货失败'; + $error_msg = 'WMS发货单发货失败:'. $error_msg; return false; } } - }else{ - //OMS发货 + // 模拟response自动响应发货 $data = array( - 'delivery_bn' => $deliveryInfo['delivery_bn'], - 'delivery_time' => time(), - 'weight' => $weight, - 'delivery_cost_actual' => 0, - 'status' => 'delivery', + 'delivery_bn' => $deliveryInfo['delivery_bn'], + 'delivery_time' => time(), + 'weight' => $weight, + 'delivery_cost_actual' => 0, + 'status' => 'delivery', + 'logistics' => $logi_id, + 'logi_no' => $logi_no, ); - $result = kernel::single('erpapi_router_response')->set_channel_id($wms_id)->set_api_name('wms.delivery.status_update')->dispatch($data); if($result['rsp'] == 'fail'){ //回滚事务 $orderObj->db->rollBack(); - $error_msg = '发货单发货失败'; + $error_msg = '发货单自动发货失败:'. ($result['msg'] ? $result['msg'] : $result['error_msg']); return false; } } @@ -2586,9 +2619,10 @@ class ome_order { * @param number $weight * @return boolean */ - function wmsConsignDelivery($order_id, $logi_no, $weight) + function wmsConsignDelivery($order_id, $logi_no, $weight, &$error_msg=null) { if(empty($order_id) || empty($logi_no)){ + $error_msg = '订单ID或者物流单号不能为空'; return false; } @@ -2604,16 +2638,19 @@ class ome_order { $delivery_id = $deliveryBillLib->getDeliveryIdByPrimaryLogi($logi_no); if(empty($delivery_id)){ $opObj->write_log('order_edit@ome', $order_id, '自动发货失败:未找到对应发货单号'); + + $error_msg = '自动发货失败:未找到对应发货单号'; return false; } $dly = $dlyObj->dump(array('delivery_id' => $delivery_id),'*',array('delivery_items'=>array('*'))); if(empty($dly)){ $opObj->write_log('order_edit@ome', $order_id, '自动发货失败:未找到发货单信息'); + + $error_msg = '自动发货失败:未找到发货单信息'; return false; } - $logi_number = $dly['logi_number']; $delivery_logi_number = $dly['delivery_logi_number']+1; //获取物流费用 @@ -2624,20 +2661,20 @@ class ome_order { //更新bill发货单 $data = array( - 'status' => '1', - 'weight' => $weight, - 'delivery_cost_actual' => $delivery_cost_actual, - 'delivery_time' => time(), - 'type' => 1, + 'status' => '1', + 'weight' => $weight, + 'delivery_cost_actual' => $delivery_cost_actual, + 'delivery_time' => time(), + 'type' => 1, ); $dlyBillObj->update($data, array('logi_no'=>$logi_no)); //更新wms发货单 $dly['delivery_cost_actual'] += $delivery_cost_actual; $data = array( - 'delivery_logi_number' => $delivery_logi_number, - 'weight' => $dly['weight'], - 'delivery_cost_actual' => $dly['delivery_cost_actual'], + 'delivery_logi_number' => $delivery_logi_number, + 'weight' => $dly['weight'], + 'delivery_cost_actual' => $dly['delivery_cost_actual'], ); $dlyObj->update($data, array('delivery_id'=>$dly['delivery_id'])); @@ -2647,6 +2684,7 @@ class ome_order { return true; }else { $opObj->write_log('order_edit@ome', $order_id, '发货失败,发货单:'.$dly['delivery_bn']); + $error_msg = '发货失败,发货单:'.$dly['delivery_bn']; return false; } } @@ -3242,4 +3280,73 @@ class ome_order { return $fixedPriceData; } + + /** + * 判断订单是否编辑过商品 + * 规则:只有平台子订单 oid 被删除且不存在对应未删除商品时,才算编辑过商品; + * + * @param int $order_id 订单ID + * @return bool + */ + public function isOrderGoodsModified($order_id) + { + $orderMdl = app::get('ome')->model('orders'); + + // order + $orderInfo = $orderMdl->dump(array('order_id'=>$order_id), 'order_bn,process_status,status,pay_status,ship_status,is_modify'); + if(empty($orderInfo)){ + return false; + } + + if($orderInfo['is_modify'] != 'true'){ + return false; + } + + // order_objects + $objectList = app::get('ome')->model('order_objects')->getList('obj_id,oid,`delete`', array('order_id'=>$order_id)); + if (empty($objectList)) { + return false; + } + + $oidStatus = array(); + foreach ($objectList as $object) + { + $oid = $object['oid']; + if (empty($oid)) { + continue; + } + + if (!isset($oidStatus[$oid])) { + $oidStatus[$oid] = array( + 'has_deleted' => false, + 'has_active' => false, + ); + } + + if ($object['delete'] == 'true') { + $oidStatus[$oid]['has_deleted'] = true; + } else { + $oidStatus[$oid]['has_active'] = true; + } + } + + // 订单明细没有子订单oid + if(empty($oidStatus)){ + if($orderInfo['is_modify'] == 'true'){ + return true; + }else{ + return false; + } + } + + // check + foreach ($oidStatus as $status) + { + if ($status['has_deleted'] && !$status['has_active']) { + return true; + } + } + + return false; + } } diff --git a/app/ome/view/admin/order/confirm/receiver_info.html b/app/ome/view/admin/order/confirm/receiver_info.html index 4773734c..0b240d2c 100644 --- a/app/ome/view/admin/order/confirm/receiver_info.html +++ b/app/ome/view/admin/order/confirm/receiver_info.html @@ -14,7 +14,7 @@ limitations under the License. --> -

<{if $order.is_encrypt}><{/if}>收货人信息 <{if !$order.is_jy}>使用其他收货人信息<{/if}> +

<{if $order.is_encrypt && (!defined('SENSITIVE_DATA_SHOW') || constant('SENSITIVE_DATA_SHOW'))}><{/if}>收货人信息 <{if !$order.is_jy}>使用其他收货人信息<{/if}>

<{include file="admin/order/confirm/member_confirm.html"}> diff --git a/app/omeanalysts/lib/finder/ome/goods.php b/app/omeanalysts/lib/finder/ome/goods.php index 7cc37146..c2f350fe 100644 --- a/app/omeanalysts/lib/finder/ome/goods.php +++ b/app/omeanalysts/lib/finder/ome/goods.php @@ -14,16 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + class omeanalysts_finder_ome_goods{ var $detail_basic = '基础物料详情'; - /** - * detail_basic - * @param mixed $goods_id ID - * @return mixed 返回值 - */ - public function detail_basic($goods_id) { + public function detail_basic($goods_id) { $filter = array( 'goods_id'=>$goods_id, 'time_from' => $_GET['time_from'], diff --git a/app/setup/controller/default.php b/app/setup/controller/default.php index d1ff6326..c89a849a 100644 --- a/app/setup/controller/default.php +++ b/app/setup/controller/default.php @@ -131,6 +131,11 @@ class setup_ctl_default extends setup_controller{ * @return mixed 返回值 */ public function success(){ + try { + kernel::single('entermembercenter_stat')->reportInstall(); + } catch (Throwable $e) { + // 上报失败不阻断成功页 + } $this->pagedata['statics_url'] = $this->app->res_url; $this->pagedata['conf'] = base_setup_config::deploy_info(); $output = $this->fetch('installer-success.html'); diff --git a/app/wms/view/admin/delivery/package/add_items.html b/app/wms/view/admin/delivery/package/add_items.html index 4479916d..4c86738c 100644 --- a/app/wms/view/admin/delivery/package/add_items.html +++ b/app/wms/view/admin/delivery/package/add_items.html @@ -179,7 +179,7 @@ } } - $('package-form').submit(); + $('package-form').fireEvent('submit',{stop:$empty}); $('package-btn').getParent('.dialog').retrieve('instance').close(); }); diff --git a/app/wms/view/admin/delivery/process_consign_index.html b/app/wms/view/admin/delivery/process_consign_index.html index 42d5263a..f02c19a3 100644 --- a/app/wms/view/admin/delivery/process_consign_index.html +++ b/app/wms/view/admin/delivery/process_consign_index.html @@ -377,12 +377,12 @@ function delivery_verify(e){ }}); }else{ - if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').submit(); } + if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').fireEvent('submit',{stop:$empty}); } } } }else{ - if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').submit(); } + if (currentDeliveryIsPickup) { submitSend(e); } else { $('ome_single_delivery').fireEvent('submit',{stop:$empty}); } } } } diff --git a/app/wmsmgr/desktop.xml b/app/wmsmgr/desktop.xml index 86df942b..bcd94b3c 100644 --- a/app/wmsmgr/desktop.xml +++ b/app/wmsmgr/desktop.xml @@ -25,7 +25,7 @@ 第三方仓储管理 异常错误码管理 - + 报价系统授权 diff --git a/config/deploy.xml b/config/deploy.xml index 59757ff3..74a40251 100644 --- a/config/deploy.xml +++ b/config/deploy.xml @@ -1,5 +1,5 @@ - 8.0.0.20251210 + 8.3.0.20260424 ONEX OMS taog