info.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. <template>
  2. <view v-if="fetch && fetch.info" @click="Dever.close()">
  3. <use-tabbar :tabbar="false"></use-tabbar>
  4. <view class="swiper-area w-full">
  5. <swiper class="h-full pos-r" indicator-dots circular="true" duration="400">
  6. <swiper-item v-for="(item, index) in fetch.info.pic" :key="index">
  7. <view class="wh-full" @click="viewPic(item, index)">
  8. <image :src="item" class="wh-full loaded" lazy-load="true" mode="aspectFill"></image>
  9. </view>
  10. </swiper-item>
  11. </swiper>
  12. </view>
  13. <!-- 商品数据区 -->
  14. <view class="goods-area use-area margin-lr-sm user-bg-main padding">
  15. <view v-if="fetch.info.price > 0">
  16. <view class="padding-right dflex" v-if="fetch.info.promotion_tag && fetch.info.promotion_tag.name">
  17. <view class="use-tag pos-top bg-base">
  18. {{ fetch.info.promotion_tag.name }}
  19. </view>
  20. </view>
  21. <view class="dflex-b">
  22. <view class="dflex-c" style="display: flex; align-items: center;">
  23. <text class="price fs-big">{{ fetch.info.price_text}}</text>
  24. <text class="m-price" v-if="fetch.info.m_price > 0">{{ fetch.info.m_price_text }}</text>
  25. <u-popover v-if="fetch.info.promotion_text" position="top" width="200px">
  26. <view style="margin-left:5px;display: inline-block;">
  27. <u-icon name="question-circle"></u-icon>
  28. </view>
  29. <template v-slot:content>
  30. <view style="color: white;">
  31. <u-parse :content="fetch.info.promotion_text"></u-parse>
  32. </view>
  33. </template>
  34. </u-popover>
  35. </view>
  36. <view class="dflex ft-dark" v-if="fetch.info.show_sell == 1">
  37. <view class="padding-right-xs">销量:</view>
  38. <text>{{ fetch.info.num_sell }}</text>
  39. </view>
  40. </view>
  41. <view class="margin-top padding-right dflex">
  42. <text class="title fs-30 fwbd clamp-2">{{ fetch.info.name }}</text>
  43. </view>
  44. <view class="margin-top-sm padding-right dflex-b"
  45. v-if="fetch.info.rebate && fetch.info.rebate.buy && fetch.info.rebate.buy.desc">
  46. <view class="dflex-c">
  47. <view class="dflex padding-16 border-radius-sm bg-drak rebate-line">
  48. <text class="icon icon-jifen">🎁</text>
  49. <text class="fs-xs label">{{ fetch.info.rebate.buy.name }}:</text>
  50. <text class="fs-xs score value">{{ fetch.info.rebate.buy.desc }}</text>
  51. </view>
  52. </view>
  53. </view>
  54. <view class="padding-right dflex-b"
  55. v-if="fetch.info.rebate && fetch.info.rebate.share && fetch.info.rebate.share.desc">
  56. <view class="dflex-c">
  57. <view class="dflex padding-16 border-radius-sm bg-drak rebate-line">
  58. <text class="icon icon-yongjin">💰</text>
  59. <text class="fs-xs label">{{ fetch.info.rebate.share.name }}:</text>
  60. <text class="fs-xs score value">{{ fetch.info.rebate.share.desc }}</text>
  61. </view>
  62. </view>
  63. <!--
  64. <view class="dflex">
  65. <view class="border-radius-lg bg-drak dflex-c use-hover">
  66. <view class="dflex-c wh-full">
  67. <view class="iconfont iconfenxiang"></view>
  68. </view>
  69. </view>
  70. </view>-->
  71. </view>
  72. </view>
  73. <view v-else>
  74. <view class="padding-right dflex">
  75. <text class="title fs-30 fwbd clamp-2">{{ fetch.info.name }}</text>
  76. </view>
  77. <view class="margin-top dflex-b">
  78. <text v-if="fetch.info.info" class="price-desc">{{ fetch.info.info }}</text>
  79. <text v-else class="price free-tag">免费</text>
  80. <text class="m-price" v-if="fetch.info.m_price > 0">{{ fetch.info.m_price_text }}</text>
  81. </view>
  82. </view>
  83. </view>
  84. <view class="show-area use-area padding-tb-sm"
  85. v-if="fetch && ((fetch.sku && fetch.spec && fetch.spec.length > 0) || (fetch.info.price > 0 && fetch.coupon && fetch.coupon.length > 0) || (fetch.help && fetch.help.length > 0))">
  86. <view class="show-sku-area">
  87. <view class="dflex-b padding-tb-16 use-hover" @click="open('sku')"
  88. v-if="fetch && fetch.sku && fetch.spec && fetch.spec.length > 0">
  89. <view class="dflex">
  90. <view class="ft-dark">已选</view>
  91. <text>{{fetch.info.sku_name}}</text>
  92. </view>
  93. <view class="dflex-c">
  94. <view class="iconfont iconjiantou-01 fs-sm ft-dark"></view>
  95. </view>
  96. </view>
  97. <u-popup :show="show.sku" @close="close('sku')" round="25">
  98. <view class="bg-main padding border-radius-top30 safe-area-inset-bottom"
  99. style="min-height: 66vh; max-height: 80vh;" v-if="fetch && fetch.sku">
  100. <!-- 商品信息 -->
  101. <view class="dflex margin-top-xs">
  102. <image class="" style="width: 48px; height: 48px;"
  103. :src="fetch.sku.pic ? fetch.sku.pic : fetch.info.pic[0]"
  104. @click="viewSkuPic" />
  105. <view class="margin-left-sm">
  106. <view class="dflex" style="align-items: flex-end;">
  107. <view class="price fs-big">{{ fetch.sku.price_text}}</view>
  108. <text class="m-price"
  109. v-if="fetch.sku.m_price > 0">{{ fetch.sku.m_price_text }}</text>
  110. </view>
  111. <view class="use-tags margin-0 margin-top-sm">
  112. <view
  113. v-if="fetch.sku.rebate && fetch.sku.rebate.buy && fetch.sku.rebate.buy.desc">
  114. 返{{fetch.sku.rebate.buy.desc}}</view>
  115. <view
  116. v-if="fetch.sku.rebate && fetch.sku.rebate.share && fetch.sku.rebate.share.desc">
  117. 赚{{fetch.sku.rebate.share.desc}}</view>
  118. <!--
  119. <view v-if="fetch.sku.unum > 0">赠{{ fetch.sku.unum}}次</view>-->
  120. </view>
  121. </view>
  122. </view>
  123. <!-- 滚动属性选择区域 -->
  124. <scroll-view scroll-y="true" class="overflow-auto" style="max-height: 50vh;">
  125. <view v-for="(item, index) in fetch.spec" :key="index">
  126. <view class="margin-tb-sm">
  127. <text class="fwbd">{{item.name}} ({{item.value.length}})</text>
  128. </view>
  129. <view class="dflex dflex-wrap-w">
  130. <view class="dflex margin-right-sm margin-bottom-sm use-hover"
  131. v-for="(v, k) in item.value" :key="k"
  132. :class="v.selected ? 'tag-base' : 'tag-gray'" @click.stop="sku(index, k)">
  133. <view>{{v.value}}</view>
  134. </view>
  135. </view>
  136. </view>
  137. </scroll-view>
  138. <!-- 购买数量 -->
  139. <view class="padding-tb-sm margin-top dflex-b pos-r">
  140. <view class="dflex pos-r" style="top: 4px;">
  141. <view>购买数量</view>
  142. <text v-if="fetch.sku.stock.num > 0" class="margin-left-sm ft-dark fs-xs"
  143. style="width: auto">库存{{fetch.sku.stock.num}}件</text>
  144. </view>
  145. <u-number-box :integer="true" :step="1" :min="1"
  146. :max="fetch.sku.stock.num >= 0 ? fetch.sku.stock.num : 9999" v-model="num"
  147. @change="operNumber"></u-number-box>
  148. </view>
  149. <!-- 底部按钮占位 -->
  150. <view class="w-full" style="height: 76px;"></view>
  151. <!-- 操作按钮 -->
  152. <view class="pos-a pos-b-full padding safe-area-inset-bottom-plus dflex-c">
  153. <view class="flex1 btn-container dflex-b border-radius-big margin-top">
  154. <!--
  155. <view class="dflex-c padding-tb-sm flex1 bg-warn use-hover">
  156. <text>加入购物车</text>
  157. </view>
  158. -->
  159. <view class="dflex-c padding-tb-sm flex1 bg-base use-hover"
  160. v-if="fetch.sku.stock.num > 0 || fetch.sku.stock.num < 0"
  161. @click="buy(fetch.sku)">
  162. <text>立即购买</text>
  163. </view>
  164. <view class="dflex-c padding-tb-sm flex1 bg-base use-hover bg-disabled" v-else>已售磐
  165. </view>
  166. </view>
  167. </view>
  168. </view>
  169. </u-popup>
  170. </view>
  171. <view class="show-coupon-area" v-if="fetch.info.price > 0 && fetch.coupon && fetch.coupon.length > 0">
  172. <view class="dflex-b padding-tb-16 use-hover" @click="open('coupon')">
  173. <view class="dflex">
  174. <view class="ft-dark">优惠</view>
  175. <text>领取优惠券</text>
  176. </view>
  177. <view class="dflex-c">
  178. <view class="bg-base padding-lr-xs border-radius-lg fs-xxs margin-right-xs">去领取</view>
  179. <view class="iconfont iconjiantou-01 fs-sm ft-dark"></view>
  180. </view>
  181. </view>
  182. <u-popup :show="show.coupon" @close="close('coupon')" round="25">
  183. <!-- 优惠券区 -->
  184. <scroll-view class="popup-area coupon-area border-radius-top30 padding bg-drak"
  185. v-if="fetch && fetch.coupon && fetch.coupon.length > 0" scroll-y="true">
  186. <view class="coupon-item bg-main pos-r fs-xs" v-for="(item, index) in fetch.coupon"
  187. :key="index">
  188. <view class="content pos-r padding dflex-b">
  189. <view class="">
  190. <view class="margin-bottom-xs fs">{{ item.name }}</view>
  191. <view class="ft-dark">{{item.date_name}}</view>
  192. </view>
  193. <view class="tar">
  194. <view class="margin-bottom-xs price" v-if="item.type == 4">{{ item.value }}个
  195. </view>
  196. <view class="margin-bottom-xs price" v-if="item.type == 3">{{ item.value }}折
  197. </view>
  198. <view class="margin-bottom-xs price" v-else>{{ item.value }}</view>
  199. <view class="ft-dark">{{ item.title }}</view>
  200. </view>
  201. <view class="circle l"></view>
  202. <view class="circle r"></view>
  203. </view>
  204. <view class="dflex-b">
  205. <text class="ft-dark padding-lr">{{ item.type_name }}</text>
  206. <text class="submit dflex-c border-radius-big padding-lr animated-all bg-base"
  207. @click="getCoupon(item.id)">立即领取</text>
  208. </view>
  209. </view>
  210. </scroll-view>
  211. <view v-else class="popup-area coupon-area border-radius-top30 padding bg-drak dflex-c">暂无优惠券</view>
  212. </u-popup>
  213. </view>
  214. <!-- 服务 -->
  215. <view class="show-help-area" v-if="fetch.help && fetch.help.length > 0">
  216. <view class="dflex-b padding-tb-16 use-hover" v-for="(item, index) in fetch.help" :key="index"
  217. @click="open('help', index)">
  218. <view class="dflex">
  219. <view class="ft-dark">{{item.name}}</view>
  220. <view v-for="(v, k) in item.list" :key="k">
  221. <text class="dot margin-right-xs" v-if="k > 0"></text>
  222. <text class="margin-right-xs">{{v.name}}</text>
  223. </view>
  224. </view>
  225. <view class="dflex-c">
  226. <view class="iconfont iconjiantou-01 fs-sm ft-dark"></view>
  227. </view>
  228. </view>
  229. <u-popup :show="show.help" @close="close('help')" round="25">
  230. <view v-for="(item, index) in fetch.help" :key="index" v-if="show.help_content[index]"
  231. class="bg-main border-radius-top30 safe-area-inset-bottom">
  232. <view class="tac fwbd w-full padding-lr padding-tb-xl fs-34">{{item.name}}</view>
  233. <scroll-view scroll-y="true" class="popup-area padding-lr-lg padding-bottom">
  234. <view v-for="(v, k) in item.list" :key="k" class="margin-right-sm dflex dflex-s">
  235. <view class="iconfont iconyiwancheng- fwbd fs ft-base margin-right-xs line-height-0"
  236. style="display: none;"></view>
  237. <view>
  238. <view class="fs-30 fwbd line-height-0">{{ v.name }}</view>
  239. <view class="margin-top margin-bottom-sm ft-dark-3">{{ v.info }}</view>
  240. </view>
  241. </view>
  242. </scroll-view>
  243. <view class="padding w-full margin-top dflex-c border-radius-big" @click="close('help')">
  244. <view class="border-radius-big" style="width: 60vw;">
  245. <view class="padding-tb-sm dflex-c bg-base">确认</view>
  246. </view>
  247. </view>
  248. </view>
  249. </u-popup>
  250. </view>
  251. </view>
  252. <!-- 评价区 -->
  253. <view class="use-area evaluate-area margin-lr-sm" v-if="fetch.review && fetch.review.length > 0">
  254. <view class="dflex-b use-hover">
  255. <view class="dflex fwbd">评价({{ fetch.review_total }})</view>
  256. <view class="dflex-c">
  257. <text class="margin-right-xs ft-dark"
  258. @click="Dever.location('source/review?id=' + fetch.info.id)">查看全部</text>
  259. <text class="iconfont iconjiantou-01 fs-sm ft-dark"></text>
  260. </view>
  261. </view>
  262. <view v-for="(item, index) in fetch.review" :key="index" class="margin-top border-line">
  263. <view class="dflex-b">
  264. <view class="dflex">
  265. <image class="headimg border-radius-c" :src="item.user.avatar" mode="aspectFill"
  266. @click="Dever.pic.preview([item.user.avatar], item.user.avatar)"></image>
  267. <view class="right-area flex1 padding-left-sm">
  268. <view class="margin-right">
  269. <view class="fwbd">{{ item.user.name }}</view>
  270. <view class="use-rate dflex line-height-1">
  271. <view v-for="i in 5" :key="i" class="pos-r margin-left-sm"
  272. :style="{ marginLeft: '0px' }">
  273. <text class="iconfont"
  274. :class="i <= item.rate ? 'iconshoucang- ft-base fs' : 'iconshoucang-01 ft-dark fs'"></text>
  275. </view>
  276. </view>
  277. </view>
  278. </view>
  279. </view>
  280. <text class="time ft-dark fs-xs">{{ item.cdate_str }}</text>
  281. </view>
  282. <view class="content-area margin-top-xs">
  283. <view class="ft-main margin-top-xs margin-bottom-sm clamp-2">
  284. {{ item.content || '此用户没有填写评价' }}
  285. </view>
  286. <view class="dflex dflex-wrap-w" v-if="item.pic && item.pic.length > 0">
  287. <view v-for="(img, i) in item.pic" :key="i" class="dflex-c image-area border-radius">
  288. <image :src="img" mode="aspectFill" style="height: 166px;"
  289. @click="Dever.pic.preview([item.pic], img)" />
  290. </view>
  291. </view>
  292. <view class="padding-bottom-sm">
  293. <text class="fs-xxs ft-dark">{{ item.style }}</text>
  294. </view>
  295. </view>
  296. </view>
  297. </view>
  298. <view class="detail-area use-area margin-lr-sm bg-main" v-if="fetch.tab && fetch.tab.length > 0">
  299. <view class="flex-center">
  300. <u-tabs :list="fetch.tab" @click="setTab"></u-tabs>
  301. </view>
  302. <view class="detail-area" v-if="tab.id > 0">
  303. <view class="list-item" v-for="(item, index) in fetch.list" :key="index">
  304. <view v-if="item.name" @click="goContentInfo(item)">
  305. <view class="item-header">
  306. <text class="name">{{ item.name }}</text>
  307. <view class="icons">
  308. <u-icon v-if="item.look == 2" name="lock" size="18" color="#ff9800"></u-icon>
  309. <u-icon v-if="item.look >= 3" name="integral" size="18" color="#4caf50"></u-icon>
  310. </view>
  311. </view>
  312. <text class="desc">{{ item.info }}</text>
  313. </view>
  314. <view class="detail-area" v-else>
  315. <u-parse :content="item.info"></u-parse>
  316. </view>
  317. </view>
  318. <view class="view-more" @click="goContent(tab.id)" v-if="tab.more == 1">
  319. 查看更多 >
  320. </view>
  321. </view>
  322. <view class="detail-area" v-else>
  323. <u-parse :content="fetch.info.content"></u-parse>
  324. </view>
  325. </view>
  326. <!-- 详情区 -->
  327. <!--
  328. <view class="detail-area use-area margin-lr-sm bg-main" v-if="fetch.info.content">
  329. <view class="d-header padding dflex-c"><text>图文详情</text></view>
  330. <u-parse :content="fetch.info.content"></u-parse>
  331. </view>-->
  332. <!-- 操作区 -->
  333. <view id="view-more" class="oper-area pos-f dflex-b w-full padding-lr-sm" style="justify-content: left;">
  334. <!--
  335. <view class="btn-area dflex dflex-flow-c"
  336. @click="Dever.location('source/home?id=' + fetch.info.channel_id)">
  337. <text class="iconfont iconshouye-1"></text>
  338. <text>首页</text>
  339. </view>-->
  340. <!--
  341. <button class="btn no-border dflex" open-type="contact">
  342. <view class="btn-area dflex-c dflex-flow-c">
  343. <u-icon
  344. name="kefu-ermai"
  345. size="25"
  346. ></u-icon>
  347. <text>客服</text>
  348. </view>
  349. </button>
  350. -->
  351. <view class="btn-area dflex dflex-flow-c" :class="{ active: fetch.collect }" @click="setCollect">
  352. <u-icon v-if="fetch.collect" name="star-fill" size="25" color="#ff6a6c"></u-icon>
  353. <u-icon v-else name="star" size="25"></u-icon>
  354. <text>收藏</text>
  355. </view>
  356. <view class="btn-area dflex dflex-flow-c" @click="shareOpen">
  357. <u-icon name="share" size="25"></u-icon>
  358. <text>分享</text>
  359. </view>
  360. <!--
  361. <view class="btn-area dflex dflex-flow-c" v-if="fetch.content"
  362. @click="Dever.location('source/content?id=' + fetch.info.id)">
  363. <u-icon name="list-dot" size="25"></u-icon>
  364. <text>{{fetch.info.content_name}}</text>
  365. </view>
  366. <view class="btn-area dflex dflex-flow-c" v-if="fetch.tool"
  367. @click="Dever.location('source/tool?id=' + fetch.info.id)">
  368. <u-icon name="grid" size="25"></u-icon>
  369. <text>{{fetch.info.func_name}}</text>
  370. </view>-->
  371. <view class="flex1 btn-container dflex-b border-radius-big"
  372. v-if="fetch.info.show_submit == 1 && fetch.sku && fetch.spec && fetch.spec.length >= 0">
  373. <!--<view class="tac padding-tb-sm flex1 bg-warn" v-if="fetch.info.stock > 0 || fetch.info.stock < 0" @click="tocart()">加入购物车
  374. </view>
  375. -->
  376. <view class="tac padding-tb-sm flex1 bg-base"
  377. v-if="fetch.info.stock.num > 0 || fetch.info.stock.num < 0" @click="pay()">立即下单
  378. </view>
  379. <view class="tac padding-tb-sm flex1 bg-disabled" v-else>已售磐</view>
  380. </view>
  381. <view class="flex1 btn-container dflex-b border-radius-big" v-else>
  382. <view class="tac padding-tb-sm flex1 bg-disabled">载入中</view>
  383. </view>
  384. </view>
  385. <use-totop ref="usetop"></use-totop>
  386. <u-modal ref="posterModal" :show="poster.show" :title="poster.title" :closeOnClickOverlay="true"
  387. @close="closePoster" @confirm="closePoster">
  388. <view class="slot-content">
  389. <u-poster @success="success" :palette="poster.value" :width="poster.width"></u-poster>
  390. <view class="flex1 poster-btn-container dflex-b">
  391. <view class="btn btn-warn" @click="save()">保存相册</view>
  392. <button open-type="share" class="btn btn-base" @click="share()">分享好友</button>
  393. </view>
  394. </view>
  395. </u-modal>
  396. </view>
  397. </template>
  398. <script>
  399. export default {
  400. data() {
  401. return {
  402. id: 0,
  403. num: 1,
  404. fetch: {
  405. collect: false,
  406. },
  407. // 弹窗展示
  408. show: {
  409. sku: false,
  410. coupon: false,
  411. help: false,
  412. help_content: [],
  413. },
  414. poster: {
  415. show: false,
  416. title: '分享好友',
  417. width: 255,
  418. value: {},
  419. file: '',
  420. },
  421. tab: {
  422. id: -1,
  423. name: '详情'
  424. },
  425. };
  426. },
  427. watch: {
  428. 'poster.show'(val) {
  429. if (val) {
  430. this.$nextTick(() => {
  431. // 获取 modal 内容宽度
  432. const query = uni.createSelectorQuery().in(this);
  433. query.select('.slot-content').boundingClientRect(rect => {
  434. if (rect) {
  435. this.poster.width = rect.width; // 设置给 u-poster
  436. }
  437. }).exec();
  438. });
  439. }
  440. }
  441. },
  442. onPageScroll(e) {
  443. this.$refs.usetop.change(e.scrollTop);
  444. },
  445. onLoad(options) {
  446. let title = '资源详情';
  447. if (options) {
  448. this.id = options.id;
  449. if (options.title) {
  450. title = options.title;
  451. }
  452. }
  453. uni.setNavigationBarTitle({
  454. title: title
  455. })
  456. //#ifdef MP-WEIXIN
  457. wx.hideShareMenu({
  458. menus: ['shareAppMessage', 'shareTimeline']
  459. })
  460. //#endif
  461. this.load();
  462. },
  463. onPullDownRefresh() {
  464. this.load();
  465. },
  466. // 小程序分享
  467. onShareAppMessage(res) {
  468. if (res.from === 'button' && this.fetch && this.fetch.path) {
  469. return {
  470. title: this.fetch.info.name,
  471. path: this.fetch.path,
  472. imageUrl: this.fetch.info.pic[0],
  473. }
  474. }
  475. return null
  476. },
  477. methods: {
  478. load() {
  479. this.loadData();
  480. this.loadSpec();
  481. this.loadCoupon();
  482. },
  483. loadData() {
  484. this.DeverApi.get(this, 'source.info', {
  485. id: this.id
  486. }, res => {
  487. uni.setNavigationBarTitle({
  488. title: res.info.name
  489. });
  490. if (res.tab.length > 0) {
  491. this.setTab(res.tab[0]);
  492. }
  493. }, err => {
  494. this.Dever.goHome()
  495. });
  496. },
  497. loadSpec() {
  498. this.DeverApi.get(this, 'source.spec', {
  499. id: this.id
  500. });
  501. this.loadSku('', 0);
  502. },
  503. loadSku(spec, sku_id) {
  504. this.DeverApi.get(this, 'source.sku', {
  505. id: this.id,
  506. spec: spec,
  507. sku_id: sku_id,
  508. });
  509. },
  510. loadContent(channel_id) {
  511. this.DeverApi.get(this, 'source.contentList', {
  512. id: this.id,
  513. cid: channel_id,
  514. });
  515. },
  516. loadCoupon() {
  517. this.DeverApi.get(this, 'coupon.getList', {
  518. source_id: this.id
  519. });
  520. },
  521. getCoupon(id) {
  522. this.DeverApi.post('coupon.receive', {
  523. id: id
  524. }, r => {
  525. this.Dever.success(r, () => {
  526. this.close('coupon');
  527. });
  528. });
  529. },
  530. setTab(e) {
  531. this.tab = e
  532. if (this.tab.id > 0) {
  533. this.loadContent(this.tab.id);
  534. }
  535. uni.pageScrollTo({
  536. selector: '#view-more',
  537. duration: 300
  538. })
  539. },
  540. goContent(channel_id) {
  541. this.Dever.location('source/content?id=' + this.fetch.info.id + '&cid=' + channel_id)
  542. },
  543. pay() {
  544. if (this.fetch && this.fetch.sku && this.fetch.spec && this.fetch.spec.length > 0) {
  545. this.open('sku');
  546. } else {
  547. this.buy(this.fetch.sku);
  548. }
  549. },
  550. open(key, index) {
  551. this.show[key] = true;
  552. if (index >= 0) {
  553. this.show[key + '_content'] = []
  554. this.show[key + '_content'][index] = true;
  555. }
  556. },
  557. close(key) {
  558. this.show[key] = false;
  559. if (key == 'help') {
  560. this.show[key + '_content'] = []
  561. }
  562. },
  563. operNumber(e) {
  564. this.num = e.value;
  565. },
  566. sku(spec, value) {
  567. console.info(spec)
  568. var key = this.fetch.sku.key.split(',');
  569. this.fetch.spec[spec].value.forEach((v, k) => {
  570. if (value == k) {
  571. v.selected = true;
  572. key[spec] = v.id;
  573. } else {
  574. v.selected = false;
  575. }
  576. })
  577. key = key.join(',');
  578. this.loadSku(key, this.fetch.sku.id);
  579. },
  580. viewPic(pic, index) {
  581. this.Dever.pic.preview(this.fetch.info.pic, pic);
  582. },
  583. viewSkuPic() {
  584. var value = this.fetch.info.pic[0]
  585. if (this.fetch.sku.pic) {
  586. value = this.fetch.sku.pic;
  587. this.Dever.pic.preview([value], value);
  588. } else {
  589. this.Dever.pic.preview([value], value);
  590. }
  591. },
  592. buy(sku) {
  593. if (!this.DeverApi.getToken()) {
  594. this.Dever.confirm('您需要登录才能继续操作', () => {
  595. this.Dever.goLogin();
  596. })
  597. return;
  598. }
  599. var detail = [{
  600. id: this.fetch.info.id,
  601. sku_id: sku.id,
  602. num: this.num
  603. }]
  604. this.Dever.data('detail', {
  605. type: 'source',
  606. type_id: this.fetch.info.cate_id,
  607. detail: detail,
  608. jump: 'order/info',
  609. });
  610. this.Dever.location('order/create');
  611. },
  612. setCollect() {
  613. this.fetch.collect = !this.fetch.collect;
  614. if (this.fetch.collect) {
  615. var url = 'collect.up';
  616. } else {
  617. var url = 'collect.cancel';
  618. }
  619. this.DeverApi.post(url, {
  620. type: 1,
  621. type_id: this.id
  622. });
  623. },
  624. save() {
  625. if (this.Dever.env == 2) {
  626. const link = document.createElement('a')
  627. link.href = this.file
  628. link.download = 'share.png'
  629. link.click()
  630. uni.showToast({
  631. title: '已保存到相册',
  632. icon: 'none'
  633. })
  634. } else if (this.Dever.env == 3) {
  635. uni.showToast({
  636. title: '请长按保存到相册',
  637. icon: 'none'
  638. })
  639. } else {
  640. uni.saveImageToPhotosAlbum({
  641. filePath: this.file,
  642. success: () => {
  643. uni.showToast({
  644. title: '已保存到相册',
  645. icon: 'success'
  646. })
  647. },
  648. fail: (err) => {
  649. console.error('保存失败:', err)
  650. // 可能是没有权限
  651. uni.showModal({
  652. title: '提示',
  653. content: '请开启相册权限后重试',
  654. showCancel: false
  655. })
  656. }
  657. })
  658. }
  659. },
  660. goContentInfo(item) {
  661. if (item.look == 2) {
  662. // 购买规格
  663. this.Dever.confirm(item.buy, () => {
  664. this.buyContent(item)
  665. });
  666. } else if (item.look >= 3) {
  667. this.Dever.confirm(item.score, () => {
  668. this.DeverApi.post('source.contentBuy', {
  669. id: item.id
  670. }, r => {
  671. this.Dever.success('付费成功', () => {
  672. this.Dever.location('source/content_info?id=' + item.id +
  673. '&title=' + item.name)
  674. })
  675. });
  676. });
  677. } else {
  678. this.Dever.location('source/content_info?id=' + item.id + '&title=' + item.name)
  679. }
  680. },
  681. buyContent(item) {
  682. if (!this.DeverApi.getToken()) {
  683. this.Dever.confirm('您需要登录才能继续操作', () => {
  684. this.Dever.goLogin();
  685. })
  686. return;
  687. }
  688. var detail = [{
  689. id: item.info_id,
  690. sku_id: item.sku_id,
  691. num: 1
  692. }]
  693. this.Dever.data('detail', {
  694. type: 'source',
  695. type_id: item.cate_id,
  696. detail: detail,
  697. jump: 'source/content_info?id=' + item.id + '&title=' + item.name,
  698. });
  699. this.Dever.location('order/create');
  700. },
  701. success(file) {
  702. this.poster.file = file;
  703. },
  704. closePoster() {
  705. this.poster.show = false;
  706. },
  707. share() {
  708. //this.closePoster();
  709. },
  710. shareOpen() {
  711. this.DeverApi.get(this, 'user.code', {
  712. type: this.id
  713. }, res => {
  714. this.poster.show = true;
  715. this.poster.value = {
  716. "width": "375px",
  717. "height": "500px",
  718. "background": "#ff6a6c",
  719. "background": "#fff",
  720. "views": [{
  721. "type": "rect",
  722. "style": {
  723. "width": "356px",
  724. "height": "473px",
  725. "top": "11px",
  726. "left": "8px",
  727. "background": "#fff",
  728. "borderRadius": "10px",
  729. "zindex": 1,
  730. "color": "#fff"
  731. }
  732. },
  733. {
  734. "type": "text",
  735. "text": this.fetch.info.price ? this.fetch.info.price_text : '',
  736. "style": {
  737. "width": "180px",
  738. "height": "31px",
  739. "top": "359px",
  740. "left": "25px",
  741. "background": "transparent",
  742. "borderColor": "transparent",
  743. "zindex": 10,
  744. "color": "#ff6a6c",
  745. "fontSize": "28px",
  746. "fontFamily": "Arial"
  747. }
  748. },
  749. {
  750. "type": "text",
  751. "text": this.fetch.info.price ? '' : this.fetch.info.info,
  752. "style": {
  753. "width": "252px",
  754. "height": "20px",
  755. "top": "437px",
  756. "left": "26px",
  757. "background": "transparent",
  758. "borderColor": "transparent",
  759. "zindex": 11,
  760. "color": "#333",
  761. "fontSize": "16px",
  762. "lineHeight": 1.16,
  763. "maxLines": "2",
  764. "fontFamily": "Arial"
  765. }
  766. },
  767. {
  768. "type": "image",
  769. "url": this.fetch.info.pic[0],
  770. "style": {
  771. "width": "321px",
  772. "height": "321px",
  773. "top": "30px",
  774. "left": "25px",
  775. "borderColor": "transparent",
  776. "borderRadius": "10px",
  777. "zindex": 10,
  778. "mode": "scaleToFill"
  779. }
  780. },
  781. {
  782. "type": "text",
  783. "text": this.fetch.info.name,
  784. "style": {
  785. "width": "252px",
  786. "height": "59px",
  787. "top": "404px",
  788. "left": "24px",
  789. "background": "transparent",
  790. "borderColor": "transparent",
  791. "zindex": 11,
  792. "color": "#000000",
  793. "fontSize": "18px",
  794. "lineHeight": 1.5,
  795. "maxLines": 2,
  796. "fontFamily": "Arial"
  797. }
  798. }
  799. ]
  800. }
  801. if (this.Dever.env == 5) {
  802. this.poster.value.views.push({
  803. "type": "image",
  804. "url": res.qrcode,
  805. "style": {
  806. "width": "58px",
  807. "height": "58px",
  808. "top": "404px",
  809. "left": "286px",
  810. "background": "#ffffff",
  811. "color": "#000000",
  812. "zindex": 100
  813. }
  814. });
  815. } else {
  816. this.poster.value.views.push({
  817. "type": "qrcode",
  818. "content": res.link,
  819. "style": {
  820. "width": "58px",
  821. "height": "58px",
  822. "top": "404px",
  823. "left": "286px",
  824. "background": "#ffffff",
  825. "color": "#000000",
  826. "zindex": 100
  827. }
  828. });
  829. }
  830. });
  831. }
  832. }
  833. };
  834. </script>
  835. <style lang="scss">
  836. page {
  837. background: $page-color-base;
  838. padding-bottom: 120rpx;
  839. }
  840. contact-button {
  841. display: flex;
  842. justify-content: center;
  843. align-items: center;
  844. width: 50px;
  845. height: 50px;
  846. }
  847. .score {
  848. margin-right: 10rpx;
  849. }
  850. .fixed-top {
  851. bottom: 230rpx;
  852. }
  853. /* 轮播区 */
  854. .swiper-area {
  855. position: relative;
  856. height: 720rpx;
  857. top: 0;
  858. }
  859. /* #ifndef MP */
  860. .swiper-area {}
  861. /* #endif */
  862. /* #ifdef APP-PLUS */
  863. .swiper-area {
  864. margin-top: 0;
  865. }
  866. /* #endif */
  867. /* 商品数据区 */
  868. .goods-area {
  869. .price-box {
  870. display: flex;
  871. align-items: baseline;
  872. }
  873. .title {
  874. color: $font-color-dark;
  875. height: 46rpx;
  876. line-height: 46rpx;
  877. }
  878. }
  879. .show-area {
  880. padding: 28rpx;
  881. .dflex .ft-dark {
  882. width: 88rpx;
  883. }
  884. .dot {
  885. width: 6rpx;
  886. height: 6rpx;
  887. border-radius: 50%;
  888. background: #bbb;
  889. display: inline-block;
  890. position: relative;
  891. top: -8rpx;
  892. }
  893. }
  894. .share-area {
  895. .vertical-line {
  896. right: 50%;
  897. height: 40%;
  898. }
  899. }
  900. /* 评价 */
  901. .evaluate-area {
  902. padding: 28rpx;
  903. .headimg {
  904. flex-shrink: 0;
  905. width: 80rpx;
  906. height: 80rpx;
  907. }
  908. .right-area {
  909. image {
  910. margin-right: 10rpx;
  911. margin-bottom: 10rpx;
  912. height: 200rpx;
  913. width: 30%;
  914. }
  915. }
  916. }
  917. /* 详情区 */
  918. .detail-area {
  919. padding-top: 4rpx;
  920. padding-left: 14rpx;
  921. padding-right: 14rpx;
  922. .d-header {
  923. font-size: $font-base + 2upx;
  924. color: $font-color-dark;
  925. position: relative;
  926. text {
  927. padding: 0 20rpx;
  928. background: #fff;
  929. position: relative;
  930. z-index: 1;
  931. }
  932. &:after {
  933. position: absolute;
  934. left: 50%;
  935. top: 50%;
  936. transform: translateX(-50%);
  937. width: 300rpx;
  938. height: 0;
  939. content: '';
  940. border-bottom: 1px solid #ccc;
  941. }
  942. }
  943. /* 产品详情 */
  944. .pro-detail {
  945. width: 100%;
  946. overflow: hidden;
  947. -webkit-touch-callout: none;
  948. img {
  949. width: 100%;
  950. max-width: 100%;
  951. overflow: hidden;
  952. }
  953. }
  954. }
  955. /* 操作区 */
  956. .oper-area {
  957. left: 0;
  958. bottom: 0;
  959. background: rgba(255, 255, 255, 0.95);
  960. box-shadow: 0 0 20rpx 0 #f0f0f0;
  961. height: 100rpx;
  962. z-index: 95;
  963. .btn-area {
  964. font-size: $font-sm;
  965. color: $font-color-base;
  966. width: 96rpx;
  967. .iconfont {
  968. font-size: 40rpx;
  969. line-height: 48rpx;
  970. }
  971. }
  972. }
  973. .rebate-info {
  974. margin-top: 8rpx;
  975. font-size: 24rpx;
  976. color: #555;
  977. }
  978. .rebate-line {
  979. display: flex;
  980. align-items: center;
  981. margin-bottom: 4rpx;
  982. }
  983. .rebate-line .icon {
  984. margin-right: 6rpx;
  985. }
  986. .rebate-line .label {
  987. color: #999;
  988. margin-right: 4rpx;
  989. }
  990. .rebate-line .value {
  991. color: #e64340;
  992. font-weight: bold;
  993. }
  994. .free-tag {
  995. color: #4caf50;
  996. /* 绿色 */
  997. background-color: #e6f5ea;
  998. padding: 4rpx 10rpx;
  999. border-radius: 6rpx;
  1000. font-size: 24rpx;
  1001. }
  1002. .use-tag {
  1003. border-top-left-radius: 5px;
  1004. border-bottom-right-radius: 5px;
  1005. line-height: 1;
  1006. padding: 4px 6px;
  1007. font-size: 11px;
  1008. }
  1009. .price-desc {
  1010. font-size: 24rpx;
  1011. color: #666;
  1012. font-weight: normal;
  1013. }
  1014. .poster-btn-container {
  1015. margin-top: 20rpx;
  1016. gap: 20rpx;
  1017. /* 按钮之间留点间距 */
  1018. }
  1019. .btn {
  1020. flex: 1;
  1021. text-align: center;
  1022. padding: 20rpx 0;
  1023. border-radius: 50rpx;
  1024. /* 圆角胶囊效果 */
  1025. font-size: 28rpx;
  1026. font-weight: 600;
  1027. color: #fff;
  1028. box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.15);
  1029. /* 阴影增强层次感 */
  1030. transition: all 0.3s;
  1031. }
  1032. /* 悬停/点击时稍微缩小,增加交互感 */
  1033. .btn:active {
  1034. transform: scale(0.96);
  1035. opacity: 0.9;
  1036. }
  1037. .btn-warn {
  1038. background: linear-gradient(135deg, #ff7b47 0%, #ff4e50 100%);
  1039. }
  1040. .btn-base {
  1041. background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  1042. }
  1043. .flex-center {
  1044. display: flex;
  1045. justify-content: center;
  1046. }
  1047. .item-header .u-icon {
  1048. margin-right: 10rpx;
  1049. }
  1050. .detail-area {
  1051. padding: 16rpx;
  1052. }
  1053. .list-item {
  1054. background: #fff;
  1055. border-radius: 12rpx;
  1056. padding: 24rpx;
  1057. margin-bottom: 20rpx;
  1058. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
  1059. }
  1060. .item-header {
  1061. display: flex;
  1062. justify-content: space-between;
  1063. align-items: center;
  1064. margin-bottom: 12rpx;
  1065. }
  1066. .name {
  1067. font-size: 32rpx;
  1068. font-weight: 600;
  1069. color: #333;
  1070. }
  1071. .icons {
  1072. display: flex;
  1073. gap: 12rpx;
  1074. }
  1075. .desc {
  1076. margin-top: 10rpx;
  1077. font-size: 26rpx;
  1078. color: #666;
  1079. word-break: break-word;
  1080. white-space: normal;
  1081. line-height: 1.6;
  1082. }
  1083. .view-more {
  1084. text-align: center;
  1085. font-size: 28rpx;
  1086. color: #409EFF;
  1087. /* 蓝色 */
  1088. padding: 20rpx 0;
  1089. }
  1090. </style>