pagedata['organization'] = $obj_organizations_op->getGropById(); $this->page('admin/organization/treeList.html'); } /** * listing * @param mixed $store_classify store_classify * @return mixed 返回值 */ public function listing($store_classify = 'offline') { $this->title = '门店列表'; $params = array( 'title' => $this->title, 'use_buildin_new_dialog' => false, 'use_buildin_set_tag' => false, 'use_buildin_recycle' => false, 'use_buildin_export' => true, 'use_buildin_import' => false, 'use_buildin_filter' => true, 'use_view_tab' => true, 'base_filter' => ['store_classify' => $store_classify], 'actions' => [ [ 'label' => '添加门店', 'href' => $this->url . '&act=add', 'target' => 'dialog::{width:660,height:480,title:\'添加门店\'}', ], [ 'label' => '批量设置', 'submit' => 'index.php?app=o2o&ctl=admin_store&act=batchCtrlStore', 'target' => 'dialog::{width:660,height:400,title:\'批量设置门店\'}', ], [ 'label' => '导入门店', 'href' => sprintf('%s&act=import', $this->url), 'target' => 'dialog::{width:660,height:400,title:\'导入门店\'}', ], ], ); $this->finder('o2o_mdl_store', $params); } //展示页面获取下架组织信息 /** * 获取ChildNode * @return mixed 返回结果 */ public function getChildNode() { $obj_organizations_op = kernel::single('organization_operation'); $this->pagedata['organization'] = $obj_organizations_op->getGropById($_POST['orgId']); $this->display('admin/organization/sub_treeList.html'); } //展示所有下级 /** * 获取AllChildNode * @return mixed 返回结果 */ public function getAllChildNode() { $obj_organizations_op = kernel::single('organization_operation'); //获取所有下级组织数组 $dataList = $obj_organizations_op->getAllChildNode($_POST['orgId'], 2); if ($dataList) { //格式化为html展示 $html = $obj_organizations_op->getAllChildNodeHtml_store($dataList); $this->pagedata['store_html'] = $html; } $this->display('admin/organization/store_all_sub_treeList.html'); } /* * 添加门店 */ public function add($org_id = null, $p_org_id = null) { // 获取总店 $shopList = app::get('ome')->model('shop')->getList('shop_id,name', [ 's_type' => '1', 'node_type' => ['ecos.ecshopx'], ]); $this->pagedata['shopList'] = $shopList; // 获取服务端 $serverList = app::get('o2o')->model('server')->getList('server_id,name'); $this->pagedata['serverList'] = $serverList; $Htime = $Mtime = []; for ($i = 0; $i < 24; $i++) { $i = str_pad($i, 2, '0', STR_PAD_LEFT); $Htime[$i] = $i; } for ($i = 0; $i < 60; $i++) { $i = str_pad($i, 2, '0', STR_PAD_LEFT); $Mtime[$i] = $i; } $this->pagedata['Htime'] = $Htime; $this->pagedata['Mtime'] = $Mtime; // 获取经销商列表(cos_type='bs') $dealerList = app::get('organization')->model('cos')->getList('cos_id,cos_name, cos_code', [ 'cos_type' => 'bs' ]); $this->pagedata['dealerList'] = $dealerList; $this->display("admin/system/store.html"); } /* * 编辑门店 */ public function edit($store_id) { // 获取服务端 $serverList = app::get('o2o')->model('server')->getList('server_id,name'); $this->pagedata['serverList'] = $serverList; $Htime = $Mtime = []; for ($i = 0; $i < 24; $i++) { $i = str_pad($i, 2, '0', STR_PAD_LEFT); $Htime[$i] = $i; } for ($i = 0; $i < 60; $i++) { $i = str_pad($i, 2, '0', STR_PAD_LEFT); $Mtime[$i] = $i; } $this->pagedata['Htime'] = $Htime; $this->pagedata['Mtime'] = $Mtime; // 获取总店 $shopList = app::get('ome')->model('shop')->getList('shop_id,name', [ 's_type' => '1', 'node_type' => ['ecos.ecshopx'], ]); $this->pagedata['shopList'] = $shopList; // 门店 $store_prop = app::get('o2o')->model('store')->dump($store_id); $org = app::get('organization')->model('organization')->dump([ 'org_no' => $store_prop['store_bn'], ]); $this->pagedata['org'] = $org; list(, $store_prop['org_name']) = explode(':', $org['org_parents_structure']); $open_hours = explode('-', $store_prop['open_hours']); list($store_prop['from_time']['H'], $store_prop['from_time']['M']) = explode(':', $open_hours[0]); list($store_prop['to_time']['H'], $store_prop['to_time']['M']) = explode(':', $open_hours[1]); $branchList = kernel::single('ome_interface_branch')->getList('*',[ 'branch_bn' => $store_prop['store_bn'], 'b_type' => '2', ]); $store_prop['storage_code'] = $branchList[0]['storage_code']; // 获取门店关联的经销商信息 if ($store_prop['store_bn']) { $orgMdl = app::get('organization')->model('organization'); $storeOrg = $orgMdl->dump(['org_no' => $store_prop['store_bn']]); if ($storeOrg && $storeOrg['parent_id']) { // 查找父级组织 $parentOrg = $orgMdl->dump(['org_id' => $storeOrg['parent_id']]); // 如果父级是经销商类型(org_type=3),获取对应的cos_id if ($parentOrg && $parentOrg['org_type'] == 3) { $cosMdl = app::get('organization')->model('cos'); // 注意:这里需要去掉BS_前缀来匹配cos_code $dealerCode = str_replace('BS_', '', $parentOrg['org_no']); $dealerCos = $cosMdl->dump(['cos_code' => $dealerCode], 'cos_id'); if ($dealerCos) { $store_prop['dealer_cos_id'] = $dealerCos['cos_id']; } } } } $this->pagedata['store_prop'] = $store_prop; // 获取经销商列表(cos_type='bs') $dealerList = app::get('organization')->model('cos')->getList('cos_id,cos_name, cos_code', [ 'cos_type' => 'bs' ]); $this->pagedata['dealerList'] = $dealerList; $this->display("admin/system/store.html"); } /** * 保存 * @return mixed 返回操作结果 */ public function save() { $this->begin(); list($rs, $msg) = kernel::single('o2o_store')->create($_POST); $this->end($rs, $msg); } /** * toRemoveStore * @param mixed $org_id ID * @return mixed 返回值 */ public function toRemoveStore($org_id) { $this->begin('index.php?app=o2o&ctl=admin_store&act=index'); $org_id = intval($org_id); if (!$org_id) { $this->end(false, '参数错误!'); } $orgObj = app::get('organization')->model('organization'); $storeObj = app::get('o2o')->model('store'); $orderObj = app::get('ome')->model('orders'); $deliveryObj = app::get('ome')->model('delivery'); $arr_store = array(); $tmp_shop_store = array(); $tmp_branch_store = array(); $tmp_shops = array(); $tmp_branches = array(); $org_arr = $orgObj->getList('org_id,org_no,parent_id', array('org_id' => $org_id)); $org_info = $org_arr[0]; $store_info = $storeObj->getList('store_id,store_bn,name,shop_id,branch_id', array('store_bn' => $org_info['org_no']), 0, 1); $store_id = $store_info[0]['store_id']; $store_bn = $store_info[0]['store_bn']; $store_name = $store_info[0]['name']; $shop_id = $store_info[0]['shop_id']; $branch_id = $store_info[0]['branch_id']; //检查门店关联的店铺是否有订单 if ($shop_id) { $row = $orderObj->getList('shop_id', array('shop_id' => $shop_id)); if ($row) { $error_msg = $store_name . '已有订单数据,不能删除'; $this->end(false, $error_msg); } } //检查门店关联的仓库是否有发货单 if ($branch_id) { $row = $deliveryObj->getList('branch_id', array('branch_id' => $branch_id)); if ($row) { $error_msg = $store_name . '已有发货数据,不能删除'; $this->end(false, $error_msg); } } $shopObj = app::get('o2o')->model('shop'); $branchObj = app::get('o2o')->model('branch'); $shopObj->delete(array('shop_id' => $shop_id)); $branchObj->delete(array('branch_id' => $branch_id)); $storeObj->delete(array('store_id' => $store_id)); //处理组织结构中的数据内容,删除店铺节点,更新父级节点的子节点标记 $orgObj->delete(array('org_id' => $org_id)); //处理原来选中的父节点 if ($org_info['parent_id'] > 0) { $p_org_info = $orgObj->dump(array("org_id" => $org_info['parent_id']), "haschild"); $child_arr = $orgObj->getList("org_id", array("parent_id" => $org_info['parent_id'], 'org_type' => 2), 0, -1); if (count($child_arr) > 0) { $org_save_parent_data['haschild'] = $p_org_info['haschild'] | 2; } else { $org_save_parent_data['haschild'] = $p_org_info['haschild'] ^ 2; } $orgObj->update($org_save_parent_data, array('org_id' => $org_info['parent_id'])); } $this->end(true, '删除门店成功!'); } /** * 获取CoordinateByAddr * @return mixed 返回结果 */ public function getCoordinateByAddr() { $adr = !empty($_GET['adr']) ? trim($_GET['adr']) : false; $city = !empty($_GET['city']) ? trim($_GET['city']) : false; if (!$adr || !$city) { echo 'false'; exit; } $uri = '/place/v2/search'; $ak = app::get('o2o')->getConf('o2o.baidumap.ak'); $sk = app::get('o2o')->getConf('o2o.baidumap.sk'); $querystring_arrays = array( 'q' => $adr, 'region' => $city, 'output' => 'json', 'ak' => $ak, 'timestamp' => time(), ); $api_url = 'http://api.map.baidu.com' . $uri . '?' . http_build_query($querystring_arrays) . '&sn=' . $this->caculateAKSN($ak, $sk, $uri, $querystring_arrays); $http = new base_httpclient; echo $http->get($api_url); exit; } /** * baiduAPI sn生成器 * @return void */ protected function caculateAKSN($ak, $sk, $url, $querystring_arrays, $method = 'GET') { if ($method === 'POST') { ksort($querystring_arrays); } $querystring = http_build_query($querystring_arrays); return md5(urlencode($url . '?' . $querystring . $sk)); } //批量导入门店 public function import() { $this->display('admin/system/import.html'); } public function to_import() { $this->finder('o2o_mdl_store'); //echo ""; } //导出门店模板 public function exportTemplate() { header("Content-Type: text/csv"); header("Content-Disposition: attachment; filename=导入门店模板-" . date('Ymd') . ".csv"); header('Cache-Control:must-revalidate,post-check=0,pre-check=0'); header('Expires:0'); header('Pragma:public'); $o2oStoreObj = app::get('o2o')->model('store'); $title = $o2oStoreObj->exportTemplate(); echo '"' . implode('","', $title) . '"'; #模板案例 /* $data[0] = array('20160088001', '上海徐汇店', '华东地区-上海', '启用', '上海-上海市-徐汇区', '移动端', '桂林路396号', '230001', '李先生', '021-34520001', '13812345678', '自营', '支持', '不支持', '不支持', '不需要', '116.43000|39.908000'); $data[1] = array('20160088002', '华南区总店', '华南地区', '启用', '广西-北海市-海城区', 'WebPos', '大连路101号', '230001', '将先生', '021-34520002', '13912345678', '加盟', '不支持', '支持', '不支持', '需要', '192.43000|63.908000'); */ $data[0] = array('20160088001', '上海徐汇店', '华东地区-上海', '启用', '上海-上海市-徐汇区', '移动端', '桂林路396号', '230001', '李先生', '021-34520001', '13812345678', '自营', '', '上海-上海市-徐汇区'); $data[1] = array('20160088002', '华南区总店', '华南地区', '启用', '广西-北海市-海城区', 'WebPos', '大连路101号', '230001', '将先生', '021-34520002', '13912345678', '加盟', '某某贸易公司', '中国'); foreach ($data as $items) { foreach ($items as $key => $val) { $items[$key] = kernel::single('base_charset')->utf2local($val); } echo "\n"; echo '"' . implode('","', $items) . '"'; } } /** * 新增仓位 * @param [type] $store_id * @return [type] */ public function position($store_id) { $storeMdl = app::get('o2o')->model('store'); $stores = $storeMdl->dump($store_id, '*'); $this->pagedata['stores'] = $stores; $branch_types = kernel::single('o2o_store')->getBranchType(); $typeoptions = []; foreach($branch_types as $v){ $typeoptions[$v['type_code']]=$v['text']; } $this->pagedata['typeoptions'] = $typeoptions; $this->display("admin/system/position.html"); } public function saveposition() { $this->begin(); $store_id = $_POST['store_id']; $branch_type = $_POST['branch_type']; $storage_code = $_POST['storage_code']; $store = app::get('o2o')->model('store')->dump($store_id); if (!$store) { $this->end(false, '门店不存在'); } $store['storage_code'] = $storage_code; list($rs, $msg) = kernel::single('o2o_store')->saveBranchType($store, $branch_type); app::get('ome')->model('operation_log')->write_log('storage_upsert@o2o', $store['store_id'], '仓位创建'); $this->end($rs, $msg); } /** * 门店编辑快照展示 * @param $log_id * @param $store_id * @date 2025-06-12 下午3:36 */ public function show_history($log_id, $store_id) { $logSnapshootMdl = app::get('ome')->model('operation_log_snapshoot'); $log = $logSnapshootMdl->db_dump(['log_id' => $log_id]); $store_prop = json_decode($log['snapshoot'], 1); //若没有缓存 历史编辑读取当前店铺信息 if (!$store_prop && $store_id) { $store_prop = app::get('o2o')->model('store')->dump($store_id); } // 获取服务端 $serverList = app::get('o2o')->model('server')->getList('server_id,name'); $this->pagedata['serverList'] = $serverList; // 获取总店 $shopList = app::get('ome')->model('shop')->getList('shop_id,name', [ 's_type' => '1', 'node_type' => ['ecos.ecshopx'], ]); $this->pagedata['shopList'] = $shopList; $org = app::get('organization')->model('organization')->dump([ 'org_no' => $store_prop['store_bn'], ]); $this->pagedata['org'] = $org; list(, $store_prop['org_name']) = explode(':', $org['org_parents_structure']); $open_hours = explode('-', $store_prop['open_hours']); list($store_prop['from_time']['H'], $store_prop['from_time']['M']) = explode(':', $open_hours[0]); list($store_prop['to_time']['H'], $store_prop['to_time']['M']) = explode(':', $open_hours[1]); $branchList = kernel::single('ome_interface_branch')->getList('*', [ 'branch_bn' => $store_prop['store_bn'], 'b_type' => '2', ]); $store_prop['storage_code'] = $branchList[0]['storage_code']; // 获取门店关联的经销商信息(历史快照) if ($store_prop['store_bn']) { $orgMdl = app::get('organization')->model('organization'); $storeOrg = $orgMdl->dump(['org_no' => $store_prop['store_bn']]); if ($storeOrg && $storeOrg['parent_id']) { // 查找父级组织 $parentOrg = $orgMdl->dump(['org_id' => $storeOrg['parent_id']]); // 如果父级是经销商类型(org_type=3),获取对应的cos_id if ($parentOrg && $parentOrg['org_type'] == 3) { $cosMdl = app::get('organization')->model('cos'); // 注意:这里需要去掉BS_前缀来匹配cos_code $dealerCode = str_replace('BS_', '', $parentOrg['org_no']); $dealerCos = $cosMdl->dump(['cos_code' => $dealerCode], 'cos_id,cos_name'); if ($dealerCos) { $store_prop['dealer_cos_id'] = $dealerCos['cos_id']; $store_prop['dealer_cos_name'] = $dealerCos['cos_name']; } } } } // 获取经销商列表(用于历史快照显示) $dealerList = app::get('organization')->model('cos')->getList('cos_id,cos_name', [ 'cos_type' => 'bs' ]); $this->pagedata['dealerList'] = $dealerList; $this->pagedata['store_prop'] = $store_prop; $this->singlepage('admin/system/store_history.html'); } /** * 门店设置库存管控 * @param $store_id * @date 2025-06-18 上午10:28 */ public function displayCtrlStore($store_id) { $storeMdl = app::get('o2o')->model('store'); $store = $storeMdl->db_dump($store_id, 'store_id,is_ctrl_store,store_bn,is_negative_store,is_o2o'); $this->pagedata['store'] = $store; $this->display("admin/system/ctrl_store.html"); } /** * 保存库存管控 * @date 2025-06-18 上午10:28 */ public function setCtrlStore() { $this->begin(); $store_id = $_POST['store_id']; $is_ctrl_store = $_POST['is_ctrl_store']; $is_negative_store = $_POST['is_negative_store']; $is_o2o = $_POST['is_o2o'] ?: '1'; $storeMdl = app::get('o2o')->model('store'); $store = $storeMdl->db_dump($store_id); if (!$store) { $this->end(false, '门店不存在'); } // 当管控库存选择"否"时,允许负库存也设置为"否" 校验是否有库存、冻结、在途 if ($is_ctrl_store == '2') { $branchProductStore = app::get('ome')->model('branch_product')->db_dump(['branch_id' => $store['branch_id'], 'store|noequal' => '0']); if ($branchProductStore) { $this->end(false, '门店有库存不能更改设置!'); } $branchProductStore = app::get('ome')->model('branch_product')->db_dump(['branch_id' => $store['branch_id'], 'store_freeze|noequal' => '0']); if ($branchProductStore) { $this->end(false, '门店有库存冻结不能更改设置!'); } $branchProductStore = app::get('ome')->model('branch_product')->db_dump(['branch_id' => $store['branch_id'], 'arrive_store|noequal' => '0']); if ($branchProductStore) { $this->end(false, '门店有在途库存不能更改设置!'); } $is_negative_store = '2'; } // 更新门店设置 $updateData = [ 'is_ctrl_store' => $is_ctrl_store, 'is_negative_store' => $is_negative_store, 'is_o2o' => $is_o2o, ]; $rs = $storeMdl->update($updateData, ['store_id' => $store_id]); if(!$rs) { $this->end(false, '保存失败!'); } // 同步更新分支设置 app::get('ome')->model('branch')->update([ 'is_ctrl_store' => $is_ctrl_store, 'is_negative_store' => $is_negative_store ], ['branch_id' => $store['branch_id'], 'check_permission' => 'false']); // 当设置为不参加O2O时,如果该门店仓曾作为任意店铺的供应仓,则需要移除 if ($is_o2o === '2' && $store['store_bn']) { $relation = app::get('ome')->getConf('shop.branch.relationship'); if (is_array($relation) && $relation) { $ip = kernel::single("base_request")->get_remote_addr(); $hasChange = false; foreach ($relation as $relShopBn => $shopBranchMap) { if (!is_array($shopBranchMap) || !$shopBranchMap) continue; $originalMap = $shopBranchMap; $changedForThisShop = false; foreach ($shopBranchMap as $relBranchId => $relBranchBn) { if ($relBranchBn === $store['store_bn']) { unset($relation[$relShopBn][$relBranchId]); $changedForThisShop = true; $hasChange = true; } } if ($changedForThisShop) { // 记录与 saveBranchRelation 一致的日志格式 $shopRow = app::get('ome')->model('shop')->dump(['shop_bn' => $relShopBn], 'shop_id'); $logShopId = $shopRow['shop_id']; $memo = '店铺' . $relShopBn . "供货仓关系原数据【" . json_encode($originalMap) . "】" . 'IP:' . $ip; $optLogModel = app::get('inventorydepth')->model('operation_log'); $optLogModel->write_log('shop', $logShopId, 'supply_branches_set', $memo); } } if ($hasChange) { app::get('ome')->setConf('shop.branch.relationship', $relation); } } } // 记录操作日志 $ctrlStoreName = ['1' => '是', '2' => '否']; $negativeStoreName = ['1' => '是', '2' => '否']; $o2oName = ['1' => '是', '2' => '否']; $msg = sprintf('【%s】管控库存,【%s】允许负库存,【%s】参加O2O', $ctrlStoreName[$is_ctrl_store], $negativeStoreName[$is_negative_store], $o2oName[$is_o2o] ); app::get('ome')->model('operation_log')->write_log('store_upsert@o2o', $store['store_id'], $msg); $this->end(true, '保存成功'); } /** * 批量设置门店库存管控 * @date 2025-06-18 上午10:28 */ public function batchCtrlStore() { // 获取选中的门店ID,参考订单定时审单的实现 if($_POST['isSelectedAll'] == '_ALL_') { // 处理全选的情况 $baseFilter = array( 'store_classify' => 'offline', 'status' => 'active' ); $storeMdl = app::get('o2o')->model('store'); $selStore = $storeMdl->getList('store_id', $baseFilter, 0, -1); $arrStoreId = array(); foreach($selStore as $val) { $arrStoreId[] = $val['store_id']; } } else { $arrStoreId = $_POST['store_id']; } $this->pagedata['storeIds'] = $arrStoreId; $this->pagedata['selected_count'] = count($arrStoreId); $this->display("admin/system/batch_ctrl_store.html"); } /** * 保存批量库存管控 * @date 2025-06-18 上午10:28 */ public function saveBatchCtrlStore() { $store_ids = $_POST['store_ids']; $is_ctrl_store = $_POST['is_ctrl_store']; $is_negative_store = $_POST['is_negative_store']; $is_o2o = isset($_POST['is_o2o']) ? $_POST['is_o2o'] : '1'; if (!$store_ids || !is_array($store_ids)) { $this->splash('error', null, '请选择要设置的门店'); return; } $storeMdl = app::get('o2o')->model('store'); $success_count = 0; $error_count = 0; $error_messages = []; foreach ($store_ids as $store_id) { $store = $storeMdl->dump($store_id); if (!$store) { $error_count++; $error_messages[] = "门店ID {$store_id}: 门店不存在"; continue; } // 当管控库存选择"否"时,允许负库存也设置为"否" 校验是否有库存、冻结、在途 if ($is_ctrl_store == '2') { $branchProductStore = app::get('ome')->model('branch_product')->dump(['branch_id' => $store['branch_id'], 'store|noequal' => '0']); if ($branchProductStore) { $error_count++; $error_messages[] = "门店 " . ($store['name'] ?: $store_id) . ": 有库存不能更改设置"; continue; } $branchProductStore = app::get('ome')->model('branch_product')->dump(['branch_id' => $store['branch_id'], 'store_freeze|noequal' => '0']); if ($branchProductStore) { $error_count++; $error_messages[] = "门店 " . ($store['name'] ?: $store_id) . ": 有库存冻结不能更改设置"; continue; } $branchProductStore = app::get('ome')->model('branch_product')->dump(['branch_id' => $store['branch_id'], 'arrive_store|noequal' => '0']); if ($branchProductStore) { $error_count++; $error_messages[] = "门店 " . ($store['name'] ?: $store_id) . ": 有在途库存不能更改设置"; continue; } $is_negative_store = '2'; } // 更新门店设置 $updateData = [ 'is_ctrl_store' => $is_ctrl_store, 'is_negative_store' => $is_negative_store, 'is_o2o' => $is_o2o, ]; $rs = $storeMdl->update($updateData, ['store_id' => $store_id]); if(!$rs) { $error_count++; $error_messages[] = "门店 " . ($store['name'] ?: $store_id) . ": 保存失败"; continue; } // 同步更新分支设置 app::get('ome')->model('branch')->update([ 'is_ctrl_store' => $is_ctrl_store, 'is_negative_store' => $is_negative_store ], ['branch_id' => $store['branch_id'], 'check_permission' => 'false']); // 当设置为不参加O2O时,如果该门店仓曾作为任意店铺的供应仓,则需要移除 if ($is_o2o === '2' && isset($store['store_bn']) && $store['store_bn']) { $relation = app::get('ome')->getConf('shop.branch.relationship'); if (is_array($relation) && $relation) { $ip = kernel::single("base_request")->get_remote_addr(); $hasChange = false; foreach ($relation as $relShopBn => $shopBranchMap) { if (!is_array($shopBranchMap) || !$shopBranchMap) continue; $originalMap = $shopBranchMap; $changedForThisShop = false; foreach ($shopBranchMap as $relBranchId => $relBranchBn) { if ($relBranchBn === $store['store_bn']) { unset($relation[$relShopBn][$relBranchId]); $changedForThisShop = true; $hasChange = true; } } if ($changedForThisShop) { // 记录与 saveBranchRelation 一致的日志格式 $shopRow = app::get('ome')->model('shop')->dump(['shop_bn' => $relShopBn], 'shop_id'); $logShopId = $shopRow['shop_id']; $memo = '店铺' . $relShopBn . "供货仓关系原数据【" . json_encode($originalMap) . "】" . 'IP:' . $ip; $optLogModel = app::get('inventorydepth')->model('operation_log'); $optLogModel->write_log('shop', $logShopId, 'supply_branches_set', $memo); } } if ($hasChange) { app::get('ome')->setConf('shop.branch.relationship', $relation); } } } $success_count++; } // 记录操作日志 - 简化文案 $ctrlStoreName = ['1' => '是', '2' => '否']; $negativeStoreName = ['1' => '是', '2' => '否']; $o2oName = ['1' => '是', '2' => '否']; $msg = sprintf('批量设置: 管控库存【%s】,允许负库存【%s】,参加O2O【%s】', $ctrlStoreName[$is_ctrl_store], $negativeStoreName[$is_negative_store], $o2oName[$is_o2o] ); // 使用o2o模块已定义的操作标识符 app::get('ome')->model('operation_log')->write_log('store_upsert@o2o', implode(',', $store_ids), $msg); if ($success_count > 0 && $error_count == 0) { $this->splash('success', null, "成功设置 {$success_count} 个门店"); } else if ($success_count > 0 && $error_count > 0) { $message = "成功设置 {$success_count} 个门店,失败 {$error_count} 个"; if (!empty($error_messages)) { $message .= ";错误详情:" . implode(';', array_slice($error_messages, 0, 3)); } $this->splash('error', null, $message); } else { $message = "设置失败"; if (!empty($error_messages)) { $message .= ":" . implode(';', array_slice($error_messages, 0, 3)); } $this->splash('error', null, $message); } } /** * 门店覆盖区域设置 * @param $store_id */ public function storeRegion($store_id) { $storeMdl = app::get('o2o')->model('store'); $store = $storeMdl->dump($store_id, 'store_id,store_bn,name,branch_id'); if (!$store) { $this->splash('error', null, '门店不存在'); return; } $this->pagedata['store'] = $store; // 检查是否已有覆盖区域设置 $warehouseMdl = app::get('logisticsmanager')->model('warehouse'); $existingWarehouse = $warehouseMdl->dump(array('branch_bn' => $store['store_bn'], 'b_type' => 2), '*'); $warehouse = array('region_ids' => '', 'region_names' => ''); if ($existingWarehouse) { $warehouse['id'] = $existingWarehouse['id']; $warehouse['warehouse_name'] = $existingWarehouse['warehouse_name']; $regionIdsRaw = $existingWarehouse['region_ids']; // 兼容按路径分号分隔的存储格式,提取每条路径最后一个数字ID作为选中项 $pathList = array_filter(explode(';', $regionIdsRaw)); $leafIds = array(); foreach ($pathList as $path) { $parts = array_values(array_filter(explode(',', $path), function ($v) { return is_numeric($v); })); if (!empty($parts)) { $leafIds[] = end($parts); } } // 回退兼容:如果没有解析出叶子ID(例如仅选了根“中国”),则展开为所有省份 if (empty($leafIds) && !empty($regionIdsRaw)) { $provinces = app::get('eccommon')->model('regions')->getList('region_id', array('region_grade' => 1, 'source' => 'systems')); foreach ($provinces as $prov) { $leafIds[] = (string)$prov['region_id']; } } // 若覆盖范围包含所有省份,则回显为选择“中国” $regionsMdl = app::get('eccommon')->model('regions'); $allProvinces = $regionsMdl->getList('region_id', array('region_grade' => 1, 'source' => 'systems')); $allProvinceIds = array_map(function($r){ return (string)$r['region_id']; }, $allProvinces); sort($allProvinceIds); $sortedLeafIds = $leafIds; sort($sortedLeafIds); if (!empty($sortedLeafIds) && $sortedLeafIds === $allProvinceIds) { $warehouse['region_ids'] = json_encode(array('CN')); $warehouse['region_names'] = '中国'; } else { $warehouse['region_ids'] = json_encode($leafIds); // 根据提取到的叶子ID查询显示名称 if (!empty($leafIds)) { $regionList = $regionsMdl->getList('local_name', array('region_id' => $leafIds)); $regionNames = array(); foreach ($regionList as $region) { $regionNames[] = $region['local_name']; } $warehouse['region_names'] = implode(',', $regionNames); } } } $this->pagedata['warehouse'] = $warehouse; $this->display('admin/store/store_region.html'); } /** * 保存门店覆盖区域 */ public function saveRange() { $this->begin(); if (empty($_POST['branch_id'])) { $this->end(false, '请选择仓库'); } if (empty($_POST['p_region_id'])) { $this->end(false, '请选择覆盖区域'); } $pRegionIdRaw = json_decode($_POST['p_region_id'], true); // 规范化区域ID路径,移除非数字节点(例如根节点“中国”的 CN) $normalizedPRegionId = array(); if (is_array($pRegionIdRaw)) { foreach ($pRegionIdRaw as $path) { $ids = explode(',', $path); $ids = array_values(array_filter($ids, function ($v) { return is_numeric($v); })); if (!empty($ids)) { $normalizedPRegionId[] = implode(',', $ids); } } } // 若仅选择“中国”(根节点),展开为所有省份ID if (empty($normalizedPRegionId) && !empty($pRegionIdRaw)) { $provinces = app::get('eccommon')->model('regions')->getList('region_id', array('region_grade' => 1, 'source' => 'systems')); foreach ($provinces as $prov) { $normalizedPRegionId[] = (string)$prov['region_id']; } } // 判定是否全国:前端若勾选中国会传 ["CN"]. 若未包含 CN,但已覆盖所有省份也视为全国 $isNationwide = is_array($pRegionIdRaw) && in_array('CN', $pRegionIdRaw, true); // 若未显式传 CN,进一步判断是否覆盖所有省份 if (!$isNationwide) { $provincesAll = app::get('eccommon')->model('regions')->getList('region_id', array('region_grade' => 1, 'source' => 'systems')); $allIds = array_map(function($r){ return (string)$r['region_id']; }, $provincesAll); sort($allIds); $selIds = array_values(array_unique(explode(',', implode(',', $normalizedPRegionId)))); $selIds = array_filter($selIds, function($v){ return $v !== ''; }); sort($selIds); if (!empty($selIds) && $selIds === $allIds) { $isNationwide = true; } } $pRegionId = $normalizedPRegionId; $operator = kernel::single('desktop_user')->get_name(); $warehouseObj = app::get('logisticsmanager')->model('warehouse'); $branchObj = app::get('ome')->model('branch'); // 门店类型固定为2 $b_type = isset($_POST['b_type']) ? $_POST['b_type'] : 2; $branch = $branchObj->dump(array('branch_id' => $_POST['branch_id'], 'check_permission' => 'false'), 'branch_bn'); if (!$branch) { $this->end(false, '仓库不存在'); } $id = $_POST['id']; $addressIds = explode(',', implode(',', $pRegionId)); $oneLevelLocalAddressName = app::get('eccommon')->model('regions')->getList('local_name,region_grade', array('region_id' => $addressIds)); $oneAddressName = ''; $addressName = ''; if ($oneLevelLocalAddressName) { foreach ($oneLevelLocalAddressName as $value) { if ($value['region_grade'] == 1) { $oneAddressName .= $value['local_name'] . ','; } } if (substr($oneAddressName, -1, 1) == ',') { $oneAddressName = substr($oneAddressName, 0, (strlen($oneAddressName) - 1)); } $addressName = implode(',', array_column($oneLevelLocalAddressName, 'local_name')); } // 全国时,region_names 统一保存为“中国” if ($isNationwide) { $addressName = '中国'; } if ($id) { $update_data = array( 'branch_id' => $_POST['branch_id'], 'warehouse_name' => 'STORE_' . ($_POST['store_bn'] ?: $branch['branch_bn']), 'region_ids' => implode(';', $pRegionId), 'region_names' => $addressName, 'branch_bn' => $branch['branch_bn'], 'one_level_region_names' => $oneAddressName, 'b_type' => $b_type, ); $warehouseObj->update($update_data, array('id' => $id)); } else { $warehouse = $warehouseObj->dump(array('branch_id' => $_POST['branch_id'], 'b_type' => $b_type), 'id'); if ($warehouse) { $this->end(false, '系统仓库ID重复,请重新填写'); } // 允许覆盖范围重合,不再校验重合 $autoWarehouseName = 'STORE_' . ($_POST['store_bn'] ?: $branch['branch_bn']); $warehouse = $warehouseObj->dump(array('warehouse_name' => $autoWarehouseName, 'b_type' => $b_type), 'id'); if ($warehouse) { $this->end(false, '区域仓名称:' . $autoWarehouseName . '已存在'); } $insert_data = array( 'branch_id' => $_POST['branch_id'], 'branch_bn' => $branch['branch_bn'], 'warehouse_name' => $autoWarehouseName, 'region_ids' => implode(';', $pRegionId), 'region_names' => $addressName, 'create_time' => time(), 'warn_num' => isset($_POST['warn_num']) ? $_POST['warn_num'] : 5, 'operator' => $operator, 'one_level_region_names' => $oneAddressName, 'b_type' => $b_type, ); $warehouseObj->insert($insert_data); } $this->end(true, '区域仓设置成功'); } }