正在显示
16 个修改的文件
包含
1230 行增加
和
101 行删除
addons/address/.addonrc
0 → 100644
1 | +{"files":[],"license":"regular","licenseto":"10789","licensekey":"89rbzyMwR7egBFAo EyUfEJxJ9VFzYuZOURRwgg==","domains":[],"licensecodes":[],"validations":[]} |
addons/address/Address.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\address; | ||
4 | + | ||
5 | +use think\Addons; | ||
6 | + | ||
7 | +/** | ||
8 | + * 地址选择 | ||
9 | + * @author [MiniLing] <[laozheyouxiang@163.com]> | ||
10 | + */ | ||
11 | +class Address extends Addons | ||
12 | +{ | ||
13 | + | ||
14 | + /** | ||
15 | + * 插件安装方法 | ||
16 | + * @return bool | ||
17 | + */ | ||
18 | + public function install() | ||
19 | + { | ||
20 | + return true; | ||
21 | + } | ||
22 | + | ||
23 | + /** | ||
24 | + * 插件卸载方法 | ||
25 | + * @return bool | ||
26 | + */ | ||
27 | + public function uninstall() | ||
28 | + { | ||
29 | + return true; | ||
30 | + } | ||
31 | + | ||
32 | +} |
addons/address/bootstrap.js
0 → 100644
1 | +require([], function () { | ||
2 | + //绑定data-toggle=addresspicker属性点击事件 | ||
3 | + | ||
4 | + $(document).on('click', "[data-toggle='addresspicker']", function () { | ||
5 | + var that = this; | ||
6 | + var callback = $(that).data('callback'); | ||
7 | + var input_id = $(that).data("input-id") ? $(that).data("input-id") : ""; | ||
8 | + var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : ""; | ||
9 | + var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : ""; | ||
10 | + var lat = lat_id ? $("#" + lat_id).val() : ''; | ||
11 | + var lng = lng_id ? $("#" + lng_id).val() : ''; | ||
12 | + var url = "/addons/address/index/select"; | ||
13 | + url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng : ''; | ||
14 | + Fast.api.open(url, '位置选择', { | ||
15 | + callback: function (res) { | ||
16 | + input_id && $("#" + input_id).val(res.address).trigger("change"); | ||
17 | + lat_id && $("#" + lat_id).val(res.lat).trigger("change"); | ||
18 | + lng_id && $("#" + lng_id).val(res.lng).trigger("change"); | ||
19 | + try { | ||
20 | + //执行回调函数 | ||
21 | + if (typeof callback === 'function') { | ||
22 | + callback.call(that, res); | ||
23 | + } | ||
24 | + } catch (e) { | ||
25 | + | ||
26 | + } | ||
27 | + } | ||
28 | + }); | ||
29 | + }); | ||
30 | +}); |
addons/address/config.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +return array( | ||
4 | + array( | ||
5 | + 'name' => 'maptype', | ||
6 | + 'title' => '默认地图类型', | ||
7 | + 'type' => 'radio', | ||
8 | + 'content' => | ||
9 | + array( | ||
10 | + 'baidu' => '百度地图', | ||
11 | + 'amap' => '高德地图', | ||
12 | + 'tencent' => '腾讯地图', | ||
13 | + ), | ||
14 | + 'value' => 'baidu', | ||
15 | + 'rule' => 'required', | ||
16 | + 'msg' => '', | ||
17 | + 'tip' => '', | ||
18 | + 'ok' => '', | ||
19 | + 'extend' => '', | ||
20 | + ), | ||
21 | + array( | ||
22 | + 'name' => 'location', | ||
23 | + 'title' => '默认检索城市', | ||
24 | + 'type' => 'string', | ||
25 | + 'content' => | ||
26 | + array(), | ||
27 | + 'value' => '北京', | ||
28 | + 'rule' => 'required', | ||
29 | + 'msg' => '', | ||
30 | + 'tip' => '', | ||
31 | + 'ok' => '', | ||
32 | + 'extend' => '', | ||
33 | + ), | ||
34 | + array( | ||
35 | + 'name' => 'zoom', | ||
36 | + 'title' => '默认缩放级别', | ||
37 | + 'type' => 'string', | ||
38 | + 'content' => | ||
39 | + array(), | ||
40 | + 'value' => '12', | ||
41 | + 'rule' => 'required', | ||
42 | + 'msg' => '', | ||
43 | + 'tip' => '', | ||
44 | + 'ok' => '', | ||
45 | + 'extend' => '', | ||
46 | + ), | ||
47 | + array( | ||
48 | + 'name' => 'lat', | ||
49 | + 'title' => '默认Lat', | ||
50 | + 'type' => 'string', | ||
51 | + 'content' => | ||
52 | + array(), | ||
53 | + 'value' => '39.919990', | ||
54 | + 'rule' => 'required', | ||
55 | + 'msg' => '', | ||
56 | + 'tip' => '', | ||
57 | + 'ok' => '', | ||
58 | + 'extend' => '', | ||
59 | + ), | ||
60 | + array( | ||
61 | + 'name' => 'lng', | ||
62 | + 'title' => '默认Lng', | ||
63 | + 'type' => 'string', | ||
64 | + 'content' => | ||
65 | + array(), | ||
66 | + 'value' => '116.456270', | ||
67 | + 'rule' => 'required', | ||
68 | + 'msg' => '', | ||
69 | + 'tip' => '', | ||
70 | + 'ok' => '', | ||
71 | + 'extend' => '', | ||
72 | + ), | ||
73 | + array( | ||
74 | + 'name' => 'baidukey', | ||
75 | + 'title' => '百度地图KEY', | ||
76 | + 'type' => 'string', | ||
77 | + 'content' => | ||
78 | + array(), | ||
79 | + 'value' => 'hAeMFHmpyHa2ZjaCH9VVridl', | ||
80 | + 'rule' => 'required', | ||
81 | + 'msg' => '', | ||
82 | + 'tip' => '', | ||
83 | + 'ok' => '', | ||
84 | + 'extend' => '', | ||
85 | + ), | ||
86 | + array( | ||
87 | + 'name' => 'amapkey', | ||
88 | + 'title' => '高德地图KEY', | ||
89 | + 'type' => 'string', | ||
90 | + 'content' => | ||
91 | + array(), | ||
92 | + 'value' => '608d75903d29ad471362f8c58c550daf', | ||
93 | + 'rule' => 'required', | ||
94 | + 'msg' => '', | ||
95 | + 'tip' => '', | ||
96 | + 'ok' => '', | ||
97 | + 'extend' => '', | ||
98 | + ), | ||
99 | + array( | ||
100 | + 'name' => 'tencentkey', | ||
101 | + 'title' => '腾讯地图KEY', | ||
102 | + 'type' => 'string', | ||
103 | + 'content' => | ||
104 | + array(), | ||
105 | + 'value' => '608d75903d29ad471362f8c58c550daf', | ||
106 | + 'rule' => 'required', | ||
107 | + 'msg' => '', | ||
108 | + 'tip' => '', | ||
109 | + 'ok' => '', | ||
110 | + 'extend' => '', | ||
111 | + ), | ||
112 | + array( | ||
113 | + 'name' => '__tips__', | ||
114 | + 'title' => '温馨提示', | ||
115 | + 'type' => '', | ||
116 | + 'content' => | ||
117 | + array(), | ||
118 | + 'value' => '请先申请对应地图的Key,配置后再使用', | ||
119 | + 'rule' => '', | ||
120 | + 'msg' => '', | ||
121 | + 'tip' => '', | ||
122 | + 'ok' => '', | ||
123 | + 'extend' => 'alert-danger-light', | ||
124 | + ), | ||
125 | +); |
addons/address/controller/Index.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | +namespace addons\address\controller; | ||
4 | + | ||
5 | +use think\addons\Controller; | ||
6 | +use think\Config; | ||
7 | +use think\Hook; | ||
8 | + | ||
9 | +class Index extends Controller | ||
10 | +{ | ||
11 | + | ||
12 | + public function index() | ||
13 | + { | ||
14 | + // 语言检测 | ||
15 | + $lang = strip_tags($this->request->langset()); | ||
16 | + | ||
17 | + $site = Config::get("site"); | ||
18 | + | ||
19 | + // 配置信息 | ||
20 | + $config = [ | ||
21 | + 'site' => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])), | ||
22 | + 'upload' => null, | ||
23 | + 'modulename' => 'addons', | ||
24 | + 'controllername' => 'index', | ||
25 | + 'actionname' => 'index', | ||
26 | + 'jsname' => 'addons/address', | ||
27 | + 'moduleurl' => '', | ||
28 | + 'language' => $lang | ||
29 | + ]; | ||
30 | + $config = array_merge($config, Config::get("view_replace_str")); | ||
31 | + | ||
32 | + // 配置信息后 | ||
33 | + Hook::listen("config_init", $config); | ||
34 | + // 加载当前控制器语言包 | ||
35 | + $this->view->assign('site', $site); | ||
36 | + $this->view->assign('config', $config); | ||
37 | + | ||
38 | + return $this->view->fetch(); | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * 选择地址 | ||
43 | + * @return string | ||
44 | + * @throws \think\Exception | ||
45 | + */ | ||
46 | + public function select() | ||
47 | + { | ||
48 | + $config = get_addon_config('address'); | ||
49 | + $lat = $this->request->get('lat', $config['lat']); | ||
50 | + $lng = $this->request->get('lng', $config['lng']); | ||
51 | + $this->view->assign('lat', $lat); | ||
52 | + $this->view->assign('lng', $lng); | ||
53 | + $this->view->assign('location', $config['location']); | ||
54 | + return $this->view->fetch('index/' . $config['maptype']); | ||
55 | + } | ||
56 | + | ||
57 | +} |
addons/address/info.ini
0 → 100644
addons/address/view/index/amap.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/> | ||
8 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
9 | + <style type="text/css"> | ||
10 | + body { | ||
11 | + margin: 0; | ||
12 | + padding: 0; | ||
13 | + } | ||
14 | + | ||
15 | + #container { | ||
16 | + position: absolute; | ||
17 | + left: 0; | ||
18 | + top: 0; | ||
19 | + right: 0; | ||
20 | + bottom: 0; | ||
21 | + } | ||
22 | + | ||
23 | + .confirm { | ||
24 | + position: absolute; | ||
25 | + bottom: 30px; | ||
26 | + right: 4%; | ||
27 | + z-index: 99; | ||
28 | + height: 50px; | ||
29 | + width: 50px; | ||
30 | + line-height: 50px; | ||
31 | + font-size: 15px; | ||
32 | + text-align: center; | ||
33 | + background-color: white; | ||
34 | + background: #1ABC9C; | ||
35 | + color: white; | ||
36 | + border: none; | ||
37 | + cursor: pointer; | ||
38 | + border-radius: 50%; | ||
39 | + } | ||
40 | + | ||
41 | + .search { | ||
42 | + position: absolute; | ||
43 | + width: 400px; | ||
44 | + top: 0; | ||
45 | + left: 50%; | ||
46 | + padding: 5px; | ||
47 | + margin-left: -200px; | ||
48 | + } | ||
49 | + | ||
50 | + .amap-marker-label { | ||
51 | + border: 0; | ||
52 | + background-color: transparent; | ||
53 | + } | ||
54 | + | ||
55 | + .info { | ||
56 | + padding: .75rem 1.25rem; | ||
57 | + margin-bottom: 1rem; | ||
58 | + border-radius: .25rem; | ||
59 | + position: fixed; | ||
60 | + top: 2rem; | ||
61 | + background-color: white; | ||
62 | + width: auto; | ||
63 | + min-width: 22rem; | ||
64 | + border-width: 0; | ||
65 | + left: 1.8rem; | ||
66 | + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); | ||
67 | + } | ||
68 | + </style> | ||
69 | +</head> | ||
70 | +<body> | ||
71 | +<div class="search"> | ||
72 | + <div class="input-group"> | ||
73 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
74 | + <span class="input-group-btn"> | ||
75 | + <button type="submit" name="search" id="search-btn" class="btn btn-success"> | ||
76 | + <i class="fa fa-search"></i> | ||
77 | + </button> | ||
78 | + </span> | ||
79 | + </div> | ||
80 | +</div> | ||
81 | +<div class="confirm">确定</div> | ||
82 | +<div id="container"></div> | ||
83 | +<script type="text/javascript" src="//webapi.amap.com/maps?v=1.4.11&key={$config.amapkey|default=''}&plugin=AMap.ToolBar,AMap.Autocomplete,AMap.PlaceSearch,AMap.Geocoder"></script> | ||
84 | +<!-- UI组件库 1.0 --> | ||
85 | +<script src="//webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script> | ||
86 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
87 | +<script type="text/javascript"> | ||
88 | + $(function () { | ||
89 | + var as, address, map, lat, lng, geocoder; | ||
90 | + var init = function () { | ||
91 | + AMapUI.loadUI(['misc/PositionPicker', 'misc/PoiPicker'], function (PositionPicker, PoiPicker) { | ||
92 | + //加载PositionPicker,loadUI的路径参数为模块名中 'ui/' 之后的部分 | ||
93 | + map = new AMap.Map('container', { | ||
94 | + zoom: parseInt('{$config.zoom}') | ||
95 | + }); | ||
96 | + geocoder = new AMap.Geocoder({ | ||
97 | + radius: 1000 //范围,默认:500 | ||
98 | + }); | ||
99 | + var positionPicker = new PositionPicker({ | ||
100 | + mode: 'dragMarker',//设定为拖拽地图模式,可选'dragMap'、'dragMarker',默认为'dragMap' | ||
101 | + map: map//依赖地图对象 | ||
102 | + }); | ||
103 | + //输入提示 | ||
104 | + var autoOptions = { | ||
105 | + input: "place" | ||
106 | + }; | ||
107 | + | ||
108 | + var relocation = function (lnglat) { | ||
109 | + lng = lnglat.lng; | ||
110 | + lat = lnglat.lat; | ||
111 | + map.panTo([lng, lat]); | ||
112 | + positionPicker.start(lnglat); | ||
113 | + geocoder.getAddress(lng + ',' + lat, function (status, result) { | ||
114 | + if (status === 'complete' && result.regeocode) { | ||
115 | + var address = result.regeocode.formattedAddress; | ||
116 | + var label = '<div class="info">地址:' + address + '<br>经度:' + lng + '<br>纬度:' + lat + '</div>'; | ||
117 | + positionPicker.marker.setLabel({ | ||
118 | + content: label //显示内容 | ||
119 | + }); | ||
120 | + } else { | ||
121 | + console.log(JSON.stringify(result)); | ||
122 | + } | ||
123 | + }); | ||
124 | + }; | ||
125 | + var auto = new AMap.Autocomplete(autoOptions); | ||
126 | + | ||
127 | + //构造地点查询类 | ||
128 | + var placeSearch = new AMap.PlaceSearch({ | ||
129 | + map: map | ||
130 | + }); | ||
131 | + //注册监听,当选中某条记录时会触发 | ||
132 | + AMap.event.addListener(auto, "select", function (e) { | ||
133 | + placeSearch.setCity(e.poi.adcode); | ||
134 | + placeSearch.search(e.poi.name); //关键字查询查询 | ||
135 | + }); | ||
136 | + AMap.event.addListener(map, 'click', function (e) { | ||
137 | + relocation(e.lnglat); | ||
138 | + }); | ||
139 | + | ||
140 | + //加载工具条 | ||
141 | + var tool = new AMap.ToolBar(); | ||
142 | + map.addControl(tool); | ||
143 | + | ||
144 | + var poiPicker = new PoiPicker({ | ||
145 | + input: 'place', | ||
146 | + placeSearchOptions: { | ||
147 | + map: map, | ||
148 | + pageSize: 6 //关联搜索分页 | ||
149 | + } | ||
150 | + }); | ||
151 | + poiPicker.on('poiPicked', function (poiResult) { | ||
152 | + poiPicker.hideSearchResults(); | ||
153 | + $('.poi .nearpoi').text(poiResult.item.name); | ||
154 | + $('.address .info').text(poiResult.item.address); | ||
155 | + $('#address').val(poiResult.item.address); | ||
156 | + $("#place").val(poiResult.item.name); | ||
157 | + | ||
158 | + relocation(poiResult.item.location); | ||
159 | + }); | ||
160 | + | ||
161 | + positionPicker.on('success', function (positionResult) { | ||
162 | + as = positionResult.position; | ||
163 | + address = positionResult.address; | ||
164 | + lat = as.lat; | ||
165 | + lng = as.lng; | ||
166 | + }); | ||
167 | + positionPicker.on('fail', function (positionResult) { | ||
168 | + address = ''; | ||
169 | + }); | ||
170 | + positionPicker.start(); | ||
171 | + }); | ||
172 | + }; | ||
173 | + | ||
174 | + //点击确定后执行回调赋值 | ||
175 | + var close = function (data) { | ||
176 | + var index = parent.Layer.getFrameIndex(window.name); | ||
177 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
178 | + //再执行关闭 | ||
179 | + parent.Layer.close(index); | ||
180 | + //再调用回传函数 | ||
181 | + if (typeof callback === 'function') { | ||
182 | + callback.call(undefined, data); | ||
183 | + } | ||
184 | + }; | ||
185 | + | ||
186 | + //点击搜索按钮 | ||
187 | + $(document).on('click', '.confirm', function () { | ||
188 | + var zoom = map.getZoom(); | ||
189 | + var data = {lat: lat, lng: lng, zoom: zoom, address: address}; | ||
190 | + close(data); | ||
191 | + }); | ||
192 | + init(); | ||
193 | + }); | ||
194 | +</script> | ||
195 | +</body> | ||
196 | +</html> |
addons/address/view/index/baidu.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/> | ||
8 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
9 | + <style type="text/css"> | ||
10 | + body { | ||
11 | + margin: 0; | ||
12 | + padding: 0; | ||
13 | + } | ||
14 | + | ||
15 | + #container { | ||
16 | + position: absolute; | ||
17 | + left: 0; | ||
18 | + top: 0; | ||
19 | + right: 0; | ||
20 | + bottom: 0; | ||
21 | + } | ||
22 | + | ||
23 | + .confirm { | ||
24 | + position: absolute; | ||
25 | + bottom: 30px; | ||
26 | + right: 4%; | ||
27 | + z-index: 99; | ||
28 | + height: 50px; | ||
29 | + width: 50px; | ||
30 | + line-height: 50px; | ||
31 | + font-size: 15px; | ||
32 | + text-align: center; | ||
33 | + background-color: white; | ||
34 | + background: #1ABC9C; | ||
35 | + color: white; | ||
36 | + border: none; | ||
37 | + cursor: pointer; | ||
38 | + border-radius: 50%; | ||
39 | + } | ||
40 | + | ||
41 | + .search { | ||
42 | + position: absolute; | ||
43 | + width: 400px; | ||
44 | + top: 0; | ||
45 | + left: 50%; | ||
46 | + padding: 5px; | ||
47 | + margin-left: -200px; | ||
48 | + } | ||
49 | + | ||
50 | + label.BMapLabel { | ||
51 | + max-width: inherit; | ||
52 | + padding: .75rem 1.25rem; | ||
53 | + margin-bottom: 1rem; | ||
54 | + background-color: white; | ||
55 | + width: auto; | ||
56 | + min-width: 22rem; | ||
57 | + border: none; | ||
58 | + box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5); | ||
59 | + } | ||
60 | + | ||
61 | + </style> | ||
62 | +</head> | ||
63 | +<body> | ||
64 | +<div class="search"> | ||
65 | + <div class="input-group"> | ||
66 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
67 | + <div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div> | ||
68 | + <span class="input-group-btn"> | ||
69 | + <button type="button" name="search" id="address" class="btn btn-success"> | ||
70 | + <i class="fa fa-search"></i> | ||
71 | + </button> | ||
72 | + </span> | ||
73 | + </div> | ||
74 | +</div> | ||
75 | +<div class="confirm">确定</div> | ||
76 | +<div id="container"></div> | ||
77 | +<script type="text/javascript" src="//api.map.baidu.com/api?v=2.0&ak={$config.baidukey|default=''}"></script> | ||
78 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
79 | +<script type="text/javascript"> | ||
80 | + $(function () { | ||
81 | + // 百度地图API功能 | ||
82 | + function G(id) { | ||
83 | + return document.getElementById(id); | ||
84 | + } | ||
85 | + | ||
86 | + var map, marker, searchService, address = null, lng, lat; | ||
87 | + | ||
88 | + var init = function () { | ||
89 | + map = new BMap.Map("container"); // 创建地图实例 | ||
90 | + var point = new BMap.Point({$lng}, {$lat}); // 创建点坐标 | ||
91 | + map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放 | ||
92 | + map.centerAndZoom(point, parseInt("{$config.zoom}")); // 初始化地图,设置中心点坐标和地图级别 | ||
93 | + | ||
94 | + var size = new BMap.Size(10, 20); | ||
95 | + map.addControl(new BMap.CityListControl({ | ||
96 | + anchor: BMAP_ANCHOR_TOP_LEFT, | ||
97 | + offset: size, | ||
98 | + })); | ||
99 | + | ||
100 | + var geoc = new BMap.Geocoder(); | ||
101 | + | ||
102 | + var addpoint = function (point) { | ||
103 | + //通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度 | ||
104 | + var pt = point; | ||
105 | + geoc.getLocation(pt, function (rs) { | ||
106 | + //对象可以获取到详细的地址信息 | ||
107 | + address = rs.address; | ||
108 | + deletePoint(); | ||
109 | + var mk = new BMap.Marker(pt); | ||
110 | + map.addOverlay(mk); | ||
111 | + map.panTo(pt); | ||
112 | + var label = new BMap.Label('<div class="info">地址:' + address + '<br>经度:' + pt.lng + '<br>纬度:' + pt.lat + '</div>', {offset: new BMap.Size(16, 20)}); | ||
113 | + label.setStyle({ | ||
114 | + border: 'none', | ||
115 | + padding: '.75rem 1.25rem' | ||
116 | + }); | ||
117 | + mk.setLabel(label); | ||
118 | + //将对应的HTML元素设置值 | ||
119 | + lng = pt.lng; | ||
120 | + lat = pt.lat; | ||
121 | + }); | ||
122 | + }; | ||
123 | + | ||
124 | + if ("{$lng}" != '' && "{$lat}" != '') { | ||
125 | + addpoint(point); | ||
126 | + } | ||
127 | + | ||
128 | + ac = new BMap.Autocomplete({"input": "place", "location": map}); //建立一个自动完成的对象 | ||
129 | + ac.addEventListener("onhighlight", function (e) { //鼠标放在下拉列表上的事件 | ||
130 | + var str = ""; | ||
131 | + var _value = e.fromitem.value; | ||
132 | + var value = ""; | ||
133 | + if (e.fromitem.index > -1) { | ||
134 | + value = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
135 | + } | ||
136 | + str = "FromItem<br />index = " + e.fromitem.index + "<br />value = " + value; | ||
137 | + | ||
138 | + value = ""; | ||
139 | + if (e.toitem.index > -1) { | ||
140 | + _value = e.toitem.value; | ||
141 | + value = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
142 | + } | ||
143 | + str += "<br />ToItem<br />index = " + e.toitem.index + "<br />value = " + value; | ||
144 | + G("searchResultPanel").innerHTML = str; | ||
145 | + }); | ||
146 | + ac.addEventListener("onconfirm", function (e) { //鼠标点击下拉列表后的事件 | ||
147 | + var _value = e.item.value; | ||
148 | + myValue = _value.province + _value.city + _value.district + _value.street + _value.business; | ||
149 | + G("searchResultPanel").innerHTML = "onconfirm<br />index = " + e.item.index + "<br />myValue = " + myValue; | ||
150 | + setPlace(); | ||
151 | + }); | ||
152 | + | ||
153 | + function setPlace() { | ||
154 | + map.clearOverlays(); //清除地图上所有覆盖物 | ||
155 | + function myFun() { | ||
156 | + var result = local.getResults().getPoi(0); | ||
157 | + var pp = result.point; //获取第一个智能搜索的结果 | ||
158 | + map.centerAndZoom(pp, 18); | ||
159 | + map.addOverlay(new BMap.Marker(pp)); //添加标注 | ||
160 | + lng = pp.lng; | ||
161 | + lat = pp.lat; | ||
162 | + address = result.address; | ||
163 | + } | ||
164 | + | ||
165 | + var local = new BMap.LocalSearch(map, { //智能搜索 | ||
166 | + onSearchComplete: myFun | ||
167 | + }); | ||
168 | + local.search(myValue); | ||
169 | + } | ||
170 | + | ||
171 | + map.addEventListener("click", function (e) { | ||
172 | + //通过点击百度地图,可以获取到对应的point, 由point的lng、lat属性就可以获取对应的经度纬度 | ||
173 | + var pt = e.point; | ||
174 | + addpoint(e.point); | ||
175 | + }); | ||
176 | + | ||
177 | + /** | ||
178 | + * 清除覆盖物 | ||
179 | + */ | ||
180 | + function deletePoint() { | ||
181 | + var allOverlay = map.getOverlays(); | ||
182 | + for (var i = 0; i < allOverlay.length; i++) { | ||
183 | + map.removeOverlay(allOverlay[i]); | ||
184 | + } | ||
185 | + } | ||
186 | + }; | ||
187 | + | ||
188 | + var close = function (data) { | ||
189 | + var index = parent.Layer.getFrameIndex(window.name); | ||
190 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
191 | + //再执行关闭 | ||
192 | + parent.Layer.close(index); | ||
193 | + //再调用回传函数 | ||
194 | + if (typeof callback === 'function') { | ||
195 | + callback.call(undefined, data); | ||
196 | + } | ||
197 | + }; | ||
198 | + | ||
199 | + //点击确定后执行回调赋值 | ||
200 | + $(document).on('click', '.confirm', function () { | ||
201 | + var zoom = map.getZoom(); | ||
202 | + var data = {lat: lat, lng: lng, zoom: zoom, address: address}; | ||
203 | + close(data); | ||
204 | + }); | ||
205 | + | ||
206 | + init(); | ||
207 | + }); | ||
208 | +</script> | ||
209 | +</body> | ||
210 | +</html> |
addons/address/view/index/index.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> | ||
5 | + | ||
6 | + <title>地图位置(经纬度)选择插件 - FastAdmin</title> | ||
7 | + | ||
8 | + <!-- Bootstrap Core CSS --> | ||
9 | + <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
10 | + | ||
11 | + <!-- Custom CSS --> | ||
12 | + <link href="https://cdn.demo.fastadmin.net/assets/css/frontend.css" rel="stylesheet"> | ||
13 | + | ||
14 | + <!-- Plugin CSS --> | ||
15 | + <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"> | ||
16 | + | ||
17 | + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||
18 | + <!--[if lt IE 9]> | ||
19 | + <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script> | ||
20 | + <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script> | ||
21 | + <![endif]--> | ||
22 | +</head> | ||
23 | +<body> | ||
24 | +<div class="container"> | ||
25 | + | ||
26 | + <div class="bs-docs-section clearfix"> | ||
27 | + <div class="row"> | ||
28 | + <div class="col-lg-12"> | ||
29 | + <div class="page-header"> | ||
30 | + <h2 id="navbar">地图位置(经纬度)选择示例</h2> | ||
31 | + </div> | ||
32 | + | ||
33 | + <div class="bs-component"> | ||
34 | + <form action="" method="post" role="form"> | ||
35 | + <div class="form-group"> | ||
36 | + <label for=""></label> | ||
37 | + <input type="text" class="form-control" name="" id="address" placeholder="地址"> | ||
38 | + </div> | ||
39 | + <div class="form-group"> | ||
40 | + <label for=""></label> | ||
41 | + <input type="text" class="form-control" name="" id="lng" placeholder="经度"> | ||
42 | + </div> | ||
43 | + <div class="form-group"> | ||
44 | + <label for=""></label> | ||
45 | + <input type="text" class="form-control" name="" id="lat" placeholder="纬度"> | ||
46 | + </div> | ||
47 | + | ||
48 | + <button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择地址获取经纬度</button> | ||
49 | + </form> | ||
50 | + </div> | ||
51 | + | ||
52 | + <div class="page-header"> | ||
53 | + <h2 id="code">调用代码</h2> | ||
54 | + </div> | ||
55 | + <div class="bs-component"> | ||
56 | + <textarea class="form-control" rows="17"> | ||
57 | +<form action="" method="post" role="form"> | ||
58 | + <div class="form-group"> | ||
59 | + <label for=""></label> | ||
60 | + <input type="text" class="form-control" name="" id="address" placeholder="地址"> | ||
61 | + </div> | ||
62 | + <div class="form-group"> | ||
63 | + <label for=""></label> | ||
64 | + <input type="text" class="form-control" name="" id="lng" placeholder="经度"> | ||
65 | + </div> | ||
66 | + <div class="form-group"> | ||
67 | + <label for=""></label> | ||
68 | + <input type="text" class="form-control" name="" id="lat" placeholder="纬度"> | ||
69 | + </div> | ||
70 | + | ||
71 | + <button type="button" class="btn btn-primary" data-toggle='addresspicker' data-input-id="address" data-lng-id="lng" data-lat-id="lat">点击选择地址获取经纬度</button> | ||
72 | +</form> | ||
73 | + </textarea> | ||
74 | + </div> | ||
75 | + <div class="page-header"> | ||
76 | + <h2 id="navbar">参数说明</h2> | ||
77 | + </div> | ||
78 | + | ||
79 | + <div class="bs-component"> | ||
80 | + <table class="table table-condensed table-hover"> | ||
81 | + <thead> | ||
82 | + <tr> | ||
83 | + <th>参数</th> | ||
84 | + <th>释义</th> | ||
85 | + </tr> | ||
86 | + </thead> | ||
87 | + <tbody> | ||
88 | + <tr> | ||
89 | + <td>data-input-id</td> | ||
90 | + <td>填充地址的文本框ID</td> | ||
91 | + </tr> | ||
92 | + <tr> | ||
93 | + <td>data-lng-id</td> | ||
94 | + <td>填充经度的文本框ID</td> | ||
95 | + </tr> | ||
96 | + <tr> | ||
97 | + <td>data-lat-id</td> | ||
98 | + <td>填充纬度的文本框ID</td> | ||
99 | + </tr> | ||
100 | + </tbody> | ||
101 | + </table> | ||
102 | + </div> | ||
103 | + | ||
104 | + </div> | ||
105 | + </div> | ||
106 | + </div> | ||
107 | + | ||
108 | +</div> | ||
109 | +<script type="text/javascript"> | ||
110 | + var require = { | ||
111 | + config: {$config | json_encode | ||
112 | + } | ||
113 | + } | ||
114 | + ; | ||
115 | +</script> | ||
116 | + | ||
117 | +<script> | ||
118 | + require.callback = function () { | ||
119 | + define('addons/address', ['jquery', 'bootstrap', 'frontend', 'template'], function ($, undefined, Frontend, Template) { | ||
120 | + var Controller = { | ||
121 | + index: function () { | ||
122 | + ; | ||
123 | + } | ||
124 | + }; | ||
125 | + return Controller; | ||
126 | + }); | ||
127 | + define('lang', function () { | ||
128 | + return []; | ||
129 | + }); | ||
130 | + } | ||
131 | +</script> | ||
132 | + | ||
133 | + | ||
134 | +<script src="__CDN__/assets/js/require.min.js" data-main="__CDN__/assets/js/require-frontend.min.js?v={$site.version}"></script> | ||
135 | +</body> | ||
136 | +</html> |
addons/address/view/index/tencent.html
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html> | ||
3 | +<head> | ||
4 | + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
5 | + <title>地址选择器</title> | ||
6 | + <link rel="stylesheet" href="__CDN__/assets/css/bootstrap.min.css"/> | ||
7 | + <link rel="stylesheet" href="__CDN__/assets/css/fastadmin.min.css"/> | ||
8 | + <link rel="stylesheet" href="__CDN__/assets/libs/font-awesome/css/font-awesome.min.css"/> | ||
9 | + <style type="text/css"> | ||
10 | + body { | ||
11 | + margin: 0; | ||
12 | + padding: 0; | ||
13 | + } | ||
14 | + | ||
15 | + #container { | ||
16 | + position: absolute; | ||
17 | + left: 0; | ||
18 | + top: 0; | ||
19 | + right: 0; | ||
20 | + bottom: 0; | ||
21 | + } | ||
22 | + | ||
23 | + .confirm { | ||
24 | + position: absolute; | ||
25 | + bottom: 30px; | ||
26 | + right: 4%; | ||
27 | + z-index: 99; | ||
28 | + height: 50px; | ||
29 | + width: 50px; | ||
30 | + line-height: 50px; | ||
31 | + font-size: 15px; | ||
32 | + text-align: center; | ||
33 | + background-color: white; | ||
34 | + background: #1ABC9C; | ||
35 | + color: white; | ||
36 | + border: none; | ||
37 | + cursor: pointer; | ||
38 | + border-radius: 50%; | ||
39 | + } | ||
40 | + | ||
41 | + .search { | ||
42 | + position: absolute; | ||
43 | + width: 400px; | ||
44 | + top: 0; | ||
45 | + left: 50%; | ||
46 | + padding: 5px; | ||
47 | + margin-left: -200px; | ||
48 | + } | ||
49 | + </style> | ||
50 | +</head> | ||
51 | +<body> | ||
52 | +<div class="search"> | ||
53 | + <div class="input-group"> | ||
54 | + <input type="text" id="place" name="q" class="form-control" placeholder="输入地点"/> | ||
55 | + <span class="input-group-btn"> | ||
56 | + <button type="submit" name="search" id="search-btn" class="btn btn-success"> | ||
57 | + <i class="fa fa-search"></i> | ||
58 | + </button> | ||
59 | + </span> | ||
60 | + </div> | ||
61 | +</div> | ||
62 | +<div class="confirm">确定</div> | ||
63 | +<div id="container"></div> | ||
64 | +<script charset="utf-8" src="//map.qq.com/api/js?v=2.exp&libraries=place&key={$config.tencentkey|default=''}"></script> | ||
65 | +<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script> | ||
66 | +<script type="text/javascript"> | ||
67 | + $(function () { | ||
68 | + var map, marker, geocoder, infoWin, searchService, address = null; | ||
69 | + var init = function () { | ||
70 | + var center = new qq.maps.LatLng({$lat}, {$lng}); | ||
71 | + map = new qq.maps.Map(document.getElementById('container'), { | ||
72 | + center: center, | ||
73 | + zoom: parseInt("{$config.zoom}") | ||
74 | + }); | ||
75 | + //初始化marker | ||
76 | + initmarker(center); | ||
77 | + | ||
78 | + //实例化信息窗口 | ||
79 | + infoWin = new qq.maps.InfoWindow({ | ||
80 | + map: map | ||
81 | + }); | ||
82 | + geocoder = new qq.maps.Geocoder({ | ||
83 | + complete: function (result) { | ||
84 | + infoWin.open(); | ||
85 | + address = result.detail.addressComponents.province + | ||
86 | + result.detail.addressComponents.city + | ||
87 | + result.detail.addressComponents.district; | ||
88 | + if (result.detail.addressComponents.streetNumber == '') { | ||
89 | + address += result.detail.addressComponents.street; | ||
90 | + } else { | ||
91 | + address += result.detail.addressComponents.streetNumber; | ||
92 | + } | ||
93 | + infoWin.setContent(address); | ||
94 | + infoWin.setPosition(result.detail.location); | ||
95 | + } | ||
96 | + }); | ||
97 | + //显示当前marker的位置信息窗口 | ||
98 | + geocoder.getAddress(center); | ||
99 | + | ||
100 | + var latlngBounds = new qq.maps.LatLngBounds(); | ||
101 | + //查询poi类信息 | ||
102 | + searchService = new qq.maps.SearchService({ | ||
103 | + complete: function (results) { | ||
104 | + var pois = results.detail.pois; | ||
105 | + for (var i = 0, l = pois.length; i < l; i++) { | ||
106 | + var poi = pois[i]; | ||
107 | + latlngBounds.extend(poi.latLng); | ||
108 | + initmarker(poi.latLng); | ||
109 | + //显示当前marker的位置信息窗口 | ||
110 | + geocoder.getAddress(poi.latLng); | ||
111 | + } | ||
112 | + map.fitBounds(latlngBounds); | ||
113 | + } | ||
114 | + }); | ||
115 | + //实例化自动完成 | ||
116 | + var ap = new qq.maps.place.Autocomplete(document.getElementById('place')); | ||
117 | + //添加监听事件 | ||
118 | + qq.maps.event.addListener(ap, "confirm", function (res) { | ||
119 | + searchKeyword(); | ||
120 | + }); | ||
121 | + qq.maps.event.addListener( | ||
122 | + map, | ||
123 | + 'click', | ||
124 | + function (event) { | ||
125 | + try { | ||
126 | + infoWin.setContent('<div style="text-align:center;white-space:nowrap;margin:10px;">加载中</div>'); | ||
127 | + var latLng = event.latLng, | ||
128 | + lat = latLng.getLat().toFixed(5), | ||
129 | + lng = latLng.getLng().toFixed(5); | ||
130 | + var location = new qq.maps.LatLng(lat, lng); | ||
131 | + //调用获取位置方法 | ||
132 | + geocoder.getAddress(location); | ||
133 | + infoWin.setPosition(location); | ||
134 | + marker.setPosition(location); | ||
135 | + } catch (e) { | ||
136 | + console.log(e); | ||
137 | + } | ||
138 | + } | ||
139 | + ); | ||
140 | + }; | ||
141 | + | ||
142 | + //实例化marker和监听拖拽结束事件 | ||
143 | + var initmarker = function (latLng) { | ||
144 | + marker = new qq.maps.Marker({ | ||
145 | + map: map, | ||
146 | + position: latLng, | ||
147 | + draggable: true, | ||
148 | + title: '拖动图标选择位置' | ||
149 | + }); | ||
150 | + //监听拖拽结束 | ||
151 | + qq.maps.event.addListener(marker, 'dragend', function (event) { | ||
152 | + var latLng = event.latLng, | ||
153 | + lat = latLng.getLat().toFixed(5), | ||
154 | + lng = latLng.getLng().toFixed(5); | ||
155 | + var location = new qq.maps.LatLng(lat, lng); | ||
156 | + //调用获取位置方法 | ||
157 | + geocoder.getAddress(location); | ||
158 | + }); | ||
159 | + }; | ||
160 | + var close = function (data) { | ||
161 | + var index = parent.Layer.getFrameIndex(window.name); | ||
162 | + var callback = parent.$("#layui-layer" + index).data("callback"); | ||
163 | + //再执行关闭 | ||
164 | + parent.Layer.close(index); | ||
165 | + //再调用回传函数 | ||
166 | + if (typeof callback === 'function') { | ||
167 | + callback.call(undefined, data); | ||
168 | + } | ||
169 | + }; | ||
170 | + | ||
171 | + //执行搜索方法 | ||
172 | + var searchKeyword = function () { | ||
173 | + searchService.clear();//先清除 | ||
174 | + marker.setMap(null); | ||
175 | + infoWin.close(); | ||
176 | + var keyword = $("#place").val(); | ||
177 | + searchService.setLocation("{$location}");//设置默认检索范围(默认为全国),类型可以是坐标或指定的城市名称。 | ||
178 | + searchService.setPageIndex(0);//设置检索的特定页数。 | ||
179 | + searchService.setPageCapacity(1);//设置每页返回的结果数量。 | ||
180 | + searchService.search(keyword);//开始查询 | ||
181 | + }; | ||
182 | + | ||
183 | + //点击确定后执行回调赋值 | ||
184 | + $(document).on('click', '.confirm', function () { | ||
185 | + var as = marker.getPosition(); | ||
186 | + var x = as.getLat().toFixed(5); | ||
187 | + var y = as.getLng().toFixed(5); | ||
188 | + var zoom = map.getZoom(); | ||
189 | + var data = {lat: x, lng: y, zoom: zoom, address: address}; | ||
190 | + close(data); | ||
191 | + }); | ||
192 | + | ||
193 | + //点击搜索按钮 | ||
194 | + $(document).on('click', '#search-btn', function () { | ||
195 | + if ($("#place").val() == '') | ||
196 | + return; | ||
197 | + searchKeyword(); | ||
198 | + }); | ||
199 | + | ||
200 | + init(); | ||
201 | + }); | ||
202 | +</script> | ||
203 | +</body> | ||
204 | +</html> |
@@ -121,7 +121,6 @@ class Classification extends Api | @@ -121,7 +121,6 @@ class Classification extends Api | ||
121 | 121 | ||
122 | /** | 122 | /** |
123 | * @ApiTitle (商品规格) | 123 | * @ApiTitle (商品规格) |
124 | - * @ApiSummary (分类按钮页面右侧商品列表 初次点击分类页面可不传分类id值) | ||
125 | * @ApiMethod (POST) | 124 | * @ApiMethod (POST) |
126 | * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") | 125 | * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") |
127 | * @ApiParams (name=goods_id, type=integer, required=true, description="商品id") | 126 | * @ApiParams (name=goods_id, type=integer, required=true, description="商品id") |
@@ -130,6 +129,7 @@ class Classification extends Api | @@ -130,6 +129,7 @@ class Classification extends Api | ||
130 | 'msg':'返回成功' | 129 | 'msg':'返回成功' |
131 | 'data':{ | 130 | 'data':{ |
132 | // 规格组合完毕的列表 | 131 | // 规格组合完毕的列表 |
132 | + // 如果sku是空数组 为单规格商品 只需要用list的值 | ||
133 | "list": [ | 133 | "list": [ |
134 | { | 134 | { |
135 | "goods_spec_id": 103, | 135 | "goods_spec_id": 103, |
@@ -137,7 +137,7 @@ class Classification extends Api | @@ -137,7 +137,7 @@ class Classification extends Api | ||
137 | "goods_no": "SNHW001", | 137 | "goods_no": "SNHW001", |
138 | "goods_price": "4499.00", | 138 | "goods_price": "4499.00", |
139 | "line_price": "0.00", | 139 | "line_price": "0.00", |
140 | - "stock_num": 941, | 140 | + "stock_num": 941, 库存 |
141 | "goods_sales": 58, | 141 | "goods_sales": 58, |
142 | "goods_weight": 500, | 142 | "goods_weight": 500, |
143 | "spec_sku_id": "44_46", // 搜索字段 组合sku里面的id搜索 从小到大排序 | 143 | "spec_sku_id": "44_46", // 搜索字段 组合sku里面的id搜索 从小到大排序 |
@@ -64,6 +64,86 @@ class Goods extends Api | @@ -64,6 +64,86 @@ class Goods extends Api | ||
64 | $this->success('商品详情',$goods); | 64 | $this->success('商品详情',$goods); |
65 | } | 65 | } |
66 | 66 | ||
67 | + | ||
68 | + /** | ||
69 | + * @ApiTitle (商品规格) | ||
70 | + * @ApiMethod (POST) | ||
71 | + * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") | ||
72 | + * @ApiParams (name=goods_id, type=integer, required=true, description="商品id") | ||
73 | + * @ApiReturn ({ | ||
74 | + 'code':'1', | ||
75 | + 'msg':'返回成功' | ||
76 | + 'data':{ | ||
77 | + // 规格组合完毕的列表 | ||
78 | + "list": [ | ||
79 | + { | ||
80 | + "goods_spec_id": 103, | ||
81 | + "goods_id": 22, | ||
82 | + "goods_no": "SNHW001", | ||
83 | + "goods_price": "4499.00", | ||
84 | + "line_price": "0.00", | ||
85 | + "stock_num": 941, | ||
86 | + "goods_sales": 58, | ||
87 | + "goods_weight": 500, | ||
88 | + "spec_sku_id": "44_46", // 搜索字段 组合sku里面的id搜索 从小到大排序 | ||
89 | + "spec_image": "", | ||
90 | + "create_time": 1542784591, | ||
91 | + "update_time": 1543242861 | ||
92 | + } | ||
93 | + ], | ||
94 | + // 规格展示的列表 | ||
95 | + "sku": [ | ||
96 | + { | ||
97 | + "name": "颜色", | ||
98 | + "second": [ | ||
99 | + { | ||
100 | + "id": 44, | ||
101 | + "name": "亮黑色" | ||
102 | + } | ||
103 | + ] | ||
104 | + }, | ||
105 | + { | ||
106 | + "name": "内存", | ||
107 | + "second": [ | ||
108 | + { | ||
109 | + "id": 46, | ||
110 | + "name": "6GB+64GB" | ||
111 | + } | ||
112 | + ] | ||
113 | + } | ||
114 | + ] | ||
115 | + } | ||
116 | + }) | ||
117 | + */ | ||
118 | + public function goodsSku() | ||
119 | + { | ||
120 | + $goods_id = $this->request->post('goods_id'); | ||
121 | + $goodsspecrelmodel = new GoodsSpecRel(); | ||
122 | + $list = $goodsspecrelmodel | ||
123 | + ->where('goods_id',$goods_id) | ||
124 | + ->select(); | ||
125 | + $array = []; | ||
126 | + foreach ($list as $key => $value){ | ||
127 | + if (!isset($array[$value['spec_id']])){ | ||
128 | + $array[$value['spec_id']]['name'] = Db::name('litestore_spec') | ||
129 | + ->where('id',$value['spec_id']) | ||
130 | + ->value('spec_name'); | ||
131 | + } | ||
132 | + $spec_value =Db::name('litestore_spec_value') | ||
133 | + ->where('id',$value['spec_value_id']) | ||
134 | + ->value('spec_value'); | ||
135 | + $array[$value['spec_id']]['second'][] = [ | ||
136 | + 'id' => $value['spec_value_id'], | ||
137 | + 'name' => $spec_value | ||
138 | + ]; | ||
139 | + } | ||
140 | + $array = array_values($array); | ||
141 | + $goods_spec = GoodsSpec::all(['goods_id'=>$goods_id]); | ||
142 | + $this->success('商品规格',['list'=>$goods_spec,'sku'=>$array]); | ||
143 | + } | ||
144 | + | ||
145 | + | ||
146 | + | ||
67 | /** | 147 | /** |
68 | * @ApiTitle (商品详情页评价) | 148 | * @ApiTitle (商品详情页评价) |
69 | * @ApiMethod (POST) | 149 | * @ApiMethod (POST) |
application/api/controller/Order.php
0 → 100644
1 | +<?php | ||
2 | + | ||
3 | + | ||
4 | +namespace app\api\controller; | ||
5 | + | ||
6 | + | ||
7 | +use app\api\model\GoodsSpec; | ||
8 | +use app\api\model\SpecValue; | ||
9 | +use app\common\controller\Api; | ||
10 | + | ||
11 | +class Order extends Api | ||
12 | +{ | ||
13 | + protected $noNeedLogin = ['*']; | ||
14 | + protected $noNeedRight = ['*']; | ||
15 | + | ||
16 | + /** | ||
17 | + * @ApiTitle (下单页面) | ||
18 | + * @ApiSummary ([{"goods_id":22,"goods_sku_id":106,"number":2},{"goods_id":23,"goods_sku_id":66,"number":2}]) | ||
19 | + * @ApiMethod (POST) | ||
20 | + * @ApiHeaders (name=token, type=string, required=true, description="请求的Token") | ||
21 | + * @ApiParams (name="data_json", type="string", required=true, description="下单的商品json数据") | ||
22 | + * @ApiParams (name="goods_id", type="integer", required=false, description="商品id 此值不传 json数组注释用") | ||
23 | + * @ApiParams (name="goods_sku_id", type="integer", required=false, description="规格id 此值不传 json数组注释用") | ||
24 | + * @ApiParams (name="number", type="integer", required=false, description="购买数量 此值不传 json数组注释用") | ||
25 | + * @ApiReturn ({ | ||
26 | + 'code':'1', | ||
27 | + 'msg':'返回成功' | ||
28 | + }) | ||
29 | + */ | ||
30 | + public function orderCalculation() | ||
31 | + { | ||
32 | + $json = $this->request->post('data_json'); | ||
33 | + if (!$json) $this->error('data_json参数不能为空'); | ||
34 | + $json = '[{"goods_id":22,"goods_sku_id":106,"number":2},{"goods_id":23,"goods_sku_id":66,"number":2}]'; | ||
35 | + $data = json_decode($json,true); | ||
36 | + $goodsmodel = new \app\api\model\Goods(); | ||
37 | + $skumodel = new GoodsSpec(); | ||
38 | + $specmodel = new SpecValue(); | ||
39 | + $goods_array = []; | ||
40 | + $sum_price = 0; | ||
41 | + foreach ($data as $key => $value){ | ||
42 | + if (!is_numeric($value['goods_id']) || !is_numeric($value['goods_sku_id']) || !is_numeric($value['number'])){ | ||
43 | + $this->error('参数不合法'); | ||
44 | + } | ||
45 | + $goods = $goodsmodel->where('goods_id',$value['goods_id'])->field('goods_id,goods_name,image,spec_type')->find(); | ||
46 | + if (!$goods) $this->error('商品不存在'); | ||
47 | + $sku = $skumodel->where('goods_spec_id',$value['goods_sku_id']) | ||
48 | + ->field('goods_spec_id,spec_sku_id,goods_price')->find(); | ||
49 | + if (!$sku) $this->error('商品规格不存在'); | ||
50 | + $goods['sku_id'] = $sku['goods_spec_id']; | ||
51 | + $goods['sku_price'] = $sku['goods_price']; | ||
52 | + if ($goods['spec_type'] == 10){ | ||
53 | + $goods['sku_name'] =''; | ||
54 | + }else{ | ||
55 | + $ids = explode('_',$sku['spec_sku_id']); | ||
56 | + $sku_name = $specmodel->whereIn('id',$ids)->column('spec_value'); | ||
57 | + $goods['sku_name'] = implode(' ',$sku_name); | ||
58 | + } | ||
59 | + $goods['number'] = $value['number']; | ||
60 | + $goods_array[] = $goods; | ||
61 | + $sum_price = bcadd($sum_price,bcmul($sku['goods_price'],$value['number'],2),2); | ||
62 | + } | ||
63 | + $this->success('下单页详情',['list'=>$goods_array,'price'=>$sum_price]); | ||
64 | + } | ||
65 | +} |
@@ -8,6 +8,7 @@ use app\common\library\Sms; | @@ -8,6 +8,7 @@ use app\common\library\Sms; | ||
8 | use fast\Http; | 8 | use fast\Http; |
9 | use fast\Random; | 9 | use fast\Random; |
10 | use think\Config; | 10 | use think\Config; |
11 | +use think\Db; | ||
11 | use think\Validate; | 12 | use think\Validate; |
12 | 13 | ||
13 | /** | 14 | /** |
@@ -15,7 +16,7 @@ use think\Validate; | @@ -15,7 +16,7 @@ use think\Validate; | ||
15 | */ | 16 | */ |
16 | class User extends Api | 17 | class User extends Api |
17 | { | 18 | { |
18 | - protected $noNeedLogin = ['login', 'mobilelogin', 'register', 'resetpwd', 'changeemail', 'changemobile', 'third']; | 19 | + protected $noNeedLogin = ['third']; |
19 | protected $noNeedRight = '*'; | 20 | protected $noNeedRight = '*'; |
20 | 21 | ||
21 | public function _initialize() | 22 | public function _initialize() |
@@ -30,23 +31,28 @@ class User extends Api | @@ -30,23 +31,28 @@ class User extends Api | ||
30 | 31 | ||
31 | /** | 32 | /** |
32 | * 会员中心 | 33 | * 会员中心 |
34 | + * @ApiReturn ( | ||
35 | + * data:{ | ||
36 | + * nickname 昵称 | ||
37 | + * avatar 头像 | ||
38 | + * pay 待支付 | ||
39 | + * wait_send 待发货 | ||
40 | + * wait_collect 待收货 | ||
41 | + * wait_comment 待评价 | ||
42 | + * } | ||
43 | + * ) | ||
33 | */ | 44 | */ |
34 | public function index() | 45 | public function index() |
35 | { | 46 | { |
36 | - $this->success('', ['welcome' => $this->auth->nickname]); | ||
37 | - } | ||
38 | - | ||
39 | - /** | ||
40 | - * 退出登录 | ||
41 | - * @ApiMethod (POST) | ||
42 | - */ | ||
43 | - public function logout() | ||
44 | - { | ||
45 | - if (!$this->request->isPost()) { | ||
46 | - $this->error(__('Invalid parameters')); | ||
47 | - } | ||
48 | - $this->auth->logout(); | ||
49 | - $this->success(__('Logout successful')); | 47 | + $data = []; |
48 | + $data['nickname'] = $this->auth->nickname; | ||
49 | + $data['avatar'] = cdnurl($this->auth->avatar,true); | ||
50 | + $data['mobile'] = $this->auth->mobile; | ||
51 | + $data['pay'] = Db::name('litestore_order')->where('user_id',$this->auth->id)->where('pay_status','10')->count(); | ||
52 | + $data['wait_send'] = Db::name('litestore_order')->where('user_id',$this->auth->id)->where('freight_status','10')->count(); | ||
53 | + $data['wait_collect'] = Db::name('litestore_order')->where('user_id',$this->auth->id)->where('receipt_status','10')->count(); | ||
54 | + $data['wait_comment'] = Db::name('litestore_order')->where('user_id',$this->auth->id)->where('receipt_status','20')->count(); | ||
55 | + $this->success('会员中心', ['welcome' => $this->auth->nickname]); | ||
50 | } | 56 | } |
51 | 57 | ||
52 | /** | 58 | /** |
@@ -54,106 +60,28 @@ class User extends Api | @@ -54,106 +60,28 @@ class User extends Api | ||
54 | * | 60 | * |
55 | * @ApiMethod (POST) | 61 | * @ApiMethod (POST) |
56 | * @param string $avatar 头像地址 | 62 | * @param string $avatar 头像地址 |
57 | - * @param string $username 用户名 | 63 | + * @param string $mobile 联系方式 |
58 | * @param string $nickname 昵称 | 64 | * @param string $nickname 昵称 |
59 | - * @param string $bio 个人简介 | ||
60 | */ | 65 | */ |
61 | public function profile() | 66 | public function profile() |
62 | { | 67 | { |
63 | $user = $this->auth->getUser(); | 68 | $user = $this->auth->getUser(); |
64 | - $username = $this->request->post('username'); | 69 | + $mobile = $this->request->post('mobile'); |
65 | $nickname = $this->request->post('nickname'); | 70 | $nickname = $this->request->post('nickname'); |
66 | - $bio = $this->request->post('bio'); | ||
67 | $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars'); | 71 | $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars'); |
68 | - if ($username) { | ||
69 | - $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find(); | ||
70 | - if ($exists) { | ||
71 | - $this->error(__('Username already exists')); | ||
72 | - } | ||
73 | - $user->username = $username; | 72 | + if ($mobile) { |
73 | + $user->mobile = $mobile; | ||
74 | } | 74 | } |
75 | if ($nickname) { | 75 | if ($nickname) { |
76 | - $exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find(); | ||
77 | - if ($exists) { | ||
78 | - $this->error(__('Nickname already exists')); | ||
79 | - } | ||
80 | $user->nickname = $nickname; | 76 | $user->nickname = $nickname; |
81 | } | 77 | } |
82 | - $user->bio = $bio; | 78 | + if ($avatar) { |
83 | $user->avatar = $avatar; | 79 | $user->avatar = $avatar; |
84 | - $user->save(); | ||
85 | - $this->success(); | ||
86 | - } | ||
87 | - | ||
88 | - /** | ||
89 | - * 修改邮箱 | ||
90 | - * | ||
91 | - * @ApiMethod (POST) | ||
92 | - * @param string $email 邮箱 | ||
93 | - * @param string $captcha 验证码 | ||
94 | - */ | ||
95 | - public function changeemail() | ||
96 | - { | ||
97 | - $user = $this->auth->getUser(); | ||
98 | - $email = $this->request->post('email'); | ||
99 | - $captcha = $this->request->post('captcha'); | ||
100 | - if (!$email || !$captcha) { | ||
101 | - $this->error(__('Invalid parameters')); | ||
102 | } | 80 | } |
103 | - if (!Validate::is($email, "email")) { | ||
104 | - $this->error(__('Email is incorrect')); | ||
105 | - } | ||
106 | - if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) { | ||
107 | - $this->error(__('Email already exists')); | ||
108 | - } | ||
109 | - $result = Ems::check($email, $captcha, 'changeemail'); | ||
110 | - if (!$result) { | ||
111 | - $this->error(__('Captcha is incorrect')); | ||
112 | - } | ||
113 | - $verification = $user->verification; | ||
114 | - $verification->email = 1; | ||
115 | - $user->verification = $verification; | ||
116 | - $user->email = $email; | ||
117 | $user->save(); | 81 | $user->save(); |
118 | - | ||
119 | - Ems::flush($email, 'changeemail'); | ||
120 | $this->success(); | 82 | $this->success(); |
121 | } | 83 | } |
122 | 84 | ||
123 | - /** | ||
124 | - * 修改手机号 | ||
125 | - * | ||
126 | - * @ApiMethod (POST) | ||
127 | - * @param string $mobile 手机号 | ||
128 | - * @param string $captcha 验证码 | ||
129 | - */ | ||
130 | - public function changemobile() | ||
131 | - { | ||
132 | - $user = $this->auth->getUser(); | ||
133 | - $mobile = $this->request->post('mobile'); | ||
134 | - $captcha = $this->request->post('captcha'); | ||
135 | - if (!$mobile || !$captcha) { | ||
136 | - $this->error(__('Invalid parameters')); | ||
137 | - } | ||
138 | - if (!Validate::regex($mobile, "^1\d{10}$")) { | ||
139 | - $this->error(__('Mobile is incorrect')); | ||
140 | - } | ||
141 | - if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) { | ||
142 | - $this->error(__('Mobile already exists')); | ||
143 | - } | ||
144 | - $result = Sms::check($mobile, $captcha, 'changemobile'); | ||
145 | - if (!$result) { | ||
146 | - $this->error(__('Captcha is incorrect')); | ||
147 | - } | ||
148 | - $verification = $user->verification; | ||
149 | - $verification->mobile = 1; | ||
150 | - $user->verification = $verification; | ||
151 | - $user->mobile = $mobile; | ||
152 | - $user->save(); | ||
153 | - | ||
154 | - Sms::flush($mobile, 'changemobile'); | ||
155 | - $this->success(); | ||
156 | - } | ||
157 | 85 | ||
158 | /** | 86 | /** |
159 | * 第三方登录 | 87 | * 第三方登录 |
@@ -481,3 +481,27 @@ if (!function_exists('check_ip_allowed')) { | @@ -481,3 +481,27 @@ if (!function_exists('check_ip_allowed')) { | ||
481 | } | 481 | } |
482 | } | 482 | } |
483 | } | 483 | } |
484 | + | ||
485 | +if (!function_exists('getDistance')) { | ||
486 | + function getDistance($lat1, $lng1, $lat2, $lng2) | ||
487 | + { | ||
488 | + $EARTH_RADIUS = 6378.137; | ||
489 | + $radLat1 = rad($lat1); | ||
490 | + $radLat2 = rad($lat2); | ||
491 | + $a = $radLat1 - $radLat2; | ||
492 | + $b = rad($lng1) - rad($lng2); | ||
493 | + $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))); | ||
494 | + $s = $s * $EARTH_RADIUS; | ||
495 | + $s = round($s * 10000) / 10000; | ||
496 | + | ||
497 | + return $s; | ||
498 | + } | ||
499 | +} | ||
500 | + | ||
501 | +if (!function_exists('rad')) { | ||
502 | + | ||
503 | + function rad($d) | ||
504 | + { | ||
505 | + return $d * 3.1415926 / 180.0; | ||
506 | + } | ||
507 | +} |
1 | define([], function () { | 1 | define([], function () { |
2 | - require.config({ | 2 | + require([], function () { |
3 | + //绑定data-toggle=addresspicker属性点击事件 | ||
4 | + | ||
5 | + $(document).on('click', "[data-toggle='addresspicker']", function () { | ||
6 | + var that = this; | ||
7 | + var callback = $(that).data('callback'); | ||
8 | + var input_id = $(that).data("input-id") ? $(that).data("input-id") : ""; | ||
9 | + var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : ""; | ||
10 | + var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : ""; | ||
11 | + var lat = lat_id ? $("#" + lat_id).val() : ''; | ||
12 | + var lng = lng_id ? $("#" + lng_id).val() : ''; | ||
13 | + var url = "/addons/address/index/select"; | ||
14 | + url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng : ''; | ||
15 | + Fast.api.open(url, '位置选择', { | ||
16 | + callback: function (res) { | ||
17 | + input_id && $("#" + input_id).val(res.address).trigger("change"); | ||
18 | + lat_id && $("#" + lat_id).val(res.lat).trigger("change"); | ||
19 | + lng_id && $("#" + lng_id).val(res.lng).trigger("change"); | ||
20 | + try { | ||
21 | + //执行回调函数 | ||
22 | + if (typeof callback === 'function') { | ||
23 | + callback.call(that, res); | ||
24 | + } | ||
25 | + } catch (e) { | ||
26 | + | ||
27 | + } | ||
28 | + } | ||
29 | + }); | ||
30 | + }); | ||
31 | +}); | ||
32 | + | ||
33 | +require.config({ | ||
3 | paths: { | 34 | paths: { |
4 | 'litestorefreight_delivery': '../addons/litestore/js/litestorefreight_delivery', | 35 | 'litestorefreight_delivery': '../addons/litestore/js/litestorefreight_delivery', |
5 | 'litestorefreight_regionalChoice': '../addons/litestore/js/litestorefreight_regionalChoice', | 36 | 'litestorefreight_regionalChoice': '../addons/litestore/js/litestorefreight_regionalChoice', |
-
请 注册 或 登录 后发表评论