activity_deatil.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. <template>
  2. <view class="content">
  3. <view class="header">
  4. <view class="title-read">
  5. <view class="title">
  6. {{ model.title }}
  7. </view>
  8. <view class="read">浏览量 {{ model.read }}</view>
  9. </view>
  10. <!-- <view class="header-image">
  11. <image :src="model.url" alt="" />
  12. </view> -->
  13. </view>
  14. <view class="active-deatil">
  15. <ul>
  16. <li>
  17. <p class="name">活动时间</p>
  18. <p class="deatil-content">{{ model.date }}</p>
  19. </li>
  20. <li>
  21. <p class="name">活动类型</p>
  22. <p class="deatil-content">{{ model.type == 1 ? "线上" : "线下" }}</p>
  23. </li>
  24. <li>
  25. <p class="name">主办方</p>
  26. <p class="deatil-content">{{ model.way }}</p>
  27. </li>
  28. </ul>
  29. </view>
  30. <view class="rich">
  31. <activityRichCard :model="textModel" :isFold="true" />
  32. </view>
  33. <view class="share-box">
  34. <view class="share">
  35. <button class="share" @click="shareActive()" open-type="share" style="background: transparent;">
  36. <image src="../../static/share_icon.svg"></image>
  37. </button>
  38. <view class="shareCount">{{ model.share }}</view>
  39. </view>
  40. <view class="button">
  41. <button
  42. v-if="!isJoin"
  43. @click="subscribeActivity()"
  44. :disabled="!(model.status == '待开始' && model.type == 2)"
  45. :class="{
  46. start: model.status == '待开始' && model.type == 2,
  47. begun: model.status == '已开始',
  48. ended: model.status == '已结束',
  49. falseStart: model.status == '待开始' && model.type == 1,
  50. }"
  51. >
  52. {{ model.activiteState }}
  53. </button>
  54. <button disabled="true" class="ended" v-if="isJoin">已报名</button>
  55. </view>
  56. <!-- "status":"活动状态 0:待开始;1:已开始; 2:已结束
  57. "type":"活动类型 1:线上;2 线下"} -->
  58. </view>
  59. <uni-popup ref="popup" :mask-click="false">
  60. <view class="popup-box">
  61. <view>
  62. <view class="popup-title">活动报名信息填写</view>
  63. <view class="popup-content-box">
  64. <view class="popup-content">
  65. <view class="popup-type" v-for="(info,index) in activityInfoList" :key="info.id">
  66. <view>{{info.name}}</view>
  67. <input type="text" v-model="info.value"/>
  68. </view>
  69. <!-- <view class="popup-type">
  70. <view>性别</view><input type="text" value="" />
  71. </view>
  72. <view class="popup-type">
  73. <view>年龄</view><input type="number" value="" />
  74. </view>
  75. <view class="popup-type">
  76. <view>工作单位</view><input type="text" value="" />
  77. </view>
  78. <view class="popup-type">
  79. <view>职务</view><input type="text" value="" />
  80. </view> -->
  81. </view>
  82. </view>
  83. </view>
  84. <view class="popup-footer">
  85. <button class="popup-cancel" @click="closePopup">取消</button>
  86. <button class="popup-submit" @click="submitInfo">提交</button>
  87. </view>
  88. </view>
  89. </uni-popup>
  90. </view>
  91. </template>
  92. <script>
  93. import md5 from "@/common/md5.js";
  94. import activity_rich_card from "../policy/policy_rich_card";
  95. import uniPopup from "@/components/uni-popup/uni-popup.vue"
  96. export default {
  97. filters: {
  98. formDateTime(value) {
  99. if (value) {
  100. const time = new Date(value * 1000);
  101. const y = time.getFullYear();
  102. const m =
  103. time.getMonth() + 1 < 10
  104. ? "0" + (time.getMonth() + 1)
  105. : time.getMonth() + 1;
  106. const d = time.getDate() < 10 ? "0" + time.getDate() : time.getDate();
  107. // const h = time.getHours()
  108. // const mm = time.getMinutes();
  109. // const s = time.getSeconds();
  110. return y + "." + m + "." + d;
  111. } else {
  112. return "";
  113. }
  114. },
  115. formDateTimeSecond(value) {
  116. if (value) {
  117. const time = new Date(value * 1000);
  118. // const y = time.getFullYear();
  119. // const m = (time.getMonth() + 1) < 10 ? '0' + (time.getMonth() + 1) : (time.getMonth() + 1);
  120. // const d = time.getDate() < 10 ? '0' + time.getDate(): time.getDate();
  121. const h =
  122. time.getHours() < 10 ? "0" + time.getHours() : time.getHours();
  123. const mm =
  124. time.getMinutes() < 10 ? "0" + time.getMinutes() : time.getMinutes();
  125. return h + ":" + mm;
  126. } else {
  127. return "";
  128. }
  129. },
  130. },
  131. components: {
  132. activityRichCard: activity_rich_card,
  133. uniPopup
  134. },
  135. data() {
  136. return {
  137. id: "",
  138. isJoin: false,
  139. activityInfoList:[],
  140. model: {
  141. title: "",
  142. read: 123,
  143. url: "",
  144. date: "",
  145. type: 1,
  146. status: 0,
  147. way: "",
  148. share: 0,
  149. activiteState: "",
  150. max_person: "",
  151. person_count: "",
  152. },
  153. textModel: {
  154. title: "活动内容",
  155. text: "",
  156. },
  157. };
  158. },
  159. onLoad(op) {
  160. this.id = op.id;
  161. this.getActivityDeatil();
  162. },
  163. methods: {
  164. shareRequest() {
  165. let md5Sign = md5(
  166. "method=" +
  167. "user" +
  168. "&timestamp=" +
  169. getApp().globalData.globalTimestamp +
  170. "&secret=" +
  171. getApp().globalData.secret
  172. );
  173. let url =
  174. getApp().globalData.shareUrl +
  175. "api/api.php" +
  176. "?method=user&source=activity&action=repost&timestamp=" +
  177. getApp().globalData.globalTimestamp +
  178. "&sign=" +
  179. md5Sign;
  180. uni.request({
  181. url: url,
  182. method: "POST",
  183. header: {
  184. "content-type": "application/x-www-form-urlencoded",
  185. },
  186. data: {
  187. openId: getApp().globalData.open_id,
  188. source_id: this.id,
  189. source: "activity",
  190. },
  191. success: (res) => {
  192. if (res.data.code === 200) {
  193. console.log(res);
  194. this.model.share = this.model.share + 1;
  195. }
  196. },
  197. fail: () => {
  198. console.log("连接失败");
  199. },
  200. });
  201. },
  202. shareActive() {
  203. let that = this;
  204. uni.showShareMenu({
  205. title: that.model.title,
  206. path: "pages/activity/activity_detail?id=" + that.id,
  207. success(res) {
  208. that.shareRequest();
  209. },
  210. });
  211. },
  212. getActivityDeatil() {
  213. let md5Sign = md5(
  214. "method=" +
  215. "activity" +
  216. "&timestamp=" +
  217. getApp().globalData.globalTimestamp +
  218. "&secret=" +
  219. getApp().globalData.secret
  220. );
  221. let url =
  222. getApp().globalData.shareUrl +
  223. "api/api.php" +
  224. "?method=activity&source=activity&action=info_by_id&timestamp=" +
  225. getApp().globalData.globalTimestamp +
  226. "&sign=" +
  227. md5Sign;
  228. let postData = {
  229. id: this.id,
  230. openId: getApp().globalData.open_id,
  231. };
  232. //获取文章
  233. uni.request({
  234. url: url,
  235. method: "POST",
  236. header: {
  237. "content-type": "application/x-www-form-urlencoded",
  238. },
  239. data: postData,
  240. success: (res) => {
  241. if (res.data.code == 200) {
  242. let data = res.data.data;
  243. this.isJoin = data.active ? true : false;
  244. this.activityInfoList = data.category_list;
  245. this.activityInfoList.forEach((item)=>{
  246. item.value = '';
  247. })
  248. this.model.title = data.name;
  249. this.model.read = parseInt(data.base_read_count) + parseInt(data.real_read_count);
  250. this.model.url = getApp().globalData.shareUrl + data.pic_url;
  251. let arr = ["start_time", "end_time"];
  252. let ans = [];
  253. for (const item of arr) {
  254. let time = this.$options.filters["formDateTime"](data[item]);
  255. let timeSecond = this.$options.filters["formDateTimeSecond"](data[item]);
  256. ans.push(time + " " + timeSecond);
  257. }
  258. this.model.date = ans.join(" - ");
  259. this.model.type = data.type;
  260. this.model.status = data.status;
  261. this.model.way = data.sponsor;
  262. this.model.max_person = data.max_person;
  263. this.model.person_count = data.person_count;
  264. this.model.share = parseInt(data.real_repost_count) + parseInt(data.base_repost_count);
  265. if (data.status == '待开始') {
  266. if (data.type == 2) {
  267. this.model.activiteState = "我要参加";
  268. } else {
  269. this.model.activiteState = "活动待开始";
  270. }
  271. } else if (data.status == '已开始') {
  272. this.model.activiteState = "活动进行中";
  273. } else {
  274. this.model.activiteState = "活动已结束";
  275. }
  276. }
  277. this.getRich();
  278. },
  279. fail: () => {
  280. console.log("连接失败");
  281. },
  282. });
  283. },
  284. replaceImg(html) {
  285. let result = html.replace(
  286. /<img [^>]*src=['"]([^'"]+)[^>]*>/gi,
  287. function (match, capture) {
  288. if(capture.includes('http')){
  289. return (
  290. "<img src=" +
  291. capture +
  292. ' style="max-width:100%;height:auto;display:block;margin:10px auto;"/>'
  293. );
  294. }else {
  295. return (
  296. "<img src=" +
  297. getApp().globalData.shareUrl +
  298. capture +
  299. ' style="max-width:100%;height:auto;display:block;margin:10px auto;"/>'
  300. );
  301. }
  302. }
  303. );
  304. return result;
  305. },
  306. getRich() {
  307. uni.request({
  308. url:
  309. getApp().globalData.shareUrl +
  310. `content/activity/${Math.floor(this.id / 1000)}/${this.id}.html`+'?version='+ Math.random(),
  311. method: "GET",
  312. header: {
  313. "content-type": "application/x-www-form-urlencoded",
  314. },
  315. success: (res) => {
  316. if (res.statusCode === 200) {
  317. this.textModel.text = this.replaceImg(res.data);
  318. }
  319. },
  320. fail: () => {
  321. console.log("连接失败");
  322. },
  323. });
  324. },
  325. subscribeActivity(info) {
  326. if (this.model.person_count >= this.model.max_person) {
  327. uni.showToast({
  328. title: "报名人数已达上限",
  329. icon: "error",
  330. duration: 2000,
  331. });
  332. return;
  333. }
  334. if(this.activityInfoList.length > 0){
  335. this.open();
  336. }
  337. },
  338. signUpActivity(infoList) {
  339. let md5Sign = md5(
  340. "method=" +
  341. "activity" +
  342. "&timestamp=" +
  343. getApp().globalData.globalTimestamp +
  344. "&secret=" +
  345. getApp().globalData.secret
  346. );
  347. let url =
  348. getApp().globalData.shareUrl +
  349. "api/api.php" +
  350. "?method=activity&source=activity&action=active&timestamp=" +
  351. getApp().globalData.globalTimestamp +
  352. "&sign=" +
  353. md5Sign;
  354. let postData = {
  355. openId: getApp().globalData.open_id,
  356. id: this.id,
  357. category_json:JSON.stringify(infoList)
  358. };
  359. uni.request({
  360. url: url,
  361. method: "POST",
  362. header: {
  363. "content-type": "application/x-www-form-urlencoded",
  364. },
  365. data: postData,
  366. success: (res) => {
  367. if (res.data.code == 200) {
  368. this.isJoin = true;
  369. uni.showToast({
  370. title: "报名成功",
  371. icon: "none",
  372. duration: 2500,
  373. });
  374. }
  375. },
  376. fail: () => {
  377. console.log("连接失败");
  378. },
  379. });
  380. },
  381. subscribeFn(info){
  382. let that = this;
  383. uni.requestSubscribeMessage({
  384. tmplIds: [
  385. // "bSg5tUWHE4qWDeyK31GBejogT1uRgkuBD1_n2I5ptAc",
  386. // "T_ORLiW2C_UM6nZiEerYAokltHgHRGxWCid8eElujus",
  387. "XPULJQ64YrS-5sAnfMTJj3S9iV8-8X_mb3r_H5dgAgE",
  388. "RWq7TE266RYr8DX2IHZ2F_zKbOnSfZDgh_xovBh0UiI" //测试环境模板id
  389. ],
  390. success(res) {
  391. that.signUpActivity(info);
  392. },
  393. });
  394. },
  395. open() {
  396. this.$refs.popup.open('top')
  397. },
  398. closePopup() {
  399. this.$refs.popup.close()
  400. },
  401. submitInfo(){
  402. this.activityInfoList.forEach((item)=>{
  403. delete item.addtime;
  404. delete item.name;
  405. delete item.parent_id;
  406. delete item.weight;
  407. })
  408. this.$refs.popup.close();
  409. this.subscribeFn(this.activityInfoList)
  410. }
  411. },
  412. };
  413. </script>
  414. <style lang="scss" scoped>
  415. .content {
  416. display: flex;
  417. flex-direction: column;
  418. .header {
  419. display: flex;
  420. // height: 150rpx;
  421. padding: 20rpx;
  422. .title-read {
  423. height: 100%;
  424. display: flex;
  425. flex-direction: column;
  426. justify-content: space-evenly;
  427. .title {
  428. font-weight: 600;
  429. letter-spacing: 2rpx;
  430. font-size: 34rpx;
  431. }
  432. .read {
  433. margin-top: 20rpx;
  434. font-size: 26rpx;
  435. color: $uni-text-color-grey;
  436. }
  437. }
  438. .header-image {
  439. height: 100%;
  440. width: 50%;
  441. image {
  442. width: 100%;
  443. height: 100%;
  444. border-radius: 10%;
  445. }
  446. }
  447. }
  448. .active-deatil {
  449. padding: 20rpx;
  450. ul {
  451. padding: 30rpx;
  452. box-shadow: 0px 4rpx 32rpx rgba(0, 0, 0, 0.1);
  453. border-radius: 32rpx;
  454. li {
  455. margin-bottom: 30rpx;
  456. list-style: none;
  457. .name {
  458. margin-bottom: 10rpx;
  459. font-size: 30rpx;
  460. color: $uni-text-color-grey;
  461. }
  462. .deatil-content {
  463. font-size: 28rpx;
  464. }
  465. }
  466. }
  467. }
  468. .rich {
  469. margin-bottom: 150rpx;
  470. padding: 20rpx;
  471. }
  472. .share-box {
  473. box-sizing: border-box;
  474. height: 150rpx;
  475. width: 100%;
  476. align-items: center;
  477. justify-content: space-evenly;
  478. position: fixed;
  479. bottom: 0;
  480. display: flex;
  481. background: #ffffff;
  482. .share {
  483. display: flex;
  484. justify-content: center;
  485. align-items: center;
  486. width: 60rpx;
  487. height: 60rpx;
  488. position: relative;
  489. button::after {
  490. border: none;
  491. }
  492. image {
  493. width: 100%;
  494. height: 100%;
  495. position: absolute;
  496. }
  497. .shareCount {
  498. display: flex;
  499. justify-content: center;
  500. align-items: center;
  501. position: absolute;
  502. top: -20%;
  503. right: -25%;
  504. color: #ffffff;
  505. height: 30rpx;
  506. width: 30rpx;
  507. padding: 3rpx;
  508. font-size: 16rpx;
  509. border-radius: 50%;
  510. background: #fe3637;
  511. }
  512. }
  513. .button {
  514. height: 100rpx;
  515. width: 70%;
  516. display: flex;
  517. justify-content: center;
  518. button {
  519. width: 80%;
  520. height: 90%;
  521. border: 1px solid;
  522. outline: none;
  523. background: none;
  524. }
  525. .start {
  526. //待开始
  527. background-color: #00a8ea;
  528. color: #ffffff;
  529. border-color: none;
  530. }
  531. .begun {
  532. //已开始
  533. border-color: #00a8ea;
  534. color: #00a8ea;
  535. }
  536. .ended {
  537. //已结束
  538. color: #aaaaaa;
  539. border-color: #aaaaaa;
  540. }
  541. .falseStart {
  542. color: #70b603;
  543. border-color: #70b603;
  544. }
  545. }
  546. }
  547. .popup-box {
  548. height: 100%;
  549. display: flex;
  550. flex-direction: column;
  551. justify-content: space-between;
  552. }
  553. .popup-title {
  554. text-align: center;
  555. font-weight: bold;
  556. height: 30px;
  557. border-bottom: 1px solid #d8d8d8;
  558. }
  559. .popup-content {
  560. font-size: 28rpx;
  561. padding: 10rpx 0 10rpx 0;
  562. }
  563. .popup-type {
  564. display: flex;
  565. height: 80rpx;
  566. align-items: center;
  567. view {
  568. width: 25%;
  569. }
  570. input {
  571. border: 1px solid #d7d7d7;
  572. width: 70%;
  573. border-radius: 5rpx;
  574. padding-left: 10rpx;
  575. }
  576. }
  577. .popup-footer {
  578. display: flex;
  579. button{
  580. font-size: 26rpx;
  581. height: 60rpx;
  582. width: 150rpx;
  583. line-height: 60rpx;
  584. color: #FFFFFF;
  585. }
  586. }
  587. .popup-cancel {
  588. background-color: #AAAAAA;
  589. }
  590. .popup-submit {
  591. background-color: #249CD3;
  592. }
  593. }
  594. </style>