sign_manage.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <template>
  2. <view class="page_body">
  3. <view class="page_top">
  4. <view class="banner_container"><image :src="banner" mode="scaleToFill" class="banner_img" /></view>
  5. <view class="season">
  6. <view class="season_con">
  7. <view class="title">
  8. <image src="../../static/imgs/offline.png" mode="scaleToFill"></image>
  9. <text>第{{ userInfo.season ? userInfo.season : '' }}届大卫博士创业{{ userInfo.season_type | activityType }}</text>
  10. </view>
  11. <view class="con">
  12. <view class="course_info">
  13. <view style="margin-right:102rpx;">
  14. <text>名额限制:</text>
  15. <text>{{ userInfo.is_limit && userInfo.limit_num ? userInfo.limit_num : '无限制' }}</text>
  16. <text v-if="userInfo.is_limit && userInfo.limit_num">名</text>
  17. </view>
  18. </view>
  19. <view class="course_info">
  20. <view>
  21. <text>已报名:</text>
  22. <text class="count">
  23. <text>{{ userInfo.count }}</text>
  24. <text>人</text>
  25. </text>
  26. </view>
  27. <view style="margin-left: 30rpx;">
  28. <text>剩余名额:</text>
  29. <text class="count">
  30. <text>
  31. {{ userInfo.is_limit && userInfo.limit_num ? userInfo.limit_num - userInfo.count : '无限制' }}
  32. </text>
  33. <text>人</text>
  34. </text>
  35. </view>
  36. </view>
  37. <view class="course_time">
  38. <text>时间:</text>
  39. <text>{{ getTime(userInfo.time_start) }}</text>
  40. <text>-</text>
  41. <text>{{ getTime(userInfo.time_end) }}</text>
  42. </view>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. <view class="page_center">
  48. <view :class="isFixedTop ? 'tab_fixed' : 'tab'">
  49. <view class="sign_tab">
  50. <view @click="choose(1)" :class="tab_type == 1 ? 'active' : ''">已报名({{ userInfo.count }})</view>
  51. <view @click="choose(2)" :class="tab_type == 2 ? 'active' : ''">详细数据</view>
  52. </view>
  53. <view class="sign_list_tab flexA" v-if="tab_type == 1">
  54. <view @click="sing_tap = 1" :class="sing_tap == 1 ? 'active' : ''">
  55. <picker @change="getSort" :value="sortVal" :range="sort">
  56. <view class="flexS">
  57. <text class="iconfont iconpaixu" style="font-size: 35rpx; margin-right: 5rpx;color: #666;"></text>
  58. <view class="picker">{{ sort[index] ? sort[index] : '排序' }}</view>
  59. </view>
  60. </picker>
  61. </view>
  62. <view @click="sing_tap = 2" :class="sing_tap == 2 ? 'active' : ''">
  63. <picker @change="getScreen" :value="screenVal" :range="screen">
  64. <view class="flexS">
  65. <image src="../../static/screen.png" style="width: 28rpx; height:27rpx;vertical-align: middle;"></image>
  66. <view class="picker">{{ screen[index] ? screen[index] : '筛选' }}</view>
  67. </view>
  68. </picker>
  69. </view>
  70. <view class="search flexS" @click="search">
  71. <text class="iconfont iconsousuo" style="font-size: 30rpx; margin-right: 5rpx;color: #666;"></text>
  72. <text>查找</text>
  73. </view>
  74. </view>
  75. </view>
  76. <view class="scroll" v-if="tab_type == 1">
  77. <scroll-view
  78. :scroll-y="isFixedTop ? true : false"
  79. @scrolltolower="more"
  80. :scroll-top="topNum"
  81. :style="{ height: isFixedTop ? height - tabH + 'px' : height + 'px' }"
  82. >
  83. <view class="scroll_con">
  84. <view class="sign_list flexB" v-for="item in signList" :key="item.id">
  85. <view class="list_left flexS">
  86. <image :src="item.avatar"></image>
  87. <view>
  88. <text>{{ item.nickname }}</text>
  89. <view>{{ item.created_at }}</view>
  90. </view>
  91. </view>
  92. <view class="list_right">报名成功</view>
  93. </view>
  94. </view>
  95. </scroll-view>
  96. </view>
  97. <view class="table_scroll" v-if="tab_type == 2">
  98. <scroll-view
  99. :scroll-y="isFixedTop ? true : false"
  100. @scrolltolower="more"
  101. :scroll-top="topNum"
  102. scroll-x="true"
  103. :style="{ height: isFixedTop ? height - signTabH + 'px' : height + 'px' }"
  104. >
  105. <view class="scroll_con">
  106. <view class="header">
  107. <view style="width:120rpx;">序号</view>
  108. <view style="width:350rpx;">微信昵称</view>
  109. <view>等级</view>
  110. <view style="width:220rpx;">手机号</view>
  111. <view style="width:350rpx;">报名时间</view>
  112. <view>签到状态</view>
  113. <view style="width:350rpx ;">签到时间</view>
  114. <view>签到人</view>
  115. </view>
  116. <view class="table_con" v-for="(item, index) in signList" :key="item.id">
  117. <view style="width:120rpx;">{{ index + 1 }}</view>
  118. <view style="width:350rpx;">{{ item.nickname }}</view>
  119. <view>{{ item.level }}</view>
  120. <view style="width:220rpx;">{{ item.phone }}</view>
  121. <view style="width:350rpx ;">{{ item.created_at }}</view>
  122. <view>{{ item.status == 1 ? '已签到' : '未签到' }}</view>
  123. <view style="width:350rpx ;">{{ item.sure_time }}</view>
  124. <view>{{ item.op_name }}</view>
  125. </view>
  126. </view>
  127. </scroll-view>
  128. </view>
  129. </view>
  130. </view>
  131. </template>
  132. <script>
  133. import { toSign, poyStatus, enrollList } from '../../api/sign.js';
  134. import { getBanner, getUserInfo } from '../../api/index.js';
  135. export default {
  136. data() {
  137. return {
  138. banner: '', //banner图
  139. topNum: '', //返回顶部
  140. userInfo: {},
  141. payStatus: true, //支付按钮是否能点击
  142. tab_type: 1, //tab切换 【1:信息填写】 【2:课程介绍】 【3:报名须知】
  143. cost: '', //报名需要缴纳的金额
  144. sing_tap: 1, //子tab 【1:排序】【2:筛选】【3:查找】
  145. sort: ['正序', '倒序'], //排序选项
  146. screen: ['所有人', '今日新增'], //筛选选项
  147. isScroll: false, //scroll-view 竖向是否滚动
  148. scroll: '', //scroll-view 的高度
  149. signList: [], //报名列表
  150. params: {
  151. page_size: 15,
  152. page_index: 1,
  153. type: 'all', //筛选
  154. order: '', //拍序
  155. search_name: ''
  156. },
  157. sortVal: '', //排序选中的值
  158. screenVal: '', //筛选选中的值
  159. isFixedTop: false, //是否固定顶部
  160. height: '',
  161. tabScrollTop: '',
  162. scrollTop: '',
  163. tabH: '',
  164. signTabH: '',
  165. signListH: ''
  166. };
  167. },
  168. onLoad(options) {
  169. if (!uni.getStorageSync('token') || !uni.getStorageSync('userInfo')) {
  170. uni.switchTab({
  171. url: '../index/index'
  172. });
  173. return false;
  174. }
  175. if (options.banner) {
  176. this.banner = options.banner;
  177. } else {
  178. this.getBanner();
  179. }
  180. },
  181. onShow() {
  182. if (!uni.getStorageSync('token') || !uni.getStorageSync('userInfo')) {
  183. uni.switchTab({
  184. url: '../index/index'
  185. });
  186. return false;
  187. }
  188. this.userInfo = uni.getStorageSync('userInfo');
  189. this.getEnroll();
  190. uni.getSystemInfo({
  191. success: res => {
  192. this.height = res.windowHeight;
  193. }
  194. });
  195. },
  196. onReady() {
  197. let that = this;
  198. var query = uni.createSelectorQuery();
  199. query
  200. .select('.page_center')
  201. .boundingClientRect(res => {
  202. that.tabScrollTop = res.top;
  203. })
  204. .exec();
  205. query
  206. .select('.sign_tab')
  207. .boundingClientRect(res => {
  208. that.signTabH = res.height;
  209. })
  210. .exec();
  211. query
  212. .select('.sign_list_tab')
  213. .boundingClientRect(res => {
  214. that.signListH = res.height;
  215. })
  216. .exec();
  217. that.tabH = that.signTabH + that.signListH;
  218. },
  219. onPageScroll(e) {
  220. var scrollTop = e.scrollTop;
  221. const _H = this.tab_type === 2 ? this.signTabH : 0
  222. var isSatisfy = scrollTop + _H >= this.tabScrollTop ? true : false;
  223. //只有处于吸顶的临界值才会不相等
  224. if (this.isFixedTop === isSatisfy) {
  225. return false;
  226. }
  227. this.isFixedTop = isSatisfy;
  228. },
  229. methods: {
  230. //获取banner图及用户信息
  231. getBanner() {
  232. getBanner().then(res => {
  233. if (res.code == 200) {
  234. this.banner = res.data.banner_1;
  235. } else {
  236. uni.showModal({
  237. content: res.message || '请求失败',
  238. showCancel: false
  239. });
  240. }
  241. });
  242. getUserInfo().then(res => {
  243. if (res.code == 200) {
  244. this.userInfo = res.data;
  245. uni.setStorageSync('userInfo', res.data);
  246. } else {
  247. uni.showModal({
  248. content: res.message || '请求失败',
  249. showCancel: false
  250. });
  251. }
  252. });
  253. },
  254. choose(idx) {
  255. this.tab_type = idx;
  256. this.topNum = 1;
  257. },
  258. /* 获取已报名的列表
  259. * @params page_size 显示条数
  260. * @params page_index 当前显示的页数
  261. * @params type 筛选 today【今日新增】 all【全部】
  262. * @params order 排序 '' 【正序】 desc【倒序】
  263. * @params search_name 搜索内容
  264. */
  265. getEnroll(e, state) {
  266. this.params.page_index = 1;
  267. let { page_size, page_index, type, order, search_name } = this.params;
  268. enrollList({
  269. page_size,
  270. page_index,
  271. type,
  272. order,
  273. search_name
  274. }).then(res => {
  275. if (res.code == 200) {
  276. this.signList = res.data.list;
  277. } else {
  278. uni.showModal({
  279. content: res.message || '请求失败',
  280. showCancel: false
  281. });
  282. }
  283. });
  284. },
  285. //下拉加载更多
  286. more() {
  287. this.params.page_index++;
  288. let { page_size, type, order, page_index, search_name } = this.params;
  289. enrollList({
  290. page_size,
  291. page_index,
  292. type,
  293. order,
  294. search_name
  295. }).then(res => {
  296. if (res.code == 200) {
  297. if (res.data.list.length > 0) {
  298. this.signList = this.signList.concat(res.data.list);
  299. } else {
  300. uni.showToast({
  301. title: '没有更多啦~',
  302. icon: 'none'
  303. });
  304. }
  305. } else {
  306. uni.showModal({
  307. content: res.message || '请求失败',
  308. showCancel: false
  309. });
  310. }
  311. });
  312. },
  313. // 查找
  314. search() {
  315. uni.navigateTo({
  316. url: '../search/search'
  317. });
  318. },
  319. //排序
  320. getSort(e) {
  321. this.sortVal = e.detail.value;
  322. if (this.sortVal == 1) {
  323. this.params.order = '';
  324. } else {
  325. this.params.order = 'desc';
  326. }
  327. this.getEnroll();
  328. },
  329. //筛选
  330. getScreen(e) {
  331. this.screenVal = e.target.value;
  332. if (this.screenVal == 0) {
  333. //所有
  334. this.params.type = 'all';
  335. } else {
  336. this.params.type = 'today';
  337. }
  338. this.getEnroll();
  339. },
  340. getTime(date) {
  341. if (date != NaN) {
  342. var time = new Date(Number(date) * 1000);
  343. var year = time.getFullYear();
  344. var month = time.getMonth() + 1 < 10 ? '0' + (time.getMonth() + 1) : time.getMonth() + 1;
  345. var day = time.getDate() < 10 ? '0' + time.getDate() : time.getDate();
  346. var nowDate = year + '年' + month + '月' + day + '日';
  347. return nowDate;
  348. }
  349. }
  350. }
  351. };
  352. </script>
  353. <style>
  354. page {
  355. height: 100%;
  356. min-height: 100%;
  357. background-color: #fff;
  358. }
  359. </style>
  360. <style lang="scss" scoped>
  361. .page_body {
  362. width: 100%;
  363. min-height: 100%;
  364. box-sizing: border-box;
  365. .page_top {
  366. z-index: 9;
  367. .banner_container {
  368. width: 730rpx;
  369. height: 369rpx;
  370. margin: 0 auto;
  371. .banner_img {
  372. width: 100%;
  373. height: 100%;
  374. }
  375. }
  376. .season {
  377. width: 100%;
  378. box-sizing: box-sizing;
  379. .season_con {
  380. margin: 15rpx 30rpx 0;
  381. .title {
  382. display: flex;
  383. align-items: center;
  384. font-size: 36rpx;
  385. color: #333;
  386. font-weight: 500;
  387. image {
  388. height: 44rpx;
  389. width: 44rpx;
  390. font-size: 32rpx;
  391. color: #333;
  392. margin-right: 17rpx;
  393. }
  394. }
  395. }
  396. .course_info {
  397. display: flex;
  398. align-items: center;
  399. justify-content: flex-start;
  400. &::before {
  401. content: '';
  402. display: block;
  403. width: 10rpx;
  404. height: 10rpx;
  405. border-radius: 50%;
  406. margin-right: 14rpx;
  407. background-color: #ea4a41;
  408. }
  409. .count {
  410. font-weight: bold;
  411. font-size: 28rpx;
  412. color: #ea4a41;
  413. }
  414. }
  415. .course_info > view,
  416. .course_time {
  417. display: flex;
  418. align-items: center;
  419. font-size: 26rpx;
  420. color: #333;
  421. // &::before {
  422. // content: '';
  423. // display: block;
  424. // width: 10rpx;
  425. // height: 10rpx;
  426. // border-radius: 50%;
  427. // margin-right: 14rpx;
  428. // background-color: #ea4a41;
  429. // }
  430. }
  431. .course_time,
  432. .course_info {
  433. margin-top: 33rpx;
  434. }
  435. }
  436. }
  437. .page_center {
  438. .tab_fixed {
  439. position: sticky;
  440. top: 0rpx;
  441. left: 0;
  442. z-index: 99;
  443. width: 100%;
  444. background-color: #fff;
  445. }
  446. .tab,
  447. .tab_fixed {
  448. .sign_tab {
  449. width: 100%;
  450. height: 90rpx;
  451. display: flex;
  452. justify-content: space-around;
  453. align-items: center;
  454. border-top: 1rpx solid #fafafa;
  455. border-bottom: 1rpx solid #fafafa;
  456. view {
  457. height: 85rpx;
  458. line-height: 85rpx;
  459. font-size: 32rpx;
  460. letter-spacing: 5rpx;
  461. font-weight: 500;
  462. color: #656565;
  463. &::after {
  464. content: '';
  465. display: block;
  466. width: 130rpx;
  467. height: 4rpx;
  468. border-radius: 2rpx;
  469. margin-left: 5rpx;
  470. }
  471. }
  472. .active {
  473. color: #ea4a41;
  474. &::after {
  475. background-color: #ea4a41;
  476. }
  477. }
  478. }
  479. .sign_list_tab {
  480. height: 88rpx;
  481. border-bottom: 1rpx solid #fafafa;
  482. font-size: 28rpx;
  483. color: #333;
  484. image {
  485. margin-right: 12rpx;
  486. }
  487. }
  488. }
  489. .scroll {
  490. .sign_list {
  491. padding: 0 30rpx;
  492. box-sizing: border-box;
  493. border-bottom: 1rpx solid #fafafa;
  494. height: 106rpx;
  495. .list_left {
  496. image {
  497. height: 88rpx;
  498. width: 88rpx;
  499. margin-right: 22rpx;
  500. border-radius: 50%;
  501. }
  502. view {
  503. text {
  504. font-size: 32rpx;
  505. color: #333;
  506. }
  507. view {
  508. color: #666;
  509. font-size: 28rpx;
  510. margin-top: 15rpx;
  511. }
  512. }
  513. }
  514. .list_right {
  515. font-size: 32rpx;
  516. color: #999;
  517. }
  518. }
  519. .more {
  520. text-align: center;
  521. height: 105rpx;
  522. line-height: 105rpx;
  523. font-size: 28rpx;
  524. }
  525. }
  526. }
  527. .table_scroll {
  528. .header {
  529. view {
  530. background-color: #f5f5f5;
  531. }
  532. }
  533. .table_con {
  534. view {
  535. background-color: #fff;
  536. }
  537. }
  538. .header,
  539. .table_con {
  540. white-space: nowrap;
  541. display: flex;
  542. view {
  543. width: 210rpx;
  544. height: 70rpx;
  545. flex-shrink: 0;
  546. border: 1rpx solid #e5e5e5;
  547. text-align: center;
  548. line-height: 70rpx;
  549. font-size: 28rpx;
  550. image {
  551. margin-left: 10rpx;
  552. vertical-align: middle;
  553. }
  554. }
  555. }
  556. }
  557. scroll-view {
  558. .scroll_con {
  559. padding-bottom: 118rpx;
  560. }
  561. }
  562. }
  563. </style>