index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <template>
  2. <view :class="className" :style="wrapper_style">
  3. <!-- style -->
  4. <view v-html="css"></view>
  5. <view v-if="datas.show_title" class="morebox">
  6. <view :style="title_style" class="title">{{ title }}</view>
  7. <view class="title2" @click="more">查看更多
  8. <u-icon :style="img_style2" color="#949494" name="arrow-right" size="14"></u-icon>
  9. </view>
  10. </view>
  11. <!-- 列表 -->
  12. <view class="goods-list">
  13. <view class="li" v-for="(item, index) in list" :key="item.id">
  14. <!--折扣标-->
  15. <discount :value="item.discount" :config="datas" />
  16. <!--商品图片-->
  17. <view class="item-image">
  18. <view class="image-goods">
  19. <goodsimage :src="item.pic" :index="index" />
  20. </view>
  21. </view>
  22. <view class="item-info">
  23. <!-- 价格 -->
  24. <view class="item-shop-market">
  25. <!--销售价-->
  26. <view class="item-shop bold">
  27. <view class="shop-price" :style="shopprice_style">
  28. <shopprice :value="item.price" :config="datas">
  29. </shopprice>
  30. </view>
  31. </view>
  32. <!--市场价-->
  33. <view class="item-market" v-if="del" :style="market_style">
  34. <marketprice :value="item.oprice" :shop-price="item.price" :config="datas" >
  35. </marketprice>
  36. </view>
  37. </view>
  38. </view>
  39. <!-- 剩余 -->
  40. <view class="item-claimed" :style="claimed_style">
  41. <span>{{ filter_only_left(item.num) }}</span>
  42. </view>
  43. <!-- button -->
  44. <view @click="$until.u_gopage('U_goods',item)" class="geshop-button-buynow" :style="buy_style">去购买
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. </template>
  50. <script>
  51. import discount from '@/components/ui-component/component-unit/discount/index.vue';
  52. import goodsimage from '@/components/ui-component/component-unit/image_goods/index.vue';
  53. import marketprice from '@/components/ui-component/component-unit/market_price/index.vue';
  54. import shopprice from '@/components/ui-component/component-unit/shop_price/index.vue';
  55. import landApi from '@/api/land/index.js'
  56. // 自定义样式
  57. const css = function() {
  58. const {
  59. margin_top,
  60. margin_bottom,
  61. bg_color,
  62. shop_price_color,
  63. market_price_color,
  64. text_bg_color,
  65. text_color,
  66. time_text_bg_color,
  67. time_text_color,
  68. bar_text_color,
  69. buynow_bg_color,
  70. buynow_text_color
  71. } = this.datas;
  72. return `
  73. .component-${this.id} {
  74. padding-top: ${margin_top}px;
  75. padding-bottom: ${margin_bottom}px;
  76. font-size: 24rpx;
  77. }
  78. .component-${this.id} .geshop-m-timer {
  79. background-color: ${text_bg_color || '#D8D8D8'};
  80. }
  81. .component-${this.id} .geshop-m-timer .geshop-m-timer-title {
  82. color: ${text_color};
  83. }
  84. .component-${this.id} .geshop-m-timer .geshop-m-timer-right {
  85. color: ${time_text_bg_color};
  86. }
  87. .component-${this.id} .geshop-m-timer span.timer-spiner {
  88. background-color: ${time_text_bg_color};
  89. color: ${time_text_color};
  90. }
  91. .component-${this.id} .item-shop .shop-price {
  92. color: ${shop_price_color};
  93. }
  94. .component-${this.id} .item-market {
  95. color: ${market_price_color};
  96. }
  97. .component-${this.id} .item-claimed {
  98. color: ${bar_text_color};
  99. }
  100. .component-${this.id} .geshop-button-buynow {
  101. background-color: ${buynow_bg_color};
  102. color: ${buynow_text_color};
  103. }
  104. `;
  105. };
  106. /**
  107. * 返回剩余秒数,正整值
  108. * @param {timestamp} timestamp 时间戳
  109. */
  110. const get_second = (timestamp) => {
  111. const now = new Date().getTime();
  112. let left = timestamp - now;
  113. left = Math.abs(left);
  114. const second = parseInt((left / 1000));
  115. return second;
  116. };
  117. /**
  118. * 判断当前的倒计时状态
  119. * @param {timestamp} start 开始的时间
  120. * @param {timestamp} end 结束的时间
  121. * @return {Number} 0=未开始,1=正在开始,2=已经结束
  122. */
  123. const get_status = (start, end) => {
  124. const now = new Date().getTime();
  125. if (now < start) {
  126. return 0;
  127. }
  128. if (now >= start && now < end) {
  129. return 1;
  130. }
  131. if (now >= end) {
  132. return 2;
  133. }
  134. };
  135. /**
  136. * 秒数转换成日期
  137. * @param {Number} s 秒数
  138. * @returns {Array}
  139. */
  140. const second_to_date = (s) => {
  141. let t = ['00', '00', '00', '00'];
  142. if (s > -1) {
  143. t = [];
  144. const day = Math.floor(s / 3600 / 24);
  145. const hour = Math.floor(s / 3600) % 24;
  146. const min = Math.floor(s / 60) % 60;
  147. const sec = s % 60;
  148. t.push(`${day}D`);
  149. if (hour < 10) {
  150. t.push('0' + hour);
  151. } else {
  152. t.push(hour);
  153. }
  154. if (min < 10) {
  155. t.push('0' + min);
  156. } else {
  157. t.push(min);
  158. }
  159. if (sec < 10) {
  160. t.push('0' + sec);
  161. } else {
  162. t.push(sec);
  163. }
  164. };
  165. return t;
  166. };
  167. export default {
  168. components: {
  169. discount,
  170. goodsimage,
  171. marketprice,
  172. shopprice,
  173. },
  174. props: ['datas', 'styles'],
  175. data() {
  176. this.goodsinit()
  177. return {
  178. // 加载状态
  179. loading: true,
  180. // 定时器钩子
  181. timer_id: null,
  182. // 倒计时秒数
  183. spiner: ['00', '00', '00', '00'],
  184. // 倒计时文案
  185. spiner_text: '倒计时文案',
  186. // 当前状态
  187. status: 0,
  188. list:[]
  189. };
  190. },
  191. computed: {
  192. shopprice_style(){
  193. const { shop_price_color } = this.datas
  194. return `color: ${shop_price_color};`;
  195. },
  196. market_style(){
  197. const { market_price_color } = this.datas
  198. return `color: ${market_price_color};`;
  199. },
  200. claimed_style(){
  201. const { bar_text_color } = this.datas
  202. return `color: ${bar_text_color};`;
  203. },
  204. buy_style() {
  205. const { buynow_bg_color, buynow_text_color } = this.datas
  206. return `
  207. background-color: ${buynow_bg_color};
  208. color: ${buynow_text_color};`;
  209. },
  210. className() {
  211. const name = ['component-wrapper', `component-${this.id}`];
  212. return name;
  213. },
  214. /** 副标题内容 */
  215. title() {
  216. return this.datas.title || '土地';
  217. },
  218. img_style2() {
  219. return `
  220. width:15px;
  221. height:15px;
  222. margin:auto;
  223. `;
  224. },
  225. // 副标题栏样式
  226. title_style() {
  227. const {
  228. text_size,
  229. text_color,
  230. } = this.datas;
  231. return `
  232. font-size: ${text_size}px;
  233. color: ${text_color};
  234. `;
  235. },
  236. /** 样式 */
  237. wrapper_style() {
  238. const {
  239. padding_top,
  240. padding_bottom,
  241. padding_left,
  242. padding_right,
  243. bg_color,
  244. margin_top,
  245. margin_bottom,
  246. } = this.datas;
  247. return `
  248. width: 750rpx;
  249. padding-top: ${margin_top}px;
  250. padding-bottom: ${margin_bottom}px;
  251. padding-left: ${padding_left}px;
  252. padding-right: ${padding_right}px;
  253. background-color:${bg_color};
  254. `;
  255. },
  256. css() {
  257. return '<style>' + css.call(this) + '</style>';
  258. },
  259. env() {
  260. return this.$store.state.page.env;
  261. },
  262. // 返回远端数据属否加载完毕
  263. remote_data_loaded() {
  264. return this.$store.state.page.remote_data_loaded;
  265. },
  266. // 数据源ID
  267. goods_source_id() {
  268. return this.datas.goods[0].id || '';
  269. },
  270. // 开始时间
  271. start_time() {
  272. try {
  273. const timestamp = parseInt(this.datas.goods[0].tsk_info.tsk_begin_time);
  274. return timestamp * 1000;
  275. } catch (err) {
  276. return 1577265;
  277. }
  278. },
  279. // 结束时间
  280. end_time() {
  281. try {
  282. const timestamp = parseInt(this.datas.goods[0].tsk_info.tsk_end_time);
  283. return timestamp * 1000;
  284. } catch (err) {
  285. return 1577265;
  286. }
  287. },
  288. // 是否展示删除线
  289. del() {
  290. let visible = true;
  291. visible = (this.datas.market_price_del === undefined || this.datas.market_price_del === null) ? true :
  292. Number(
  293. this.datas.market_price_del) >= 1;
  294. return visible;
  295. }
  296. },
  297. methods: {
  298. goodsinit() {
  299. let that = this
  300. let ids = []
  301. that.datas.goods.forEach(ele => {
  302. ids.push(ele.id)
  303. })
  304. let res = landApi.getlist({
  305. gids: ids,
  306. gtype: 'good',
  307. }).then(res => {
  308. console.log("res", res)
  309. if (res.status == 200) {
  310. that.list = res.data;
  311. }
  312. });
  313. },
  314. more() {
  315. uni.navigateTo({
  316. url: '/pagesE/pages/mall/list'
  317. })
  318. },
  319. // 初始化
  320. async init() {
  321. // 首次状态更新
  322. this.timer(this.start_time, this.end_time);
  323. // 装修页不执行倒计时
  324. if (this.env !== 1) {
  325. clearInterval(this.timer_id);
  326. this.timer_id = setInterval(() => {
  327. this.timer(this.start_time, this.end_time);
  328. }, 1000);
  329. }
  330. this.loading = false;
  331. },
  332. // 倒计时函数
  333. timer(start, end) {
  334. // 获取状态
  335. this.status = get_status(start, end);
  336. let second = 0;
  337. // 判断状态
  338. switch (this.status) {
  339. case 0:
  340. second = get_second(start);
  341. break;
  342. case 1:
  343. second = get_second(end);
  344. break;
  345. case 2:
  346. clearInterval(this.timer_id);
  347. break;
  348. }
  349. // 更新时分秒
  350. this.spiner = second_to_date(second);
  351. },
  352. // 剩余库存文案
  353. filter_only_left(count = 0) {
  354. return '剩余:' + count;
  355. }
  356. },
  357. watch: {
  358. // 监听是否加载远端数据,有的话重新执行倒计时
  359. remote_data_loaded(tof) {
  360. // 变更ID执行获取数据
  361. tof && this.init();
  362. },
  363. start_time() {
  364. this.init();
  365. },
  366. end_time() {
  367. this.init();
  368. },
  369. // 监听商品列表是否有变化
  370. goods_list() {
  371. debugger
  372. // this.$store.dispatch('global/async_goods_init_2', this);
  373. },
  374. },
  375. mounted() {
  376. // 初始化
  377. this.remote_data_loaded && this.init();
  378. this.$emit('loaded');
  379. // 页面元素初始化
  380. // this.$store.dispatch('global/async_goods_init_2', this);
  381. // 绑定滚动时间,兼容图片懒加载在水平滚动下无效
  382. // $(`.component-${this.id} .goods-list`).on('scroll', () => {
  383. // const images = $(this.$el).find('img.js_gdexp_lazy');
  384. // this.$store.dispatch('global/lazyload_img_by_dom', images);
  385. // });
  386. }
  387. };
  388. </script>
  389. <style lang="less" scoped>
  390. // 默认
  391. .component-wrapper {
  392. // display: flex;
  393. // flex-wrap: wrap;
  394. // justify-content: center;
  395. width: 375px;
  396. .morebox {
  397. display: flex;
  398. justify-content: space-between;
  399. align-items: center;
  400. padding: 10px 12px 10px 12px;
  401. .title2 {
  402. font-size: 28rpx;
  403. display: flex;
  404. color: #949494;
  405. align-items: center;
  406. }
  407. }
  408. // 倒计时的
  409. .geshop-m-timer {
  410. width: 100%;
  411. padding: 24 / 75rem 0;
  412. text-align: center;
  413. .geshop-m-timer-title {
  414. display: inline-block;
  415. font-size: 40 / 75rem;
  416. line-height: 54 / 75rem;
  417. height: 54 / 75rem;
  418. }
  419. .geshop-m-timer-right {
  420. font-size: 32 / 75rem;
  421. }
  422. span.timer-text {
  423. margin-right: 12 / 75rem;
  424. }
  425. span.timer-spiner {
  426. display: inline-block;
  427. height: 36 / 75rem;
  428. line-height: 36 / 75rem;
  429. padding: 0 5 / 75rem;
  430. text-align: center;
  431. font-size: 24 / 75rem;
  432. border-radius: 6 / 75rem;
  433. }
  434. }
  435. // 列表
  436. .goods-list {
  437. display: flex;
  438. flex-wrap: wrap;
  439. justify-content: space-evenly;
  440. padding: 20rpx;
  441. padding-bottom: 20rpx;
  442. .li {
  443. position: relative;
  444. flex-shrink: 0;
  445. width: 44%;
  446. overflow: hidden;
  447. padding: 20rpx;
  448. margin-top: 10rpx;
  449. background-color: #ffffff;
  450. }
  451. // 商品详情
  452. .item-info {
  453. padding-top: 10px;
  454. padding-bottom: 10px;
  455. }
  456. // 销售及市场价
  457. .item-shop-market {
  458. width: 100%;
  459. }
  460. .item-shop-market .item-shop {
  461. display: flex;
  462. flex-flow: row wrap;
  463. color: #333333;
  464. line-height: 24/37.5rem;
  465. align-items: baseline;
  466. padding-top: 10px;
  467. padding-bottom: 10px;
  468. .shop-price {
  469. font-size: 32rpx;
  470. font-weight: bold;
  471. }
  472. }
  473. .item-market {
  474. height: 30rpx;
  475. line-height: 30rpx;
  476. }
  477. // 售空
  478. .item-soldout {
  479. position: absolute;
  480. top: 50%;
  481. left: 50%;
  482. width: 160 / 75rem;
  483. height: 160 / 75rem;
  484. border-radius: 100%;
  485. background-color: #000000;
  486. opacity: 0.4;
  487. z-index: 1;
  488. margin-left: -80 / 75rem;
  489. margin-top: -80 / 75rem;
  490. display: flex;
  491. justify-content: center;
  492. align-items: center;
  493. >span {
  494. display: block;
  495. text-align: center;
  496. font-size: 28 / 75rem;
  497. color: #ffffff;
  498. width: 80%;
  499. text-align: center;
  500. word-break: break-all;
  501. line-height: 1em;
  502. }
  503. }
  504. // 促销
  505. .item-promotions {
  506. position: relative;
  507. height: 24/75rem;
  508. line-height: 24/75rem;
  509. overflow: hidden;
  510. margin-top: 6/75rem;
  511. margin-bottom: 24/75rem;
  512. font-size: 24/75rem;
  513. .gs-off-text {
  514. .special {
  515. font-weight: 700;
  516. font-family: OpenSans-Bold, arial, serif;
  517. }
  518. }
  519. .sjx {
  520. position: absolute;
  521. right: 0;
  522. top: 0;
  523. width: 28/75rem;
  524. height: 28/75rem;
  525. }
  526. .icon-downs {
  527. width: 100%;
  528. height: 100%;
  529. }
  530. }
  531. }
  532. // 购买按钮
  533. .geshop-button-buynow {
  534. text-align: center;
  535. margin-top: 20rpx;
  536. width: 100%;
  537. font-size: 28rpx;
  538. height: 60rpx;
  539. line-height: 60rpx;
  540. padding: 0px;
  541. }
  542. }
  543. </style>