index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. <template>
  2. <div class="w-full h-full">
  3. <div class="w-full px-16 h-40 mt-10 mx-auto">
  4. <div class="flex h-40 w-full items-center justify-between rounded-full border bg-[#fff]">
  5. <input
  6. type="text"
  7. v-model="searchString"
  8. class="ml-5 w-[80%] h-full pl-10 text-sm"
  9. placeholder="请输入要办理的签证居留的国家或地区名称"
  10. @keydown.enter="navigateTovisaList({ searchString })"
  11. style="outline: none; background: none"
  12. />
  13. <!-- @keydown.enter="navigateTovisaList({ searchString })" -->
  14. <button
  15. @click="navigateTovisaList({ searchString })"
  16. class="h-full border flex justify-center items-center w-66 shrink-0 rounded-r-full"
  17. >
  18. <div style="color: white" class="w-16 h-16 shrink-0">
  19. <img class="w-full h-full object-cover" src="~/assets/img/visa/search.svg" alt="" />
  20. </div>
  21. </button>
  22. </div>
  23. </div>
  24. <div class="w-full pl-32 pb-10 text-left text-sm text-black-9">
  25. *暂不支持公务员、军人办理签证
  26. </div>
  27. <div class="relative h-110 w-full pt-23">
  28. <img
  29. :src="banner_visa"
  30. alt="banner_visa"
  31. class="absolute left-0 top-0 z-[-100] h-full w-full"
  32. />
  33. <img
  34. :src="banner_left"
  35. alt="banner_left"
  36. class="absolute left-0 top-0 z-[-80] h-full w-127"
  37. />
  38. <img
  39. :src="banner_right"
  40. alt="banner_right"
  41. class="absolute right-0 top-0 -z-80 h-full w-127"
  42. />
  43. <!-- 签证的搜索区域 -->
  44. <div class="mx-auto box-border flex w-190 flex-wrap items-center justify-center">
  45. <h1 class="w-full text-center text-xl">签证居留</h1>
  46. <h2 class="w-full pb-24 pt-4 px-15 text-black-6 text-center text-sm">
  47. 覆盖全球多个国家和地区,
  48. <br />
  49. 提供全面便捷的一站式服务。
  50. </h2>
  51. </div>
  52. </div>
  53. <div class="flex flex-col items-center px-16 pt-16 justify-center bg-[#fff]">
  54. <!-- 签证办理流程 -->
  55. <VisaPayProcess></VisaPayProcess>
  56. <!-- 签证类型 -->
  57. <div class="flex w-full flex-wrap items-center justify-between">
  58. <NuxtLink
  59. v-for="(item, index) in visaTypeList"
  60. :key="item?.id"
  61. :to="`/visa/article/${item?.id}`"
  62. class="relative mb-12 box-border h-60 w-165 rounded-lg hover:border-[1px] hover:border-[#FD9A00] hover:shadow-[0_4px_4px_0_rgba(0,0,0,0.25)] active:border-[1px] active:border-[#FD9A00] active:shadow-[0_4px_4px_0_rgba(0,0,0,0.25)]"
  63. style="background: linear-gradient(90deg, #fff5eb 0%, #f9e5cd 100%)"
  64. >
  65. <h1 class="my-18 ml-16 h-24 text-xl font-semibold leading-24 text-[#FD9A00]">
  66. {{ item?.title }}
  67. </h1>
  68. <img
  69. :src="visaTypeImageList[index]"
  70. alt=""
  71. class="absolute left-0 top-0 z-[10] h-full w-full"
  72. />
  73. </NuxtLink>
  74. </div>
  75. <!-- 热门目的地签证 -->
  76. <div class="box-border w-full rounded-lg">
  77. <h1
  78. v-if="hotVisaList?.length > 0"
  79. class="p-16 text-center text-base font-normal text-black-6"
  80. >
  81. 热门签证
  82. </h1>
  83. <div class="flex flex-wrap items-start justify-between">
  84. <NuxtLink
  85. :to="`/visa/details/${item?.id}`"
  86. v-for="(item, index) in hotVisaList?.slice(0, 8)"
  87. :key="item.id"
  88. :class="`mb-12 w-[48%] cursor-pointer overflow-hidden rounded-xl bg-[#fff]`"
  89. >
  90. <div class="h-98 w-full overflow-hidden rounded-t-xl">
  91. <img v-if="item?.img" :src="item?.img" alt="" class="h-full w-full" />
  92. </div>
  93. <div class="box-border border flex rounded-b-xl items-center justify-between p-8">
  94. <span
  95. :title="item?.countryCodeIdDictMap?.name"
  96. class="w-42 line-clamp-1 text-base font-medium text-black-3"
  97. >
  98. {{ item?.countryCodeIdDictMap?.name }}
  99. </span>
  100. <div
  101. :class="` shrink-0 line-clamp-1 px-4 h-20 text-center text-sm leading-3xl rounded-full text-[${formatStatus(item?.visaTypeIdDictMap?.id)}] bg-[${formatStatus(item?.visaTypeIdDictMap?.id)}]/[0.1]`"
  102. >
  103. {{ item?.visaTypeIdDictMap.name }}
  104. </div>
  105. <span class="shrink-0 line-clamp-1">
  106. <span class="text-sm text-[#f0a020]">¥</span>
  107. <span class="text-base text-[#f0a020]">{{ item?.floorPrice }}</span>
  108. <span class="text-sm text-[#999]">起</span>
  109. </span>
  110. </div>
  111. </NuxtLink>
  112. </div>
  113. </div>
  114. </div>
  115. <h1
  116. v-if="allVisaList.length > 0"
  117. class="w-full pb-20 pt-8 font-normal text-center text-base text-black-6"
  118. >
  119. 全球目的地签证
  120. </h1>
  121. <div
  122. class="flex w-full items-center border-b-[1px] border-[#E7E7E7] border- mb-16 justify-between overflow-hidden"
  123. >
  124. <div
  125. :class="`flex relative justify-center items-center box-border h-48 flex-1 cursor-pointer ${tabs_value === item?.id ? 'border-b-1 border-b-[#FD9A00] bg-[#fff] font-[600] font-semibold text-[#FD9A00]' : ' bg-[#fff] font-normal text-black-9'} text-base `"
  126. v-for="item in allVisaList"
  127. :key="item?.id"
  128. @click="changeTabs(item?.id)"
  129. >
  130. {{ item?.title }}
  131. <div
  132. v-if="tabs_value === item?.id"
  133. class="absolute bottom-0 left-1/2 -translate-x-1/2 w-16 h-3 bg-[#FF9300] rounded"
  134. ></div>
  135. </div>
  136. </div>
  137. <div class="w-full bg-[#fff] mb-30 pl-12">
  138. <div class="box-border flex flex-wrap justify-start">
  139. <Empty v-if="!chauAllCountryVisaData.length" title="暂无数据" top="50" />
  140. <template v-for="(el, it) in chauAllCountryVisaData" :key="el?.id + el?.english_name">
  141. <div
  142. @click="navigateGlobalTovisaList({ countryCodeId: el?.country_code }, it)"
  143. :class="`mb-12 mr-10 flex py-8 px-6 h-108 w-[22%] flex-wrap justify-between rounded-[4px] ${globalActive == it ? 'bg-[#F5F7FA]' : ''} `"
  144. >
  145. <div class="h-48 mb-4 w-72 overflow-hidden border border-dotted border-[#E5E5E5]">
  146. <img
  147. v-if="el?.url !== ''"
  148. class="h-full w-full rounded-[4px] object-cover"
  149. :src="el?.url"
  150. style="object-fit: contain"
  151. alt=""
  152. />
  153. <img v-else class="h-full w-full rounded-[4px] object-cover" :src="UN" alt="" />
  154. </div>
  155. <div class="pl-2.5 box-border w-full">
  156. <div
  157. :title="el?.country"
  158. :class="`h-[26px] w-full truncate text-ellipsis whitespace-nowrap text-base font-[400] leading-[20px] ${globalActive == it ? 'text-[#FF9300]' : ''} `"
  159. >
  160. {{ el?.country }}
  161. </div>
  162. <div
  163. :title="el?.english_name"
  164. :class="`h-16 w-72 truncate text-ellipsis whitespace-nowrap text-sm font-[400] leading-sm ${globalActive == it ? 'text-[#FF9300]' : 'text-black-9 '} `"
  165. >
  166. {{ el?.english_name }}
  167. </div>
  168. </div>
  169. </div>
  170. </template>
  171. </div>
  172. </div>
  173. <Footer />
  174. </div>
  175. </template>
  176. <script setup>
  177. import banner_visa from '@/assets/img/visa/banner_visa.png'
  178. import banner_left from '@/assets/img/visa/banner_left.png'
  179. import banner_right from '@/assets/img/visa/banner_right.png'
  180. import search_svg from '~/assets/img/visa/search.svg'
  181. // 签证分类的图片
  182. import small_banner_icon1 from '@/assets/img/visa/small_banner1.png'
  183. import small_banner_icon2 from '@/assets/img/visa/small_banner2.png'
  184. import small_banner_icon3 from '@/assets/img/visa/small_banner3.png'
  185. import small_banner_icon4 from '@/assets/img/visa/small_banner4.png'
  186. //国家图片
  187. import UN from '@/assets/img/visa/UNImage.png'
  188. onMounted(() => {
  189. getVisaTypeList()
  190. getHotVisaList()
  191. getAllVisaList()
  192. getChauAllCountryVisaList()
  193. })
  194. const colorList = ['#FF9300', '#1BC467', '#FF476A', '#1BC467']
  195. // 签证的搜索
  196. const searchString = ref('')
  197. // 全球的tabs的下标
  198. const tabs_value = ref('1')
  199. // 全球签证触发的下标
  200. const globalActive = ref(null)
  201. // 顾问信息
  202. let consultantInfo = ref({})
  203. // 顾问的模态框
  204. let showVisaModal = ref(false)
  205. // 重新获取洲对应的国家
  206. watch(
  207. tabs_value,
  208. () => {
  209. getChauAllCountryVisaList()
  210. },
  211. { deep: true }
  212. )
  213. // 跳转到签证的列表页
  214. const navigateTovisaList = (parmas) => {
  215. // if (parmas.searchString) {
  216. navigateTo({
  217. path: '/visa/visaList',
  218. query: {
  219. ...parmas
  220. }
  221. })
  222. // }
  223. }
  224. // 跳转到签证的列表页
  225. const navigateGlobalTovisaList = (parmas, index) => {
  226. globalActive.value = index
  227. navigateTo({
  228. path: '/visa/visaList',
  229. query: {
  230. ...parmas
  231. }
  232. })
  233. }
  234. const visaTypeImageList = [
  235. small_banner_icon1,
  236. small_banner_icon2,
  237. small_banner_icon3,
  238. small_banner_icon4
  239. ]
  240. const isValue = (parmas) => {
  241. if (parmas !== null || parmas !== undefined || parmas !== '') {
  242. return parmas
  243. } else {
  244. return ''
  245. }
  246. }
  247. // tabs标题的切换
  248. const changeTabs = (newTabId) => {
  249. tabs_value.value = newTabId
  250. }
  251. // 获取签证的类型列表
  252. const visaTypeList = ref([])
  253. async function getVisaTypeList() {
  254. const { data } = await request(`/website/tourism/visa/getTypeList`)
  255. if (Array.isArray(data)) visaTypeList.value = data
  256. }
  257. // 获取热门签证
  258. const hotVisaList = ref([])
  259. async function getHotVisaList() {
  260. const { data } = await request('/website/tourism/visa/hotAddress')
  261. if (Array.isArray(data)) hotVisaList.value = data
  262. }
  263. // 获取全球的签证目的地
  264. const allVisaList = ref([])
  265. async function getAllVisaList() {
  266. const { data } = await request('/website/tourism/visa/interFind')
  267. if (Array.isArray(data)) allVisaList.value = data
  268. }
  269. // 获取洲对应的国家的签证目的地
  270. const chauAllCountryVisaData = ref([])
  271. async function getChauAllCountryVisaList() {
  272. let url = `/website/tourism/visa/findAllCountry?id=${tabs_value.value}`
  273. let { data } = await request(url)
  274. if (Array.isArray(data) && data?.length) {
  275. chauAllCountryVisaData.value = data
  276. } else {
  277. chauAllCountryVisaData.value = []
  278. }
  279. }
  280. function formatStatus(status) {
  281. let index = visaTypeList.value?.findIndex((item) => item.id == status)
  282. return colorList[index]
  283. }
  284. // 单独获取顾问得的二维码
  285. // const getCounselorQr = async () => {
  286. // showVisaModal.value = !showVisaModal.value
  287. // try {
  288. // let url = `/website/tourism/visa/findWechatList`
  289. // let { data } = await request(url)
  290. // if (data) {
  291. // consultantInfo.value = data
  292. // consultantInfo.value.workingTime = `${isValue(data?.start)}:00 - ${isValue(data?.end)}:00`
  293. // }
  294. // } finally {
  295. // return
  296. // }
  297. // }
  298. </script>
  299. <style lang="scss" scoped>
  300. ::v-deep .van-tabs__line {
  301. background-color: #ff9300;
  302. }
  303. ::v-deep .van-tab__text--ellipsis {
  304. font-size: 16px;
  305. }
  306. </style>