poster.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. <template>
  2. <app-layout>
  3. <view class="poster-goods">
  4. <view id="head" class="head">
  5. <view class="poster main-center cross-center" :style="cStyle">
  6. <view v-if="selectForm" :class="['style-'+ selectForm.style]">
  7. <image class="activity-bg" :src="bg"></image>
  8. <view class="middleman-tip dir-left-nowrap cross-center">
  9. <image class="middleman-avatar" :src="middleman.avatar"></image>
  10. <view>我在{{address}}{{middleman.location}}发现了一个超划算的团购!</view>
  11. </view>
  12. <view class="goods-list" :class="['number-'+ activity.goods_list.length]">
  13. <view class="goods" :class="activity.goods_list.length > 2 ? 'dir-left-nowrap' : 'dir-top-nowrap'" v-for="(item,index) in activity.goods_list" :key="index">
  14. <image class="goods-cover" :src="item.cover_pic"></image>
  15. <view class="goods-info" :class="activity.goods_list.length > 2 ? '' : 'dir-top-nowrap main-center'">
  16. <view class="t-omit-two">{{item.name}}</view>
  17. <view v-if="item.price">
  18. <view class="goods-price">¥{{item.price}}</view>
  19. <view class="goods-original-price">¥{{item.original_price}}</view>
  20. </view>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="cross-center activity" :class="selectForm.style == 1 ? 'dir-right-nowrap' : 'dir-left-nowrap'">
  25. <view class="activity-qrcode main-center cross-center">
  26. <image :src="activity.qrcode"></image>
  27. </view>
  28. <view class="activity-info">
  29. <view class="dir-left-nowrap cross-center">
  30. <view>团长:</view>
  31. <image class="activity-avatar" :src="middleman.avatar"></image>
  32. <view>{{middleman.nickname}}</view>
  33. </view>
  34. <view class="dir-left-nowrap cross-center">
  35. 结束时间:{{activity.end_at}}
  36. </view>
  37. <view class="dir-left-nowrap cross-center">
  38. 提货地址:{{address}}{{middleman.detail}}
  39. </view>
  40. </view>
  41. </view>
  42. </view>
  43. </view>
  44. </view>
  45. <view class="setting">
  46. <view class="dir-left-nowrap line">
  47. <view class="box-grow-0 main-center cross-center label">
  48. <icon :style="{'background-color': getTheme.background}" type></icon>
  49. <text>样式</text>
  50. </view>
  51. <view class="dir-left-wrap box-grow-1">
  52. <view v-for="(item,key) in styleList" :key="key"
  53. @click="changeStyle(item.value)"
  54. v-if="config.activity_poster_style.indexOf(item.value.toString()) !== -1"
  55. :style="{'border-color': item.value == selectForm.style ? getTheme.border : ''}"
  56. :class="item.value == selectForm.style ? 'active': ''"
  57. class="style-input main-center cross-center"
  58. >
  59. <text>{{item.label}}</text>
  60. <icon v-if="item.value == selectForm.style" class="icon-active"
  61. :style="{'background-color': getTheme.background}" type></icon>
  62. </view>
  63. </view>
  64. </view>
  65. <view class="dir-left-nowrap line" style="margin-bottom:5rpx">
  66. <view class="box-grow-0 main-center cross-center label">
  67. <icon :style="{'background-color': getTheme.background}" type></icon>
  68. <text>类型</text>
  69. </view>
  70. <view class="dir-left-wrap box-grow-1">
  71. <view v-for="(item,key) in typeList" :key="key"
  72. @click="changeType(item.value)"
  73. :style="{'border-color': item.value == selectForm.type ? getTheme.border : ''}"
  74. :class="item.value == selectForm.type ? 'active': ''"
  75. class="style-input dir-left-nowrap main-center cross-center"
  76. >
  77. <view v-if="item.value === 1" class="type-pure"></view>
  78. <view v-if="item.value === 2" class="type-gradient"></view>
  79. <text>{{item.label}}</text>
  80. <icon v-if="item.value == selectForm.type" class="icon-active"
  81. :style="{'background-color': getTheme.background}" type></icon>
  82. </view>
  83. </view>
  84. </view>
  85. <view class="dir-left-nowrap line" v-if="selectForm && selectForm.type == 1">
  86. <view class="box-grow-0 main-center cross-center label" style="margin-top: 19rpx">
  87. <icon :style="{'background-color': getTheme.background}" type></icon>
  88. <text>颜色</text>
  89. </view>
  90. <view class="dir-left-wrap box-grow-1">
  91. <scroll-view scroll-x class="app-scroll" enable-flex="true">
  92. <view v-for="(color,key) in config.color" :key="key"
  93. @click="changeColor(color)"
  94. class="color-bg"
  95. :style="{'background': `${color}`}">
  96. <icon v-if="color == selectForm.color" class="icon-active"
  97. :style="{'background-color': getTheme.background}" type></icon>
  98. </view>
  99. </scroll-view>
  100. </view>
  101. </view>
  102. <view class="button main-center cross-center" @click="submitSave"
  103. :style="{'background-color': getTheme.background}">保存图片
  104. </view>
  105. </view>
  106. </view>
  107. </app-layout>
  108. </template>
  109. <script>
  110. import {mapGetters, mapState} from 'vuex';
  111. export default {
  112. name: "goods",
  113. data() {
  114. return {
  115. styleList: [{
  116. label: '样式一',
  117. value: 1,
  118. }, {
  119. label: '样式二',
  120. value: 2,
  121. }, {
  122. label: '样式三',
  123. value: 3,
  124. }, {
  125. label: '样式四',
  126. value: 4,
  127. }],
  128. bg: '',
  129. typeList: [],
  130. selectForm: null,
  131. config: {
  132. color: [],
  133. activity_poster_style: [],
  134. },
  135. address: '',
  136. info: {},
  137. activity: {},
  138. middleman: {},
  139. rpx: 1,
  140. canvas: null,
  141. canvas2: null,
  142. ctx: null,
  143. activity_id: 0,
  144. middleman_id: 0,
  145. }
  146. },
  147. computed: {
  148. cStyle() {
  149. let style = '';
  150. console.log(uni.getSystemInfoSync().windowHeight)
  151. if(uni.getSystemInfoSync().windowHeight > 672) {
  152. style += `margin: 17% auto;`
  153. }
  154. if(this.selectForm && this.selectForm.type == 1) {
  155. style += `background-color:${this.selectForm.color};`
  156. }else if(this.selectForm && this.selectForm.type == 3) {
  157. style += `background-image:url(${this.config.image_bg});`
  158. }
  159. return style
  160. },
  161. ...mapGetters('mallConfig', {
  162. getTheme: 'getTheme',
  163. }),
  164. ...mapState({
  165. community: state => state.mallConfig.__wxapp_img.community,
  166. })
  167. },
  168. onLoad(options) { this.$commonLoad.onload(options);
  169. let that = this;
  170. that.$showLoading({text: '加载中'});
  171. that.activity_id = options.activity_id;
  172. that.middleman_id = options.middleman_id;
  173. that.loadData();
  174. },
  175. methods: {
  176. loadData() {
  177. const self = this;
  178. self.$request({
  179. url: self.$api.community.poster,
  180. data: {
  181. activity_id: self.activity_id,
  182. middleman_id: self.middleman_id
  183. }
  184. }).then(info => {
  185. self.$hideLoading();
  186. if (info.code === 0) {
  187. self.config = info.data.config;
  188. self.info = info.data.info;
  189. self.middleman = info.data.middleman;
  190. self.activity = info.data.activity;
  191. self.activity.goods_list = self.activity.goods_list.slice(0,6);
  192. if(self.activity.goods_list.length == 5) {
  193. self.activity.goods_list.push('')
  194. }
  195. self.address = self.middleman.city+self.middleman.district;
  196. if(self.middleman.city != self.middleman.province) {
  197. self.address = self.middleman.province + self.address
  198. }
  199. self.typeList = [{
  200. label: '纯色',
  201. value: 1,
  202. }, {
  203. label: '背景图',
  204. value: 3,
  205. }];
  206. self.selectForm = {
  207. color: self.config['color'][0],
  208. style: self.config['activity_poster_style'][0],
  209. type: 3,
  210. }
  211. switch (self.config['activity_poster_style'][0]) {
  212. case '1':
  213. self.bg = self.community.style1;
  214. break;
  215. case '2':
  216. self.bg = self.community.style2;
  217. break;
  218. case '3':
  219. self.bg = self.community.style3;
  220. break;
  221. case '4':
  222. self.bg = self.community.style4;
  223. break;
  224. }
  225. } else {
  226. uni.showToast({title: info.msg,icon: 'none'});
  227. }
  228. })
  229. },
  230. changeStyle(value) {
  231. let that = this;
  232. that.selectForm.style = value;
  233. switch (that.selectForm.style) {
  234. case 1:
  235. that.bg = that.community.style1;
  236. break;
  237. case 2:
  238. that.bg = that.community.style2;
  239. break;
  240. case 3:
  241. that.bg = that.community.style3;
  242. break;
  243. case 4:
  244. that.bg = that.community.style4;
  245. break;
  246. }
  247. },
  248. changeType(value) {
  249. const self = this;
  250. self.selectForm.type = value;
  251. },
  252. changeColor(value) {
  253. const self = this;
  254. self.selectForm.color = value;
  255. },
  256. submitSave() {
  257. this.$showLoading({text: '生成中'});
  258. let para = this.selectForm;
  259. para.activity_id = this.activity_id;
  260. para.middleman_id = this.middleman_id;
  261. this.$request({
  262. url: this.$api.community.poster_share,
  263. data: this.selectForm
  264. }).then(info => {
  265. this.$hideLoading();
  266. let { code, data, msg } = info;
  267. if (code === 0) {
  268. const pic_url = data.pic_url;
  269. this.$utils.batchSave(pic_url, 'image').then(() => {
  270. uni.showToast({title: '保存成功'});
  271. });
  272. } else {
  273. uni.showToast({title: msg, icon: 'none'});
  274. }
  275. }).catch(() => {
  276. this.$hideLoading();
  277. })
  278. },
  279. },
  280. }
  281. </script>
  282. <style scoped lang="scss">
  283. $box: #f7f7f7;
  284. ::-webkit-scrollbar {
  285. width: 0;
  286. height: 0;
  287. color: transparent;
  288. }
  289. .app-scroll {
  290. width: 100%;
  291. white-space: nowrap;
  292. padding: 0 #{14rpx};
  293. }
  294. .poster-goods {
  295. .head {
  296. width: 100%;
  297. .poster {
  298. margin: #{50rpx} auto;
  299. width: #{450rpx};
  300. height: #{800.4rpx};
  301. background-size: 100% 100%;
  302. background-position: center;
  303. background-repeat: no-repeat;
  304. position: relative;
  305. .activity-bg {
  306. position: absolute;
  307. width: 100%;
  308. height: 100%;
  309. top: 0;
  310. left: 0;
  311. }
  312. .middleman-tip {
  313. position: absolute;
  314. color: #353535;
  315. font-size: #{18rpx};
  316. width: #{358.2rpx};
  317. margin: 0 auto;
  318. .middleman-avatar {
  319. flex-shrink: 0;
  320. width: #{58.2rpx};
  321. height: #{58.2rpx};
  322. margin-right: #{12rpx};
  323. }
  324. }
  325. .goods-list {
  326. position: absolute;
  327. width: 100%;
  328. display: flex;
  329. justify-content: center;
  330. flex-wrap: wrap;
  331. align-items: center;
  332. .goods-price {
  333. color: #ff4544;
  334. }
  335. .goods-original-price {
  336. color: #999999;
  337. text-decoration: line-through;
  338. }
  339. .goods {
  340. height: #{72rpx};
  341. flex-shrink: 0;
  342. margin: 0 15rpx #{31.2rpx};
  343. .goods-cover {
  344. height: #{72rpx};
  345. width: #{72rpx};
  346. margin-right: #{8.4rpx};
  347. border-radius: #{4.8rpx};
  348. }
  349. .goods-info {
  350. width: #{99.6rpx};
  351. align-content: space-between;
  352. font-size: #{14.4rpx};
  353. .goods-original-price {
  354. font-size: #{12rpx};
  355. }
  356. }
  357. }
  358. &.number-1 {
  359. margin-top: #{-12rpx};
  360. .goods {
  361. height: 100%;
  362. .goods-cover {
  363. width: #{216rpx};
  364. height: #{216rpx};
  365. margin-right: 0;
  366. margin: 0 auto;
  367. }
  368. .goods-info {
  369. width: #{348rpx};
  370. text-align: center;
  371. margin: #{12rpx} auto;
  372. font-size: #{16.8rpx};
  373. .goods-price {
  374. margin-top: #{10rpx};
  375. }
  376. .goods-original-price {
  377. font-size: #{14.4rpx};
  378. }
  379. }
  380. }
  381. }
  382. &.number-2 {
  383. margin-top: #{-2.4rpx};
  384. .goods {
  385. height: #{270rpx};
  386. width: #{174rpx};
  387. border: #{2rpx} solid #e2e2e2;
  388. border-radius: #{4.8rpx};
  389. .goods-cover {
  390. width: #{172rpx};
  391. height: #{172rpx};
  392. margin-right: 0;
  393. border-radius: 0;
  394. }
  395. .goods-info {
  396. width: #{153.6rpx};
  397. text-align: center;
  398. margin: #{10rpx} auto;
  399. .goods-price {
  400. margin-top: #{10rpx};
  401. }
  402. }
  403. }
  404. }
  405. &.number-3 {
  406. margin-top: #{-14.4rpx};
  407. .goods {
  408. height: #{90rpx};
  409. margin-bottom: #{19.2rpx};
  410. .goods-cover {
  411. height: #{90rpx};
  412. width: #{90rpx};
  413. margin-right: #{14.4rpx};
  414. }
  415. .goods-info {
  416. width: #{270rpx};
  417. }
  418. }
  419. }
  420. &.number-4 {
  421. margin-top: #{-21.6rpx};
  422. .goods {
  423. margin-bottom: #{12rpx};
  424. .goods-info {
  425. width: #{288rpx};
  426. }
  427. }
  428. }
  429. }
  430. .activity {
  431. position: absolute;
  432. .activity-qrcode {
  433. width: #{216rpx};
  434. height: #{144rpx};
  435. image {
  436. width: #{144rpx};
  437. height: #{144rpx};
  438. }
  439. }
  440. .activity-info {
  441. width: #{198rpx};
  442. font-size: #{13.2rpx};
  443. color: #353535;
  444. .activity-avatar {
  445. width: #{19.8rpx};
  446. height: #{19.8rpx};
  447. margin: 0 #{6rpx};
  448. }
  449. }
  450. }
  451. .style-1 {
  452. .goods-list {
  453. top: #{234rpx};
  454. left: 0;
  455. }
  456. .middleman-tip {
  457. top: #{87.6rpx};
  458. left: #{46.8rpx};
  459. }
  460. .activity {
  461. bottom: #{66rpx};
  462. left: #{38.4rpx};
  463. }
  464. }
  465. .style-2 {
  466. .goods-list {
  467. top: #{114rpx};
  468. left: 0;
  469. }
  470. .middleman-tip {
  471. bottom: #{255rpx};
  472. left: #{48rpx};
  473. }
  474. .activity {
  475. bottom: #{90rpx};
  476. left: 0;
  477. }
  478. }
  479. .style-3 {
  480. .goods-list {
  481. top: #{186rpx};
  482. left: 0;
  483. }
  484. .middleman-tip {
  485. top: #{98.4rpx};
  486. left: #{48rpx};
  487. }
  488. .activity {
  489. bottom: #{54rpx};
  490. left: 0;
  491. }
  492. }
  493. .style-4 {
  494. .goods-list {
  495. top: #{290.4rpx};
  496. left: 0;
  497. }
  498. .middleman-tip {
  499. top: #{68.4rpx};
  500. left: #{33.6rpx};
  501. .middleman-avatar {
  502. margin-right: #{24rpx};
  503. }
  504. }
  505. .activity {
  506. bottom: #{54rpx};
  507. left: 0;
  508. }
  509. }
  510. }
  511. }
  512. .setting {
  513. padding-top: #{20rpx};
  514. font-size: #{24rpx};
  515. color: #353535;
  516. background: #FFFFFF;
  517. padding-bottom: #{48rpx};
  518. .line {
  519. margin-bottom: #{24rpx};
  520. .label {
  521. height: #{56rpx};
  522. icon {
  523. background-image: url("../../../static/image/poster/mark.png");
  524. background-size: 100% 100%;
  525. height: #{21rpx};
  526. width: #{21rpx};
  527. background-repeat: no-repeat;
  528. margin-left: #{24rpx};
  529. border-radius: 50%;
  530. }
  531. text {
  532. line-height: 1;
  533. padding-left: #{12rpx};
  534. padding-right: #{26rpx - 14rpx};
  535. }
  536. }
  537. .style-input {
  538. position: relative;
  539. height: #{56rpx};
  540. padding: 0 #{20rpx};
  541. background: $box;
  542. border-radius: #{5rpx};
  543. margin: 0 #{14rpx};
  544. .type-pure {
  545. height: #{32rpx};
  546. width: #{32rpx};
  547. margin-right: #{10rpx};
  548. background: #d8d8d8;
  549. }
  550. .type-gradient {
  551. height: #{32rpx};
  552. width: #{32rpx};
  553. margin-right: #{10rpx};
  554. background-image: url("./../image/icon.png");
  555. background-size: 100% 100%;
  556. }
  557. }
  558. }
  559. .active {
  560. border-width: #{3rpx};
  561. border-style: solid;
  562. background: #FFFFFF !important;
  563. }
  564. .icon-active {
  565. background-image: url("../../../static/image/poster/input-active.png");
  566. height: #{38rpx};
  567. width: #{38rpx};
  568. background-repeat: no-repeat;
  569. background-size: 100% 100%;
  570. position: absolute;
  571. top: #{-19rpx};
  572. right: #{-19rpx};
  573. z-index: 10;
  574. border-radius: 50%;
  575. }
  576. .line-input {
  577. position: relative;
  578. border-radius: #{5rpx};
  579. margin: 0 #{14rpx} #{14rpx};
  580. background: $box;
  581. width: #{140rpx};
  582. height: #{56rpx};
  583. .icon-square {
  584. background-size: 100% 100%;
  585. height: #{32rpx};
  586. width: #{32rpx};
  587. background-repeat: no-repeat;
  588. }
  589. text {
  590. margin-left: #{10rpx};
  591. }
  592. }
  593. .color-bg {
  594. position: relative;
  595. display: inline-block;
  596. height: #{60rpx};
  597. width: #{60rpx};
  598. border-radius: #{5rpx};
  599. border: 1px solid #e5e5e5;
  600. margin-right: #{26rpx};
  601. margin-top: #{19rpx};
  602. }
  603. }
  604. .button {
  605. font-size: #{32rpx};
  606. border-radius: #{40rpx};
  607. height: #{68rpx};
  608. margin: #{34rpx} auto 0;
  609. color: #ffffff;
  610. width: #{500rpx};
  611. }
  612. }
  613. </style>