1. 问题背景与解决方案概述
最近在使用通达OA系统时,不少开发者遇到了一个棘手的问题——系统弹出提示"检测到当前产品使用的地图服务未完成商用授权"。这个错误通常出现在系统集成了百度地图API但未完成商业授权的情况下。作为一名长期从事OA系统开发的工程师,我遇到过多次类似情况,今天就来分享一个可靠的解决方案。
这个问题的本质是地图服务商对API调用的授权验证机制。百度地图从2021年开始加强了对商业用途的授权管理,未购买商业授权的应用会被限制调用。通达OA默认集成的百度地图组件如果没有正确配置商业授权,就会触发这个提示。
重要提示:直接修改代码绕过授权验证是违反服务条款的行为,正确的做法是更换为合规的地图服务。
经过多次实践验证,最稳妥的解决方案是将百度地图替换为高德地图。高德地图针对企业应用提供了更友好的授权政策,且API兼容性较好,替换成本较低。下面我将详细介绍完整的替换步骤和注意事项。
2. 代码分析与修改准备
2.1 原代码结构解析
先来看下通达OA中处理地图功能的核心类TLocationCtrl。这个类位于tform/ctrl目录下,主要功能是生成地图展示的相关HTML和事件处理。
关键属性说明:
$attr: 包含字段ID、权限控制等配置信息$obj: 流程引擎对象$itemId: 表单字段ID,格式为"data_m"+字段ID$runData: 运行时数据,包含地图坐标等信息
核心方法:
buildHandleHtml(): 生成PC端地图展示HTMLbuildHandleEvent(): 生成地图相关事件配置buildViewHtml(): 生成只读视图的HTMLbuildMobileHandleEvent(): 生成移动端事件配置
2.2 修改前的准备工作
在进行代码修改前,建议做好以下准备:
- 备份原文件:复制
TLocationCtrl.class.php为TLocationCtrl.class.php.bak - 注册高德开发者账号:前往高德开放平台(https://lbs.amap.com)注册账号
- 申请Web端JS API Key:在控制台创建应用,获取API调用密钥
- 测试环境搭建:准备一个测试用的OA流程表单用于验证修改效果
3. 详细修改步骤
3.1 替换地图API引用
原代码中使用的是百度地图的API,我们需要将其替换为高德地图的引用。修改buildHandleHtml()方法中的HTML生成部分:
php复制public function buildHandleHtml()
{
// ... 保留原有属性获取逻辑 ...
$html = '<div uid="'.$this->uid.'" class="ui-location-wrapper-'.$this->itemId.' ui-location-main-wrapper" name="'.$this->itemId.'">';
$html .= '<h5 title="'.$title.'">'.$address.'</h5>';
$html .= '<input type="hidden" value="'.$value.'" name="'.$this->itemId.'">';
$html .= '
<button type="button" class="ant-btn ant-btn-ghost ant-btn-sm f-location-btn btn btn-primary" title="'.$title.'" >
<span>查看地图</span>
</button>'.$required;
// 替换为高德地图容器
$html .= '<div id="mapContainer-'.$this->itemId.'" style="width:'.$width.'px;height:'.$high.'px;display:none;margin-top:0;padding-top:0;"></div>';
// 添加高德地图JS引用
$html .= '<script src="https://webapi.amap.com/maps?v=2.0&key=您的高德API_KEY"></script>';
$html .= '</div>';
return $this->isSecret ? '' : $html;
}
3.2 修改地图初始化逻辑
在页面底部或单独JS文件中添加地图初始化代码:
javascript复制$('.f-location-btn').click(function(){
var wrapper = $(this).closest('.ui-location-main-wrapper');
var mapDiv = wrapper.find('div[id^="mapContainer"]');
var input = wrapper.find('input[type="hidden"]');
// 显示/隐藏地图容器
mapDiv.toggle();
if(mapDiv.is(':visible')){
// 解析坐标数据
var value = input.val();
var parts = value.split(',');
var lng = parts[5] || 116.397428;
var lat = parts[3] || 39.90923;
var address = parts[1] || '北京市';
// 初始化高德地图
var map = new AMap.Map(mapDiv[0], {
zoom: 15,
center: [parseFloat(lng), parseFloat(lat)]
});
// 添加标记点
new AMap.Marker({
position: [parseFloat(lng), parseFloat(lat)],
title: address,
map: map
});
}
});
3.3 调整坐标数据格式
高德地图使用的坐标格式与百度地图不同,需要注意数据格式转换。在buildHandleEvent()方法中返回的坐标数据应保持一致性:
php复制public function buildHandleEvent()
{
$value = isset($this->runData[$this->itemId]) ? $this->runData[$this->itemId] : "";
$valueArr = explode(',', $value);
$address = isset($valueArr[1]) ? $valueArr[1] : "";
$lat = isset($valueArr[3]) ? $valueArr[3] : "";
$lng = isset($valueArr[5]) ? $valueArr[5] : "";
return array(
// ... 其他字段保持不变 ...
'value' => array(
'address' => $address,
'lat' => $lat,
'lng' => $lng
),
);
}
4. 常见问题与解决方案
4.1 地图不显示或白屏
可能原因:
- API Key未正确配置或已过期
- 网络策略限制了高德地图域名的访问
- 容器尺寸为0或z-index层级问题
解决方案:
- 检查控制台是否有JS错误
- 确保以下域名可访问:
- *.amap.com
- *.aliyuncs.com
- 给地图容器添加明确的宽度高度和position:relative样式
4.2 坐标位置偏移
可能原因:
百度地图使用的是BD-09坐标系,而高德地图使用的是GCJ-02坐标系,直接使用原坐标会导致位置偏移。
解决方案:
需要进行坐标系转换,可以在服务端添加转换方法:
php复制function bdToGcj($bd_lat, $bd_lng) {
$x_pi = 3.14159265358979324 * 3000.0 / 180.0;
$x = $bd_lng - 0.0065;
$y = $bd_lat - 0.006;
$z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $x_pi);
$theta = atan2($y, $x) - 0.000003 * cos($x * $x_pi);
$gg_lng = $z * cos($theta);
$gg_lat = $z * sin($theta);
return array('lat' => $gg_lat, 'lng' => $gg_lng);
}
4.3 移动端兼容性问题
可能原因:
移动端浏览器对地图JS API的加载策略不同,可能导致初始化失败。
解决方案:
修改移动端事件构建方法,确保正确加载:
php复制public function buildMobileHandleEvent()
{
// ... 其他代码不变 ...
return array(
// ...
'amapKey' => '您的高德API_KEY', // 将KEY传递给移动端
'coordType' => 'gcj02' // 明确坐标系类型
);
}
5. 优化建议与注意事项
5.1 性能优化建议
- 延迟加载地图JS:不要在每个控件都加载JS,改为在页面底部统一加载一次
- 复用地图实例:同一页面多个地图控件可以共享一个地图实例
- 按需加载插件:高德地图的插件(如搜索、路线规划)应该动态加载
5.2 安全注意事项
- 保护API Key:不要将Key直接写在前端代码中,应该通过后端接口动态获取
- 限制Referer:在高德控制台设置Key的HTTP Referer限制
- 监控使用量:设置使用量告警,防止恶意调用产生高额费用
5.3 维护建议
- 封装地图服务类:将地图相关操作封装成独立服务类,便于后续更换服务商
- 统一坐标管理:在数据库中统一存储一种坐标系,使用时再转换为目标坐标系
- 添加版本标记:在代码中添加修改注释,方便后续维护
php复制/**
* 地图服务修改记录
* 2023-05-20 将百度地图替换为高德地图
* 修改人:YourName
* 原因:解决商业授权问题
*/
在实际项目中,我建议先在一个测试流程中验证修改效果,确认无误后再应用到生产环境。同时要注意,如果OA系统后续升级,可能需要重新应用这些修改。保留好修改记录和备份文件是关键。