detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <template>
  2. <view class="">
  3. <!-- 顶部导航 -->
  4. <fa-navbar title="详情"></fa-navbar>
  5. <!-- 内容 -->
  6. <view class="u-p-30 u-bg-white">
  7. <view class="u-font-40"><text v-text="archivesInfo.title"></text></view>
  8. <view class="u-m-t-20 u-font-22 u-tips-color"><text v-text="archivesInfo.create_date"></text></view>
  9. <view class="u-flex u-row-between u-m-t-20 u-font-24 detail-tag">
  10. <view class="u-flex">
  11. <view class="u-flex u-col-center u-m-r-30" v-if="archivesInfo.user" @click="toUser(archivesInfo.user_id)">
  12. <u-avatar size="40" :src="archivesInfo.user.avatar"></u-avatar>
  13. <view class="u-font-22 u-m-l-10 u-line-1" style="max-width: 70px;">{{ archivesInfo.user.nickname }}</view>
  14. </view>
  15. <view class="">
  16. <u-icon name="thumb-up-fill" color="#aaa" size="20"></u-icon>
  17. <text class="u-m-l-5 u-m-r-5" v-text="archivesInfo.likes"></text>
  18. 点赞
  19. </view>
  20. <!-- <view class="u-m-l-30">
  21. <u-icon name="chat-fill" color="#aaa" size="20"></u-icon>
  22. <text class="u-m-l-5 u-m-r-5" v-text="archivesInfo.comments"></text>
  23. 评论
  24. </view> -->
  25. <view class="u-m-l-30">
  26. <u-icon name="eye-fill" color="#aaa" size="20"></u-icon>
  27. <text class="u-m-l-5 u-m-r-5" v-text="archivesInfo.views"></text>
  28. 浏览
  29. </view>
  30. </view>
  31. <view class="">
  32. <!-- #ifdef MP-WEIXIN -->
  33. <button class="share-btn" open-type="share">
  34. <u-icon name="share-fill"></u-icon>
  35. <text class="u-p-l-5">分享</text>
  36. </button>
  37. <!-- #endif -->
  38. <!-- #ifdef H5 -->
  39. <button class="share-btn" @click="copyUrl">
  40. <u-icon name="share-fill"></u-icon>
  41. <text class="u-p-l-5">分享</text>
  42. </button>
  43. <!-- #endif -->
  44. </view>
  45. </view>
  46. </view>
  47. <view class="u-flex u-flex-wrap u-p-l-30 u-p-r-30 u-p-t-30">
  48. <view class="product-images" v-for="(item, index) in imagesList" :key="index">
  49. <u-image width="100%" height="220" :src="item" @click="lookImage(index)"></u-image>
  50. </view>
  51. </view>
  52. <view class="u-p-30 u-bg-white u-line-height">
  53. <u-parse
  54. :html="archivesInfo.content"
  55. :tag-style="vuex_parse_style"
  56. :domain="vuex_config.config ? vuex_config.config.upload.cdnurl : ''"
  57. @linkpress="navigate"
  58. ></u-parse>
  59. <view class="u-flex u-row-center">
  60. <u-button
  61. type="primary"
  62. hover-class="none"
  63. :custom-style="{ backgroundColor: theme.bgColor, color: theme.color, width: '60vw' }"
  64. size="medium"
  65. @click="editcode"
  66. >
  67. 查看/编辑策略
  68. </u-button>
  69. </view>
  70. <u-gap height="20"></u-gap>
  71. <view v-if="archivesInfo.tongdaxin">
  72. <u-tag text="通达信源码" shape="circle" /> <u-tag type="success" text="复制到剪贴板" shape="circle" @click="copycode('tongdaxin')" style="margin-left: 5px;"/>
  73. <u-gap height="20"></u-gap>
  74. <u-parse
  75. :html="codetagfront+archivesInfo.tongdaxin+codetagback"
  76. :tag-style="vuex_parse_style"
  77. :domain="vuex_config.config ? vuex_config.config.upload.cdnurl : ''"
  78. @linkpress="navigate"
  79. ></u-parse>
  80. </view>
  81. <view v-if="archivesInfo.tonghuashun">
  82. <u-tag text="同花顺源码" shape="circle" /> <u-tag type="success" text="复制到剪贴板" shape="circle" @click="copycode('tonghuashun')" style="margin-left: 5px;"/>
  83. <u-gap height="20"></u-gap>
  84. <u-parse
  85. :html="codetagfront+archivesInfo.tonghuashun+codetagback"
  86. :tag-style="vuex_parse_style"
  87. :domain="vuex_config.config ? vuex_config.config.upload.cdnurl : ''"
  88. @linkpress="navigate"
  89. ></u-parse>
  90. </view>
  91. <view v-if="archivesInfo.dazhihui">
  92. <u-tag text="大智慧源码" shape="circle" /> <u-tag type="success" text="复制到剪贴板" shape="circle" @click="copycode('dazhihui')" style="margin-left: 5px;"/>
  93. <u-gap height="20"></u-gap>
  94. <u-parse
  95. :html="codetagfront+archivesInfo.dazhihui+codetagback"
  96. :tag-style="vuex_parse_style"
  97. :domain="vuex_config.config ? vuex_config.config.upload.cdnurl : ''"
  98. @linkpress="navigate"
  99. ></u-parse>
  100. </view>
  101. </view>
  102. <view class="u-p-30 u-bg-white">
  103. <view class="u-flex u-flex-wrap">
  104. <view class="u-m-r-10" v-for="(item, index) in archivesInfo.tagslist" :key="index">
  105. <u-tag :text="item.name" shape="circle" type="info" mode="light" @click="goTag(item.name)" />
  106. </view>
  107. </view>
  108. <view class="u-flex u-row-right">
  109. <view class="">
  110. <u-button
  111. type="primary"
  112. hover-class="none"
  113. :custom-style="{ backgroundColor: theme.bgColor, color: theme.color }"
  114. size="mini"
  115. shape="circle"
  116. @click="collection(id, 'archives')"
  117. >
  118. <u-icon name="heart-fill"></u-icon>
  119. <text class="u-p-l-5" v-text="`收藏`"></text>
  120. </u-button>
  121. </view>
  122. <view class="u-m-l-15">
  123. <u-button
  124. type="primary"
  125. hover-class="none"
  126. :custom-style="{ backgroundColor: theme.bgColor, color: theme.color }"
  127. size="mini"
  128. shape="circle"
  129. @click="likes"
  130. >
  131. <u-icon name="thumb-up"></u-icon>
  132. <text class="u-p-l-5" v-text="`点赞(${archivesInfo.likes || 0})`"></text>
  133. </u-button>
  134. </view>
  135. </view>
  136. </view>
  137. <!-- <u-gap height="20" bg-color="#f4f6f8"></u-gap>
  138. <view class="u-bg-white u-p-30">
  139. <view class="u-p-b-10 u-tips-color">发表评论</view>
  140. <view class=""><u-input v-model="content" type="textarea" placeholder="请输入评论内容" :border="false" /></view>
  141. <view class="u-flex u-row-center">
  142. <u-button
  143. type="primary"
  144. hover-class="none"
  145. :custom-style="{ backgroundColor: theme.bgColor, color: theme.color, width: '60vw' }"
  146. size="medium"
  147. v-if="!vuex_token"
  148. @click="goLogin"
  149. >
  150. 立即登录
  151. </u-button>
  152. <u-button
  153. type="primary"
  154. hover-class="none"
  155. :custom-style="{ backgroundColor: theme.bgColor, color: theme.color, width: '60vw' }"
  156. size="medium"
  157. v-else
  158. @click="submit"
  159. >
  160. 立即评论
  161. </u-button>
  162. </view>
  163. </view> -->
  164. <!-- <u-gap height="20" bg-color="#f4f6f8"></u-gap>
  165. <view class="u-p-30 u-bg-white">
  166. <view class="u-p-b-10 u-tips-color">评论列表</view>
  167. <view class="comment" v-for="(item, index) in commentList" :key="item.id">
  168. <view class="left" @click="toUser(item.user_id)"><image :src="item.user && item.user.avatar" mode="aspectFill"></image></view>
  169. <view class="right">
  170. <view class="top">
  171. <view class="u-light-color">
  172. <u-icon name="account-fill" color="#c0c4cc"></u-icon>
  173. <text class="u-p-l-10 name u-line-1">{{ item.user && item.user.nickname }}</text>
  174. <text class="u-m-l-30">{{ item.create_date }}</text>
  175. </view>
  176. <view class="replay" @click="replay(item)">
  177. <u-icon name="chat" :size="30"></u-icon>
  178. <view class="opeate">回复</view>
  179. </view>
  180. </view>
  181. <view class="content"><rich-text :nodes="item.content"></rich-text></view>
  182. </view>
  183. </view>
  184. <view class="" v-if="!commentList.length"><u-empty text="暂无评论"></u-empty></view>
  185. </view> -->
  186. <!-- 回到顶部 -->
  187. <u-back-top :scroll-top="scrollTop" :icon-style="{ color: theme.bgColor }" :custom-style="{ backgroundColor: lightColor }"></u-back-top>
  188. <!-- 底部导航 -->
  189. <fa-tabbar></fa-tabbar>
  190. </view>
  191. </template>
  192. <script>
  193. import { tools, vote } from '@/common/fa.mixin.js';
  194. // #ifdef H5
  195. import { weixinShare } from '@/common/fa.weixin.mixin.js';
  196. // #endif
  197. export default {
  198. mixins: [
  199. tools,
  200. vote,
  201. // #ifdef H5
  202. weixinShare
  203. // #endif
  204. ],
  205. onLoad(e) {
  206. let query = this.$Route.query || e || {};
  207. this.id = query.id || 0;
  208. this.diyname = query.diyname || '';
  209. this.getArchivesDetail();
  210. },
  211. onShow() {
  212. // #ifdef MP-BAIDU
  213. if (this.archivesInfo.id) {
  214. this.setPagesInfo();
  215. }
  216. // #endif
  217. },
  218. watch: {
  219. content(newValue, oldValue) {
  220. if (!newValue) {
  221. this.pid = 0;
  222. }
  223. }
  224. },
  225. data() {
  226. return {
  227. id: 0,
  228. diyname: '',
  229. archivesInfo: {},
  230. commentList: [],
  231. imagesList: [],
  232. content: '',
  233. pid: 0,
  234. scrollTop: 0,
  235. page: 1,
  236. has_more: true,
  237. codetagfront:"<pre class=\"language-markup\"><code>",
  238. codetagback:"</code></pre>"
  239. };
  240. },
  241. methods: {
  242. copycode(type){
  243. if(type=="tongdaxin"){
  244. uni.setClipboardData({
  245. data:this.archivesInfo.tongdaxin,
  246. success: function (res) {
  247. uni.showToast({
  248. title: '复制成功',
  249. })
  250. }
  251. });
  252. }
  253. if(type=="tonghuashun"){
  254. uni.setClipboardData({
  255. data:this.archivesInfo.tonghuashun,
  256. success: function (res) {
  257. uni.showToast({
  258. title: '复制成功',
  259. })
  260. }
  261. });
  262. }
  263. if(type=="dazhihui"){
  264. uni.setClipboardData({
  265. data:this.archivesInfo.dazhihui,
  266. success: function (res) {
  267. uni.showToast({
  268. title: '复制成功',
  269. })
  270. }
  271. });
  272. }
  273. },
  274. editcode(){
  275. this.$Router.push({
  276. path: '/pages/stock/stockprogram',
  277. query: { productid: this.archivesInfo.id }
  278. });
  279. },
  280. getArchivesDetail: async function() {
  281. let res = await this.$api.getArchivesDetail({ id: this.id, diyname: this.diyname });
  282. if (!res.code) {
  283. this.$u.toast(res.msg);
  284. return;
  285. }
  286. this.archivesInfo = res.data.archivesInfo || {};
  287. this.commentList = res.data.commentList || [];
  288. this.imagesList = res.data.archivesInfo.productdata;
  289. this.$u.mpShare.title = res.data.archivesInfo.title;
  290. uni.setNavigationBarTitle({
  291. title: this.archivesInfo.title
  292. });
  293. // #ifdef MP-BAIDU
  294. this.setPagesInfo();
  295. // #endif
  296. // #ifdef H5
  297. if (this.$util.isWeiXinBrowser()) {
  298. this.wxShare({
  299. title: this.archivesInfo.title,
  300. desc: this.archivesInfo.description,
  301. link: window.location.href,
  302. img: this.archivesInfo.image
  303. });
  304. }
  305. // #endif
  306. },
  307. // #ifdef MP-BAIDU
  308. setPagesInfo() {
  309. let sitename = (this.vuex_config && this.vuex_config.config && this.vuex_config.config.sitename) || '';
  310. swan.setPageInfo({
  311. title: this.archivesInfo.title+'-'+sitename,
  312. articleTitle: this.archivesInfo.title+'-'+sitename,
  313. keywords: this.archivesInfo.keywords,
  314. description: this.archivesInfo.description,
  315. releaseDate: this.$u.timeFormat(this.archivesInfo.publishtime, 'yyyy-mm-dd hh:MM:ss'),
  316. image: this.archivesInfo.images,
  317. likes: this.archivesInfo.likes,
  318. comments: this.archivesInfo.comments,
  319. collects: this.archivesInfo.views,
  320. success: res => {
  321. console.log('setPageInfo success', res);
  322. },
  323. fail: err => {
  324. console.log('setPageInfo fail', err);
  325. }
  326. });
  327. },
  328. // #endif
  329. goCommentIndex() {
  330. this.$api.goCommentIndex({ page: this.page, aid: this.archivesInfo.id }).then(res => {
  331. if (res.code == 1) {
  332. this.has_more = res.data.commentList.length > 0;
  333. this.commentList = [...this.commentList, ...res.data.commentList];
  334. }
  335. });
  336. },
  337. toUser(user_id) {
  338. this.$Router.push('/pages/user/user?user_id=' + user_id);
  339. },
  340. replay(item) {
  341. if (!item.user) {
  342. this.$u.toast('用户不存在');
  343. return;
  344. }
  345. this.content = `@${item.user.nickname} `;
  346. this.pid = item.id;
  347. },
  348. goTag(name) {
  349. this.$Router.push({
  350. path: '/pages/tag/tag',
  351. query: { name: name }
  352. });
  353. },
  354. submit: async function() {
  355. if (!this.content) {
  356. this.$u.toast('请输入评论内容!');
  357. return;
  358. }
  359. let res = await this.$api.goCommentPost({
  360. content: this.content,
  361. aid: this.id,
  362. pid: this.pid //回复的用户上一条ID
  363. });
  364. this.$u.toast(res.msg);
  365. if (!res.code) {
  366. return;
  367. }
  368. this.content = '';
  369. if (res.data && res.data.comment) {
  370. this.commentList = [res.data.comment, ...this.commentList];
  371. }
  372. },
  373. goLogin() {
  374. this.$Router.push('/pages/login/mobilelogin');
  375. }
  376. },
  377. onPageScroll(e) {
  378. this.scrollTop = e.scrollTop;
  379. },
  380. onReachBottom() {
  381. if (this.has_more) {
  382. this.page += 1;
  383. this.goCommentIndex();
  384. }
  385. }
  386. };
  387. </script>
  388. <style lang="scss">
  389. page {
  390. background-color: #f4f6f8;
  391. }
  392. .detail-tag {
  393. color: #aaa;
  394. }
  395. .comment {
  396. background-color: #ffffff;
  397. display: flex;
  398. padding: 30rpx;
  399. .left {
  400. image {
  401. width: 64rpx;
  402. height: 64rpx;
  403. border-radius: 50%;
  404. background-color: #f2f2f2;
  405. }
  406. }
  407. .right {
  408. flex: 1;
  409. padding-left: 20rpx;
  410. .top {
  411. display: flex;
  412. justify-content: space-between;
  413. align-items: center;
  414. margin-bottom: 10rpx;
  415. .replay {
  416. display: flex;
  417. align-items: center;
  418. color: #9a9a9a;
  419. font-size: 26rpx;
  420. .opeate {
  421. margin-right: 4rpx;
  422. color: #9a9a9a;
  423. }
  424. }
  425. .name {
  426. max-width: 100rpx;
  427. }
  428. }
  429. .content {
  430. margin-bottom: 10rpx;
  431. word-break: break-word;
  432. }
  433. }
  434. }
  435. .comment:not(:last-child) {
  436. border-bottom: 1px solid #eee;
  437. }
  438. .product-images {
  439. width: 50%;
  440. margin-bottom: 30rpx;
  441. }
  442. .product-images:nth-child(2n) {
  443. padding-left: 15rpx;
  444. }
  445. .product-images:nth-child(2n + 1) {
  446. padding-right: 15rpx;
  447. }
  448. .share {
  449. padding: 0;
  450. margin: 0;
  451. border: 0;
  452. background-color: transparent;
  453. line-height: inherit;
  454. border-radius: 0;
  455. font-size: inherit;
  456. color: #999;
  457. }
  458. .share::after {
  459. border: none;
  460. }
  461. </style>