feat: 优化腾讯地图地址选点插件,完善订单管理与分销服务
这个提交包含在:
@@ -258,16 +258,17 @@
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: linear-gradient(135deg, #00e070, #04874a);
|
||||
color: #04301e;
|
||||
font-weight: 700;
|
||||
box-shadow: 0 4px 12px rgba(0, 224, 112, 0.2);
|
||||
background: linear-gradient(135deg, #00d26a, #00a854);
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 12px rgba(0, 210, 106, 0.24);
|
||||
transition: filter 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
|
||||
.fc-area-map-btn:hover,
|
||||
.fc-area-map-btn:focus {
|
||||
color: #04301e;
|
||||
filter: brightness(0.98);
|
||||
color: #ffffff;
|
||||
filter: brightness(0.96);
|
||||
}
|
||||
|
||||
.fc-area-actions {
|
||||
@@ -276,11 +277,28 @@
|
||||
padding: 4px 0 8px;
|
||||
}
|
||||
|
||||
.fc-area-actions .btn {
|
||||
min-width: 120px;
|
||||
.fc-area-actions .btn,
|
||||
.fc-area-actions .fc-area-submit-btn {
|
||||
min-width: 128px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(135deg, #00d26a, #00a854) !important;
|
||||
color: #ffffff !important;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 14px rgba(0, 210, 106, 0.28);
|
||||
opacity: 1 !important;
|
||||
transition: filter 0.15s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
.fc-area-actions .btn:hover,
|
||||
.fc-area-actions .btn:focus,
|
||||
.fc-area-actions .fc-area-submit-btn:hover,
|
||||
.fc-area-actions .fc-area-submit-btn:focus {
|
||||
background: linear-gradient(135deg, #00c462, #00964b) !important;
|
||||
color: #ffffff !important;
|
||||
filter: brightness(0.98);
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
@@ -12,8 +12,19 @@ define([], function () {
|
||||
var lat = lat_id ? $("#" + lat_id).val() : '';
|
||||
var lng = lng_id ? $("#" + lng_id).val() : '';
|
||||
var zoom = zoom_id ? $("#" + zoom_id).val() : '';
|
||||
var url = "/addons/address/index/select";
|
||||
url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng + (input_id ? "&address=" + $("#" + input_id).val() : "") + (zoom ? "&zoom=" + zoom : "") : '';
|
||||
var address = input_id ? $("#" + input_id).val() : ($(that).data("address") || '');
|
||||
var query = [];
|
||||
if (lat && lng) {
|
||||
query.push('lat=' + encodeURIComponent(lat));
|
||||
query.push('lng=' + encodeURIComponent(lng));
|
||||
}
|
||||
if (address) {
|
||||
query.push('address=' + encodeURIComponent(address));
|
||||
}
|
||||
if (zoom) {
|
||||
query.push('zoom=' + encodeURIComponent(zoom));
|
||||
}
|
||||
var url = "/addons/address/index/select" + (query.length ? '?' + query.join('&') : '');
|
||||
Fast.api.open(url, '位置选择', {
|
||||
callback: function (res) {
|
||||
input_id && $("#" + input_id).val(res.address).trigger("change");
|
||||
|
||||
@@ -321,7 +321,50 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新完整区域实时预览文案
|
||||
* 将 WGS84 坐标转换为 GCJ02 坐标(中国大陆标准)
|
||||
* @param {number} wgsLng WGS84经度
|
||||
* @param {number} wgsLat WGS84纬度
|
||||
* @return {{lat: number, lng: number}}
|
||||
*/
|
||||
var wgs84ToGcj02 = function (wgsLng, wgsLat) {
|
||||
var lon = Number(wgsLng);
|
||||
var lat = Number(wgsLat);
|
||||
if (!isFinite(lon) || !isFinite(lat)) {
|
||||
return {lat: lat, lng: lon};
|
||||
}
|
||||
var a = 6378245.0;
|
||||
var ee = 0.00669342162296594323;
|
||||
var pi = Math.PI;
|
||||
var transformLat = function (x, y) {
|
||||
var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
};
|
||||
var transformLon = function (x, y) {
|
||||
var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
|
||||
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
|
||||
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
|
||||
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
|
||||
return ret;
|
||||
};
|
||||
var dLat = transformLat(lon - 105.0, lat - 35.0);
|
||||
var dLon = transformLon(lon - 105.0, lat - 35.0);
|
||||
var radLat = lat / 180.0 * pi;
|
||||
var magic = Math.sin(radLat);
|
||||
magic = 1 - ee * magic * magic;
|
||||
var sqrtMagic = Math.sqrt(magic);
|
||||
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
|
||||
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
|
||||
return {
|
||||
lat: lat + dLat,
|
||||
lng: lon + dLon
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新完整区域实时预览文案并同步地图选点按钮默认地址
|
||||
*/
|
||||
var refreshPreview = function () {
|
||||
var parts = [
|
||||
@@ -332,6 +375,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
return item !== '';
|
||||
});
|
||||
$('#area-full-name').text(parts.length ? parts.join(' / ') : '未选择');
|
||||
$('.fc-area-map-btn').data('address', parts.join(''));
|
||||
syncWrapState();
|
||||
};
|
||||
|
||||
@@ -354,7 +398,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据所选省市区自动解析中心经纬度(腾讯地图Place API JSONP)
|
||||
* 根据所选省市区自动解析中心经纬度(腾讯Place接口 + Nominatim自动降级)
|
||||
*/
|
||||
var autoResolveCoordinates = function () {
|
||||
var p = String($province.val() || '').trim();
|
||||
@@ -375,13 +419,37 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
clearTimeout(geocodeTimer);
|
||||
}
|
||||
geocodeTimer = setTimeout(function () {
|
||||
var queryAddress = (p === c ? p : (p + c)) + d;
|
||||
var queryAddress = (p === c ? p : (p + ' ' + c)) + ' ' + d;
|
||||
var resolveByNominatim = function () {
|
||||
$.ajax({
|
||||
url: 'https://nominatim.openstreetmap.org/search',
|
||||
dataType: 'jsonp',
|
||||
jsonp: 'json_callback',
|
||||
data: {
|
||||
format: 'json',
|
||||
q: queryAddress,
|
||||
limit: 1,
|
||||
'accept-language': 'zh-CN',
|
||||
countrycodes: 'cn'
|
||||
},
|
||||
success: function (list) {
|
||||
if ($.isArray(list) && list.length > 0 && list[0].lat && list[0].lon) {
|
||||
var gcj = wgs84ToGcj02(list[0].lon, list[0].lat);
|
||||
coordAutoFilled = true;
|
||||
$lat.val(Number(gcj.lat).toFixed(6));
|
||||
$lng.val(Number(gcj.lng).toFixed(6));
|
||||
refreshCoordTip(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var tencentKey = 'WM7BZ-ZAYLL-MZEPZ-MRZBT-MBYJE-ZAFIT';
|
||||
$.ajax({
|
||||
url: 'https://apis.map.qq.com/ws/place/v1/suggestion',
|
||||
dataType: 'jsonp',
|
||||
data: {
|
||||
keyword: queryAddress,
|
||||
keyword: (p === c ? p : (p + c)) + d,
|
||||
region: c,
|
||||
key: tencentKey,
|
||||
output: 'jsonp'
|
||||
@@ -394,8 +462,13 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
$lat.val(Number(loc.lat).toFixed(6));
|
||||
$lng.val(Number(loc.lng).toFixed(6));
|
||||
refreshCoordTip(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
resolveByNominatim();
|
||||
},
|
||||
error: function () {
|
||||
resolveByNominatim();
|
||||
}
|
||||
});
|
||||
}, 180);
|
||||
@@ -847,6 +920,66 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'backend/format'], fu
|
||||
closeAllDropdowns();
|
||||
}
|
||||
});
|
||||
|
||||
// 地图选点完成回调:不仅填充坐标,还可根据地图所选位置自动反填省 / 市 / 区县
|
||||
$('.fc-area-map-btn').data('callback', function (res) {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
var fullText = String(res.address || '') + ' ' + ($.isArray(res.rawParts) ? res.rawParts.join(' ') : '');
|
||||
var matchedProv = resolveProvinceKey(res.province || '');
|
||||
if (!matchedProv && fullText) {
|
||||
for (var pIdx = 0; pIdx < tree.provinces.length; pIdx++) {
|
||||
var pCandidate = tree.provinces[pIdx];
|
||||
var pShort = pCandidate.replace(/省|市|自治区|特别行政区|壮族|回族|维吾尔/g, '');
|
||||
if (fullText.indexOf(pCandidate) !== -1 || (pShort.length >= 2 && fullText.indexOf(pShort) !== -1)) {
|
||||
matchedProv = pCandidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var matchedCity = String(res.city || '').trim();
|
||||
if (matchedProv && tree.cityMap[matchedProv]) {
|
||||
var cCandidates = tree.cityMap[matchedProv];
|
||||
if (cCandidates.length === 1) {
|
||||
matchedCity = cCandidates[0];
|
||||
} else if (!matchedCity || cCandidates.indexOf(matchedCity) === -1) {
|
||||
for (var cIdx = 0; cIdx < cCandidates.length; cIdx++) {
|
||||
var cItem = cCandidates[cIdx];
|
||||
var cShort = cItem.replace(/市|自治州|地区|盟/g, '');
|
||||
if (fullText.indexOf(cItem) !== -1 || (cShort.length >= 2 && fullText.indexOf(cShort) !== -1)) {
|
||||
matchedCity = cItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var matchedDist = String(res.district || '').trim();
|
||||
if (matchedProv && matchedCity && tree.districtMap[matchedProv + '|' + matchedCity]) {
|
||||
var dCandidates = tree.districtMap[matchedProv + '|' + matchedCity];
|
||||
if (!matchedDist || dCandidates.indexOf(matchedDist) === -1) {
|
||||
for (var dIdx = 0; dIdx < dCandidates.length; dIdx++) {
|
||||
if (fullText.indexOf(dCandidates[dIdx]) !== -1) {
|
||||
matchedDist = dCandidates[dIdx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedProv) {
|
||||
$province.val(matchedProv).trigger('change').trigger('validate');
|
||||
}
|
||||
if (matchedCity) {
|
||||
$city.val(matchedCity).trigger('change').trigger('validate');
|
||||
}
|
||||
if (matchedDist) {
|
||||
$district.val(matchedDist).trigger('change').trigger('validate');
|
||||
}
|
||||
refreshPreview();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户