RelicList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <template>
  2. <div class="relic-list">
  3. <button
  4. class="return"
  5. @click="router.go(-1)"
  6. />
  7. <!-- <menu>
  8. <button class="scene-select">
  9. 大汗之城
  10. </button>
  11. <button class="camera-select">
  12. 雄伟帝都
  13. </button>
  14. <button class="all">
  15. 全部
  16. </button>
  17. </menu> -->
  18. <el-cascader
  19. v-model="cascaderValue"
  20. :options="cameraTree"
  21. :props="{
  22. expandTrigger: 'hover',
  23. }"
  24. @change="handleCascaderChange"
  25. />
  26. <div class="search-ui">
  27. <input
  28. v-model.trim="keyword"
  29. type="text"
  30. placeholder="请输入要搜索内容"
  31. @keydown.enter="onSearch"
  32. >
  33. <button
  34. class="search"
  35. @click="onSearch"
  36. />
  37. </div>
  38. <div class="the-list">
  39. <div
  40. ref="listEl"
  41. class="content-wrap"
  42. >
  43. <div
  44. v-for="(item, idx) in relicData"
  45. :key="idx"
  46. class="relic-item"
  47. :class="{
  48. hide: !(item.isPassedSearch && item.isPassedSelect)
  49. }"
  50. @click="onClickItem(idx)"
  51. >
  52. <img
  53. class=""
  54. :src="getRelicThumbUrl(idx)"
  55. alt=""
  56. draggable="false"
  57. >
  58. <div
  59. class="name"
  60. :title="item['名称']"
  61. >
  62. {{ item['名称'] }}
  63. </div>
  64. </div>
  65. </div>
  66. </div>
  67. </div>
  68. </template>
  69. <script setup>
  70. /**
  71. * todo: 自动恢复上次滚动位置
  72. */
  73. import { ref, computed, watch, watchEffect, onMounted } from "vue"
  74. import { useRoute, useRouter } from "vue-router"
  75. import { useStore } from "vuex"
  76. import useSmoothSwipe from '@/useFunctions/useSmoothSwipe.js'
  77. import { useElementSize } from '@vueuse/core'
  78. const route = useRoute()
  79. const router = useRouter()
  80. const store = useStore()
  81. const cascaderValue = ref([
  82. 'all'
  83. ])
  84. const cameraTree = ref([
  85. {
  86. value: 'all',
  87. label: '全部',
  88. },
  89. {
  90. value: '0',
  91. label: '大汗之城',
  92. children: [
  93. {
  94. value: 'all',
  95. label: '全部',
  96. },
  97. {
  98. value: '0',
  99. label: '雄伟帝都',
  100. },
  101. {
  102. value: '1',
  103. label: '大都宫阙',
  104. },
  105. {
  106. value: '2',
  107. label: '大都览胜',
  108. },
  109. ]
  110. },
  111. {
  112. value: '1',
  113. label: '河润大都',
  114. children: [
  115. {
  116. value: 'all',
  117. label: '全部',
  118. },
  119. {
  120. value: '0',
  121. label: '通惠河畅',
  122. },
  123. {
  124. value: '1',
  125. label: '舳舻蔽水',
  126. },
  127. {
  128. value: '2',
  129. label: '繁华富庶',
  130. },
  131. ]
  132. },
  133. {
  134. value: '2',
  135. label: '大都风华',
  136. children: [
  137. {
  138. value: 'all',
  139. label: '全部',
  140. },
  141. {
  142. value: '0',
  143. label: '文人雅集',
  144. },
  145. {
  146. value: '1',
  147. label: '曲苑杂剧',
  148. },
  149. ]
  150. },
  151. ])
  152. function handleCascaderChange(e) {
  153. console.log(e)
  154. }
  155. const keyword = ref('')
  156. function onSearch() {
  157. }
  158. const sceneIdx = computed(() => {
  159. return route.query.sceneIdx
  160. })
  161. const cameraIdx = computed(() => {
  162. return route.query.cameraIdx
  163. })
  164. const relicData = computed(() => {
  165. return store.getters.relicData.map((item) => {
  166. if (cascaderValue.value[0] === 'all') {
  167. item.isPassedSelect = true
  168. } else {
  169. const selectedSceneIdx = Number(cascaderValue.value[0])
  170. const itemSceneIdx = Number(item['镜头ID'].split('-')[0]) - 1
  171. if (selectedSceneIdx !== itemSceneIdx) {
  172. item.isPassedSelect = false
  173. } else {
  174. if (cascaderValue.value[1] === 'all') {
  175. item.isPassedSelect = true
  176. } else {
  177. const selectedCameraIdx = Number(cascaderValue.value[1])
  178. const itemCameraIdx = Number(item['镜头ID'].split('-')[1]) - 1
  179. if (selectedCameraIdx === itemCameraIdx) {
  180. item.isPassedSelect = true
  181. } else {
  182. item.isPassedSelect = false
  183. }
  184. }
  185. }
  186. }
  187. if (!keyword.value) {
  188. item.isPassedSearch = true
  189. } else {
  190. if (item['名称'].includes(keyword.value)) {
  191. item.isPassedSearch = true
  192. } else {
  193. item.isPassedSearch = false
  194. }
  195. }
  196. return item
  197. })
  198. })
  199. function getRelicThumbUrl(idx) {
  200. if (Array.isArray(relicData.value[idx]['图片名']) && relicData.value[idx]['图片名'][0]) {
  201. return `${process.env.BASE_URL}relic-data/small-photo/${relicData.value[idx]['图片名'][0]}`
  202. } else {
  203. return ''
  204. }
  205. }
  206. const listEl = ref(null)
  207. const { width: listWidth, height: listHeight } = useElementSize(listEl)
  208. const { hasOperatedThisTime } = useSmoothSwipe({
  209. scrollTargetRef: listEl,
  210. viewportWidth: listWidth,
  211. })
  212. function onClickItem(idx) {
  213. if (!hasOperatedThisTime.value) {
  214. router.push({
  215. name: 'RelicDetail',
  216. query: {
  217. sceneIdx: route.query.sceneIdx,
  218. cameraIdx: route.query.cameraIdx,
  219. relicIdx: idx,
  220. }
  221. })
  222. }
  223. }
  224. </script>
  225. <style lang="less" scoped>
  226. @page-height-design-px: 970;
  227. .relic-list {
  228. height: 100%;
  229. background-image: url(@/assets/images/relic-list-bg.jpg);
  230. background-size: cover;
  231. background-repeat: no-repeat;
  232. background-position: center center;
  233. >button.return {
  234. position: absolute;
  235. width: 58px;
  236. height: 58px;
  237. left: 42px;
  238. top: 68px;
  239. background-image: url(@/assets/images/btn-return.png);
  240. background-size: contain;
  241. background-repeat: no-repeat;
  242. background-position: center center;
  243. }
  244. ::v-deep {
  245. .el-cascader {
  246. position: absolute;
  247. width: 200px;
  248. height: 58px;
  249. left: 160px;
  250. top: 68px;
  251. .el-input {
  252. height: 100%;
  253. background-image: url(@/assets/images/cascader-bg.png);
  254. background-size: 100% 100%;
  255. border: 0;
  256. .el-input__wrapper {
  257. background: none;
  258. border: 0;
  259. box-shadow: none;
  260. .el-input__inner {
  261. height: 100%;
  262. font-size: 30px;
  263. text-align: center;
  264. font-family: 'SourceHanSerifCN-Heavy';
  265. color: #6A3906;
  266. }
  267. .el-input__suffix {
  268. color: #6A3906;
  269. }
  270. }
  271. .icon-arrow-down {
  272. font-size: 24px;
  273. margin-top: 10px;
  274. }
  275. }
  276. }
  277. .el-popper .is-light {
  278. background: red;
  279. }
  280. }
  281. // >menu{
  282. // position: absolute;
  283. // width: 524px;
  284. // height: 66px;
  285. // left: 150px;
  286. // top: 64px;
  287. // background-image: url(@/assets/images/relic-list-page-menu-bg.png);
  288. // background-size: contain;
  289. // background-repeat: no-repeat;
  290. // background-position: center center;
  291. // >button.scene-select{
  292. // position: absolute;
  293. // top: 50%;
  294. // left: 10px;
  295. // transform: translateY(-50%);
  296. // width: 220px;
  297. // height: 50px;
  298. // padding-left: 10px;
  299. // font-size: 30px;
  300. // font-family: Source Han Serif CN, Source Han Serif CN;
  301. // font-weight: bold;
  302. // color: #43310E;
  303. // line-height: 46px;
  304. // letter-spacing: 6px;
  305. // }
  306. // >button.camera-select{
  307. // position: absolute;
  308. // top: 50%;
  309. // left: 230px;
  310. // transform: translateY(-50%);
  311. // width: 160px;
  312. // height: 50px;
  313. // font-size: 24px;
  314. // font-family: Source Han Sans CN, Source Han Sans CN;
  315. // font-weight: 500;
  316. // color: #FFF7D9;
  317. // line-height: 36px;
  318. // letter-spacing: 5px;
  319. // }
  320. // >button.all{
  321. // position: absolute;
  322. // top: 50%;
  323. // left: 400px;
  324. // transform: translateY(-50%);
  325. // width: 100px;
  326. // height: 50px;
  327. // font-size: 24px;
  328. // font-family: Source Han Sans CN, Source Han Sans CN;
  329. // font-weight: 500;
  330. // color: rgba(255,247,217,0.7);
  331. // line-height: 36px;
  332. // letter-spacing: 5px;
  333. // }
  334. // }
  335. >.search-ui {
  336. position: absolute;
  337. top: 65px;
  338. right: 27px;
  339. width: 406px;
  340. height: 62px;
  341. background-image: url(@/assets/images/search-bg.png);
  342. background-size: cover;
  343. background-repeat: no-repeat;
  344. background-position: center center;
  345. >input {
  346. position: absolute;
  347. left: 50px;
  348. top: 50%;
  349. transform: translateY(-50%);
  350. height: 35px;
  351. width: 250PX;
  352. font-size: 24px;
  353. font-family: Source Han Sans CN, Source Han Sans CN;
  354. font-weight: 400;
  355. color: rgba(255, 255, 255, 0.7);
  356. line-height: 28px;
  357. &::placeholder {
  358. font-size: 24px;
  359. font-family: Source Han Sans CN, Source Han Sans CN;
  360. font-weight: 400;
  361. color: rgba(255, 255, 255, 0.3);
  362. line-height: 28px;
  363. }
  364. }
  365. >button.search {
  366. position: absolute;
  367. width: 31px;
  368. height: 31px;
  369. position: absolute;
  370. top: 50%;
  371. right: 53px;
  372. transform: translateY(-50%);
  373. background-image: url(@/assets/images/icon-search.png);
  374. background-size: cover;
  375. background-repeat: no-repeat;
  376. background-position: center center;
  377. }
  378. }
  379. >.the-list {
  380. position: absolute;
  381. left: 0;
  382. top: 150px;
  383. width: 100%;
  384. height: calc(650 / @page-height-design-px * 100vh);
  385. background-image: url(@/assets/images/relic-list-bg-1.png);
  386. background-size: auto 100%;
  387. background-repeat: no-repeat;
  388. background-position: left center;
  389. padding-left: calc(56 / @page-height-design-px * 100vh);
  390. box-sizing: border-box;
  391. >.content-wrap {
  392. &::-webkit-scrollbar {
  393. height: 0;
  394. }
  395. box-sizing: border-box;
  396. height: 100%;
  397. width: 100%;
  398. overflow: auto;
  399. user-select: none;
  400. display: flex;
  401. align-items: center;
  402. background-image: url(@/assets/images/relic-list-bg-2.png);
  403. background-size: auto 92%;
  404. background-repeat: repeat no-repeat;
  405. background-position: left 44%;
  406. background-attachment: local;
  407. padding-top: calc(50 / @page-height-design-px * 100vh);
  408. >.relic-item {
  409. flex: 0 0 auto;
  410. width: calc(290 / @page-height-design-px * 100vh);
  411. height: 80%;
  412. padding: calc(10 / @page-height-design-px * 100vh);
  413. margin-right: calc(100 / @page-height-design-px * 100vh);
  414. display: flex;
  415. flex-direction: column;
  416. justify-content: center;
  417. align-items: center;
  418. cursor: pointer;
  419. >img {
  420. flex: 0 0 auto;
  421. width: 100%;
  422. height: calc(150 / @page-height-design-px * 100vh);
  423. object-fit: contain;
  424. margin-bottom: calc(10 / @page-height-design-px * 100vh);
  425. }
  426. >.name {
  427. text-align: center;
  428. flex: 0 0 auto;
  429. height: 4em;
  430. width: 100%;
  431. font-size: calc(32 / @page-height-design-px * 100vh);
  432. font-family: Source Han Serif CN, Source Han Serif CN;
  433. font-weight: 500;
  434. color: #281D0C;
  435. line-height: calc(37 / @page-height-design-px * 100vh);
  436. display: -webkit-box;
  437. -webkit-box-orient: vertical;
  438. -webkit-line-clamp: 3;
  439. overflow: hidden;
  440. }
  441. }
  442. >.relic-item.hide {
  443. display: none;
  444. }
  445. }
  446. }
  447. }
  448. </style>