share copy.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <template>
  2. </template>
  3. <script>
  4. export default {
  5. data() {
  6. return {
  7. imageUrl: 'https://example.com/path/to/your/image.jpg' // 后端提供的图片地址
  8. };
  9. },
  10. methods: {
  11. // 显示分享菜单
  12. showShareMenu() {
  13. uni.showActionSheet({
  14. itemList: ['下载图片'],
  15. success: (res) => {
  16. if (res.tapIndex === 0) {
  17. this.downloadImage(); // 点击“下载图片”
  18. }
  19. }
  20. });
  21. },
  22. // 下载图片
  23. downloadImage() {
  24. // #ifdef H5
  25. this.downloadImageForH5();
  26. // #endif
  27. // #ifdef APP-PLUS
  28. this.downloadImageForApp();
  29. // #endif
  30. },
  31. // H5 环境下载图片
  32. downloadImageForH5() {
  33. // 创建一个隐藏的 <a> 标签
  34. const link = document.createElement('a');
  35. link.href = this.imageUrl;
  36. link.download = 'image.jpg'; // 设置下载文件名
  37. document.body.appendChild(link);
  38. link.click(); // 触发下载
  39. document.body.removeChild(link);
  40. // 提示用户手动保存
  41. uni.showToast({
  42. title: '图片已下载,请手动保存到相册。',
  43. icon: 'none'
  44. });
  45. },
  46. // APP 环境下载图片
  47. downloadImageForApp() {
  48. uni.showLoading({
  49. title: '下载中...',
  50. mask: true
  51. });
  52. // 下载图片
  53. uni.downloadFile({
  54. url: this.imageUrl, // 图片地址
  55. success: (res) => {
  56. if (res.statusCode === 200) {
  57. const tempFilePath = res.tempFilePath; // 下载后的临时文件路径
  58. this.saveImageToAlbum(tempFilePath); // 保存到相册
  59. } else {
  60. uni.showToast({
  61. title: '下载失败',
  62. icon: 'none'
  63. });
  64. }
  65. },
  66. fail: (err) => {
  67. console.error('下载失败:', err);
  68. uni.showToast({
  69. title: '下载失败',
  70. icon: 'none'
  71. });
  72. },
  73. complete: () => {
  74. uni.hideLoading();
  75. }
  76. });
  77. },
  78. // 保存图片到相册(APP 环境)
  79. saveImageToAlbum(tempFilePath) {
  80. // 检查权限(仅 Android 需要)
  81. // #ifdef APP-PLUS
  82. if (uni.getSystemInfoSync().platform === 'android') {
  83. uni.authorize({
  84. scope: 'scope.writePhotosAlbum',
  85. success: () => {
  86. this.saveImage(tempFilePath);
  87. },
  88. fail: () => {
  89. // 无权限,提示用户去设置
  90. uni.showModal({
  91. title: '提示',
  92. content: '需要相册权限才能保存图片,是否去设置?',
  93. success: (res) => {
  94. if (res.confirm) {
  95. uni.openSetting(); // 打开设置页面
  96. }
  97. }
  98. });
  99. }
  100. });
  101. } else {
  102. this.saveImage(tempFilePath);
  103. }
  104. // #endif
  105. },
  106. saveImage(tempFilePath) {
  107. uni.saveImageToPhotosAlbum({
  108. filePath: tempFilePath,
  109. success: () => {
  110. uni.showToast({
  111. title: '保存成功',
  112. icon: 'success'
  113. });
  114. },
  115. fail: (err) => {
  116. console.error('保存失败:', err);
  117. uni.showToast({
  118. title: '保存失败',
  119. icon: 'none'
  120. });
  121. }
  122. });
  123. }
  124. }
  125. };
  126. </script>
  127. <style>
  128. button {
  129. margin-top: 20px;
  130. padding: 10px 20px;
  131. background-color: #007AFF;
  132. color: white;
  133. border-radius: 5px;
  134. }
  135. </style>
  136. <template>
  137. <view class="map-popup-box">
  138. <view class="icon-title-navBar-box">
  139. <view @click="goUpPage" class="nav-bar-icon"></view>
  140. <text class="nav-bar-title">选择地址</text>
  141. </view>
  142. <!-- 城市选择器 -->
  143. <view class="city-picker-box">
  144. <picker mode="region" @change="handleCityChange">
  145. <view class="city-picker">
  146. <text>{{ selectedCity }}</text>
  147. <uni-icons type="arrowdown" size="16" color="#666"></uni-icons>
  148. </view>
  149. </picker>
  150. </view>
  151. <!-- 查询地址 -->
  152. <view class="phone-search-box">
  153. <input class="search-input" placeholder="请输入地址" v-model="data.keyword" />
  154. <view class="search-icon" @click="handleClick">
  155. <uni-icons type="search" size="24" color="#fff"></uni-icons>
  156. </view>
  157. </view>
  158. <map style="width: 100%; height: 300px;" :latitude="data.latitude" :longitude="data.longitude"
  159. :markers="data.covers" :show-location="true"> </map>
  160. <!-- 搜索结果 -->
  161. <view v-if="result" class="map-card-list">
  162. <view v-for="(item,index) in result.data" :key="index" @click="xuanzeAdress(item)" class="map-card-box">
  163. <view>
  164. <view class="map-card-title"><text v-if="index==0" class="dqwz-text">当前位置</text>{{item.title}}</view>
  165. <view class="map-card-address">{{item.address}}</view>
  166. </view>
  167. <icon class="map-active-icon" v-if="index==0"></icon>
  168. </view>
  169. </view>
  170. </view>
  171. </template>
  172. <script setup>
  173. import { reactive, ref } from "vue";
  174. import myIcon from "@/static/images/common/markIcon.png";
  175. import { onLoad } from "@dcloudio/uni-app";
  176. import { useCustomMap } from "@/components/customMap/useMap.js";
  177. const emits = defineEmits(['close', 'xuanzeAdress', 'currentWeizhi']);
  178. const { getPositionSearchByKeyword } = useCustomMap();
  179. const result = ref(null);
  180. const selectedCity = ref('选择城市'); // 默认显示“选择城市”
  181. const data = reactive({
  182. keyword: '', // 关键字
  183. latitude: 0, // 纬度
  184. longitude: 0, // 经度
  185. covers: [{ latitude: 0, longitude: 0, iconPath: myIcon, width: 30, height: 30 }]
  186. });
  187. // 城市选择事件
  188. function handleCityChange(e) {
  189. const city = e.detail.value[1]; // 获取选择的城市
  190. selectedCity.value = city;
  191. updateMapCenter(city);
  192. }
  193. // 更新地图中心点
  194. async function updateMapCenter(city) {
  195. const cityLocation = await getCityLocation(city);
  196. if (cityLocation) {
  197. data.latitude = cityLocation.lat;
  198. data.longitude = cityLocation.lng;
  199. data.covers[0].latitude = cityLocation.lat;
  200. data.covers[0].longitude = cityLocation.lng;
  201. // 重新搜索附近的地点
  202. getPositionSearchByKeyword(data.keyword || '公司', `nearby(${cityLocation.lat},${cityLocation.lng},1000)`, onSuccess, onError, {
  203. page: 1,
  204. size: 3,
  205. });
  206. }
  207. }
  208. // 获取城市经纬度
  209. async function getCityLocation(city) {
  210. const url = `https://apis.map.qq.com/ws/geocoder/v1/?address=${city}&key=${Key}`;
  211. try {
  212. const res = await uni.request({ url });
  213. if (res.data && res.data.result && res.data.result.location) {
  214. return res.data.result.location; // 返回经纬度对象 { lat, lng }
  215. }
  216. } catch (err) {
  217. console.error('获取城市位置失败', err);
  218. }
  219. return null;
  220. }
  221. // 其他代码保持不变...
  222. </script>
  223. <style>
  224. .city-picker-box {
  225. padding: 10px;
  226. background-color: #fff;
  227. border-bottom: 1px solid #eee;
  228. }
  229. .city-picker {
  230. display: flex;
  231. align-items: center;
  232. justify-content: space-between;
  233. padding: 10px;
  234. border: 1px solid #ccc;
  235. border-radius: 5px;
  236. }
  237. .city-picker text {
  238. font-size: 16px;
  239. color: #333;
  240. }
  241. </style>