search.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <template>
  2. <view :class="['search-content']">
  3. <view class="search-box">
  4. <view class="search-input-box">
  5. <svg
  6. t="1733904658291"
  7. class="search-icon"
  8. viewBox="0 0 1024 1024"
  9. version="1.1"
  10. xmlns="http://www.w3.org/2000/svg"
  11. p-id="5981"
  12. xmlns:xlink="http://www.w3.org/1999/xlink"
  13. >
  14. <path
  15. d="M174.545 465.455c0-18.619 16.291-34.91 34.91-34.91s34.909 16.291 34.909 34.91c0 121.018 100.072 221.09 221.09 221.09 18.619 0 34.91 16.291 34.91 34.91s-16.291 34.909-34.91 34.909c-160.581 0-290.909-130.328-290.909-290.91z m290.91 360.727c200.145 0 360.727-160.582 360.727-360.727S665.6 104.727 465.455 104.727 104.727 265.31 104.727 465.455 265.31 826.182 465.455 826.182z m323.49-76.8L961.164 921.6c13.963 13.964 13.963 34.91 0 48.873-13.964 13.963-34.91 13.963-48.873 0L737.745 795.927c-74.472 60.51-169.89 97.746-272.29 97.746C228.073 896 34.909 702.836 34.909 465.455S228.073 34.909 465.455 34.909 896 228.073 896 465.455c0 109.381-39.564 209.454-107.055 283.927z"
  16. p-id="5982"
  17. ></path>
  18. </svg>
  19. <input
  20. confirm-type="search"
  21. ref="searchInputRef"
  22. class="search-input"
  23. :auto-blur="true"
  24. type="text"
  25. placeholder="请输入关键字"
  26. v-model="locationName"
  27. @blur="onSearchFocus(true)"
  28. placeholder-class="placeholder"
  29. />
  30. </view>
  31. <view class="search-select">
  32. <view class="select-item" @click.stop="$refs.cityRef.open()">
  33. <text class="item-text one-row">{{
  34. params.codeLabel || "办理区域"
  35. }}</text>
  36. <u-icon
  37. name="arrow-down-fill"
  38. :color="downFillColor"
  39. size="14"
  40. ></u-icon>
  41. </view>
  42. <view class="select-item" @click.stop="$refs.mapTypeRef.open()">
  43. <text class="item-text one-row">{{
  44. params.typeName || "位置类型"
  45. }}</text>
  46. <u-icon
  47. name="arrow-down-fill"
  48. :color="downFillColor"
  49. size="14"
  50. ></u-icon>
  51. </view>
  52. <view class="select-item" @click.stop="$refs.mapAdRef.open()">
  53. <text class="item-text one-row">{{
  54. params.typeName || "高频事项指引"
  55. }}</text>
  56. <u-icon
  57. name="arrow-down-fill"
  58. :color="downFillColor"
  59. size="14"
  60. ></u-icon>
  61. </view>
  62. </view>
  63. </view>
  64. <!-- 选择地址 -->
  65. <city
  66. ref="cityRef"
  67. :code.sync="params.code"
  68. @cityName="(e) => (params.codeLabel = e)"
  69. />
  70. <!-- 选择位置类型 -->
  71. <mapType
  72. ref="mapTypeRef"
  73. :mapTypeId.sync="params.mapTypeId"
  74. @typeName="(e) => (params.typeName = e)"
  75. />
  76. <!-- 选择高频事项指引 -->
  77. <mapAd
  78. ref="mapAdRef"
  79. :mapAdId.sync="params.mapAdId"
  80. @mapAdSelect="mapAdSelect"
  81. />
  82. </view>
  83. </template>
  84. <script>
  85. import { EventBus } from "@/utils/vueBus.js";
  86. import { getLocation } from "@/utils/tool.js";
  87. import $confog from "@/config/index.js";
  88. import { getMapMatterDetail_Api } from "@/api/map.js";
  89. export default {
  90. data() {
  91. return {
  92. locationPower: false,
  93. locationName: undefined,
  94. selfLatitude: undefined,
  95. selfLongitude: undefined,
  96. // selfLatitude: 30.482926,
  97. // selfLongitude: 114.414431,
  98. params: {
  99. code: undefined,
  100. codeLabel: undefined,
  101. mapTypeId: undefined,
  102. typeName: undefined,
  103. },
  104. LocationTimeout: null,
  105. SearchTimeout: null,
  106. type: $confog.type,
  107. downFillColor: "#808080",
  108. getLocationNum: 1,
  109. };
  110. },
  111. created() {
  112. this.type = $confog.type;
  113. this.downFillColor = $confog.type === "H6" ? "#808080" : "#101010";
  114. this.init();
  115. },
  116. mounted() {
  117. EventBus.$on("TianDiTuSearch", (callBack) => {
  118. this.handleSearch(callBack);
  119. }); // 确保在组件销毁前移除事件监听
  120. },
  121. beforeDestroy() {
  122. EventBus.$off("TianDiTuSearch");
  123. },
  124. methods: {
  125. init() {
  126. clearTimeout(this.LocationTimeout);
  127. this.LocationTimeout = null;
  128. this.LocationTimeout = setTimeout(() => {
  129. getLocation()
  130. .then((res) => {
  131. const { longitude, latitude } = res || {};
  132. if (longitude && latitude) {
  133. this.selfLatitude = latitude;
  134. this.selfLongitude = longitude;
  135. clearTimeout(this.LocationTimeout);
  136. this.LocationTimeout = null;
  137. this.onSearchFocus();
  138. this.$store.dispatch("updateUseLocation", {
  139. longitude,
  140. latitude,
  141. });
  142. } else {
  143. this.getLocationNum++;
  144. if (this.getLocationNum <= 5) {
  145. this.init();
  146. }
  147. }
  148. })
  149. .catch((err) => {
  150. this.getLocationNum++;
  151. if (this.getLocationNum <= 5) {
  152. this.init();
  153. }
  154. });
  155. }, 1000);
  156. },
  157. /**
  158. * 获取定位
  159. * 有callBack,着是手动定位,地图会平移调用搜索,所以无需再次搜索
  160. * 没有callBack,则需要手动收索
  161. *
  162. */
  163. handleSearch(callBack) {
  164. try {
  165. uni.showLoading({
  166. mask: true,
  167. });
  168. getLocation()
  169. .then((res) => {
  170. const { longitude, latitude } = res || {};
  171. if (longitude && latitude) {
  172. this.selfLatitude = latitude;
  173. this.selfLongitude = longitude;
  174. }
  175. callBack &&
  176. callBack({ longitude: res.longitude, latitude: res.latitude });
  177. })
  178. .catch((err) => {
  179. if (this.selfLatitude && this.selfLongitude) {
  180. callBack &&
  181. callBack({
  182. longitude: this.selfLatitude,
  183. latitude: this.selfLongitude,
  184. });
  185. } else {
  186. uni.showToast({
  187. title: "获取定位失败",
  188. icon: "none",
  189. });
  190. }
  191. })
  192. .finally(() => {
  193. uni.hideLoading();
  194. });
  195. } catch (error) {
  196. console.log(999977999, error);
  197. //TODO handle the exception
  198. }
  199. },
  200. onSearchFocus(search = false) {
  201. try {
  202. clearTimeout(this.SearchTimeout);
  203. this.SearchTimeout = null;
  204. this.SearchTimeout = setTimeout(() => {
  205. let pms = {};
  206. try {
  207. if (this.params.code) {
  208. pms.areaCode = this.params.code || undefined;
  209. }
  210. pms.mapTypeId = this.params.mapTypeId;
  211. pms.selfLatitude = this.selfLatitude;
  212. pms.selfLongitude = this.selfLongitude;
  213. pms.locationName = this.locationName;
  214. pms.search = search;
  215. } catch (error) {
  216. console.log("定位收索11 error", error);
  217. //TODO handle the exception
  218. }
  219. this.$emit("handleSearch", pms);
  220. }, 150);
  221. } catch (error) {
  222. console.log(999977999, error);
  223. //TODO handle the exception
  224. }
  225. },
  226. getVal() {
  227. return {};
  228. },
  229. mapAdSelect(val) {
  230. const { adId, jumpType, outsideAddress, resourceModelId } = val;
  231. switch (jumpType) {
  232. case 0: //图文
  233. case 1: //图文&视频
  234. uni.navigateTo({
  235. url: "/pages/map/model/adDetail?mapAdId=" + adId,
  236. });
  237. break;
  238. case 2: //内部资源
  239. getMapMatterDetail_Api({ id: resourceModelId }).then((result) => {
  240. uni.navigateTo({
  241. url: "/pages/map/matterDetails",
  242. success: function (res) {
  243. // 通过eventChannel向被打开页面传送数据
  244. res.eventChannel.emit("acceptDataFromOpenerPage", result);
  245. },
  246. });
  247. });
  248. return;
  249. uni.navigateTo({
  250. url: "/pages/pages/map/adDetail?mapAdId=" + adId,
  251. });
  252. break;
  253. case 3: //外部链接
  254. window.open(outsideAddress, "_blank");
  255. break;
  256. }
  257. },
  258. getMapList() {},
  259. },
  260. watch: {
  261. params: {
  262. handler(newV, oldV) {
  263. this.onSearchFocus(true);
  264. },
  265. deep: true,
  266. },
  267. },
  268. };
  269. </script>
  270. <style lang="scss" scoped>
  271. $radius_: 20rpx;
  272. $heig_: 80rpx;
  273. .search-box {
  274. // padding: 20rpx 20rpx 0;
  275. position: fixed;
  276. left: 20rpx;
  277. top: 20rpx;
  278. right: 20rpx;
  279. z-index: 999;
  280. background-color: #fff;
  281. border-radius: $radius_;
  282. overflow: hidden;
  283. .search-input-box {
  284. width: 100%;
  285. height: $heig_;
  286. border-radius: $radius_;
  287. box-shadow: 0rpx -10rpx 30rpx #ccc;
  288. display: flex;
  289. align-items: center;
  290. padding: 0 10px;
  291. color: #020202;
  292. font-size: 28rpx;
  293. .search-icon {
  294. width: 45rpx;
  295. height: 45rpx;
  296. path {
  297. fill: #666666;
  298. }
  299. }
  300. .search-input {
  301. padding-left: 10px;
  302. }
  303. .placeholder {
  304. color: #b3b3b3;
  305. }
  306. }
  307. .search-select {
  308. // border-top: 1rpx solid #E8E8E8;
  309. width: 100%;
  310. height: $heig_;
  311. display: flex;
  312. // justify-content: space-between;
  313. align-items: center;
  314. padding: 0 28rpx;
  315. .select-item {
  316. // width: 50%;
  317. display: flex;
  318. justify-content: center;
  319. align-items: center;
  320. font-size: 28rpx;
  321. padding: 0 10rpx;
  322. color: #1a1a1a;
  323. min-width: 28rpx;
  324. margin-right: 65rpx;
  325. .item-text {
  326. display: inline-block;
  327. padding-right: 14rpx;
  328. overflow: hidden;
  329. }
  330. &:last-child {
  331. margin: 0;
  332. }
  333. }
  334. }
  335. }
  336. .h6-search-content {
  337. .search-select {
  338. .item-text {
  339. color: #929292;
  340. }
  341. }
  342. }
  343. </style>