index.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <template>
  2. <!-- 头部 -->
  3. <nav-bar height="336" title="教师专业发展" :tabList="state.tabList" :tabBtns="state.tabBtns" :onlyTitle="false" :showFilterPicker="false" :showTabs="true" :showTabBtns="true" rightWidth="0rpx" @CommonFilterData="CommonFilterData" @GoBack="GoBack">
  4. <template #tab_btns_lef>
  5. <uni-data-select class="date_select" v-model="state.dateType" :clear="false" placeholder="请选择" :localdata="state.dateTypeList">
  6. </uni-data-select>
  7. </template>
  8. </nav-bar>
  9. <view class="page_content">
  10. <scroll-view
  11. class="scroll_view_y"
  12. :scroll-top="state.scrollTop"
  13. scroll-y="true"
  14. :refresher-enabled="false"
  15. :enable-back-to-top="true"
  16. :show-scrollbar="false"
  17. :scroll-with-animation="true"
  18. refresher-default-style="none"
  19. refresher-background="#F8F9FD"
  20. :refresher-triggered="state.isRefreshing"
  21. @scrolltolower="OnLoadMore"
  22. @refresherrefresh="OnRefresh"
  23. @scroll="OnScroll">
  24. <view class="refresh_loading" v-if="state.isRefreshing"><uni-load-more status="loading" /></view>
  25. <view class="page_list">
  26. <view class="list_item" v-for="item in state.pageList" :key="item.id" @click="PreviewHonorDetail(item.id)">
  27. <view class="item_honor_type">
  28. <view class="honor_type_item">{{item.awardDatetime}}</view>
  29. <view class="honor_type_item">{{item.awardDatetime}}</view>
  30. </view>
  31. <view class="honor_content">
  32. <image class="honor_pic" :src="item.certPicUrl"></image>
  33. <view class="honor_info">
  34. <view class="honor_name">{{item.honorName}}</view>
  35. <view class="teacher_name">获奖人:{{item.teacherName}}</view>
  36. <!-- 0 需审核 1 无审核 -->
  37. <view :class="['honor_status',{'waiting':item.honorStatus===0,'finish':item.reviewStatus == 1 || item.honorStatus===1,'reject':item.honorStatus===2}]">
  38. <template v-if="item.honorStatus===0">待审核</template>
  39. <template v-if="item.reviewStatus == 1 || item.honorStatus===1">已完成</template>
  40. <template v-if="item.honorStatus===2">已驳回</template>
  41. </view>
  42. <view class="created_at">上传时间:{{item.createdAt}}</view>
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. <view class="no_data" v-if="!state.isLoading && state.pageList.length == 0">
  48. <image class="no_data_img" src="@/static/image/bg/no_data.png"></image>
  49. <text class="no_data_text">暂无数据</text>
  50. </view>
  51. <uni-load-more v-if="state.pageList.length > 0" :status="state.loadStatus" />
  52. </scroll-view>
  53. </view>
  54. </template>
  55. <script setup>
  56. import navBar from '@/components/navBar.vue';
  57. import {queryHonorTypeList,queryHonorList} from '@/reqApi/teacherHonor.js';
  58. import {
  59. reactive,
  60. nextTick,
  61. onMounted
  62. } from 'vue';
  63. const state = reactive({
  64. tabList:[],
  65. dateTypeList:[{
  66. text:'全部',
  67. value:'',
  68. },{
  69. text:'最近3月',
  70. value:'3',
  71. },{
  72. text:'最近半年',
  73. value:'6',
  74. },{
  75. text:'最近1年',
  76. value:'12',
  77. }],
  78. tabBtns:[{
  79. label:'全部',
  80. value:'',
  81. },{
  82. label:'待审核',
  83. value:'0',
  84. },{
  85. label:'已完成',
  86. value:'1',
  87. },{
  88. label:'已驳回',
  89. value:'2',
  90. }],
  91. pageLists:[],//全部数据
  92. pageList:[],//列表数据
  93. honorTypeId:'',//荣誉类型
  94. dateType:'',//获奖时间 全部-不传值,最近三个月-3,最近 6 个月-6,最近一年-12
  95. honorStatus:'',//0-待审核,1-已审核(审核通过),2-已驳回(审核失败)
  96. pageSize: 30,
  97. pageNum: 1,
  98. pages:0,
  99. scrollTop:0,
  100. oldScrollTop:0,
  101. isRefreshing:false,//设置当前下拉刷新状态,true 表示下拉刷新已经被触发,false 表示下拉刷新未被触发
  102. isLoading:true,//加载中
  103. noMoreData:false,//没有更多数据了
  104. loadStatus:'more',//loading状态
  105. })
  106. onMounted((option) => {
  107. GetHonorTypeList();
  108. OnLoadData(true);
  109. });
  110. //查询荣誉类型列表
  111. const GetHonorTypeList = () => {
  112. queryHonorTypeList().then(res=>{
  113. if(res.code == 200){
  114. const list = res?.data || [];
  115. const tabList = list.map(item=>({
  116. ...item,
  117. label:item.honorTypeName,
  118. value:item.id
  119. }))
  120. state.tabList = [{label:'全部',value:''},...tabList];
  121. }
  122. })
  123. }
  124. //切换条件选择器
  125. const CommonFilterData = (filterOptions,type) => {
  126. const { tabsSelected,tabBtnSelected } = filterOptions;
  127. state.honorTypeId = tabsSelected;
  128. state.honorStatus = tabBtnSelected;
  129. OnLoadData(true)
  130. }
  131. /*
  132. *获取数据
  133. * initPage:初始分页 从第一开始
  134. */
  135. const OnLoadData = (initPage) => {
  136. state.isLoading = true;
  137. state.loadStatus = 'loading';
  138. if (initPage) {
  139. // uni.showLoading({
  140. // title: '加载中'
  141. // });
  142. state.pageNum = 1;//如果是下拉刷新、重新查询 默认加载第一页
  143. queryHonorList({
  144. honorTypeId:state.honorTypeId,//荣誉类型
  145. honorStatus:state.honorStatus,//0-待审核,1-已审核(审核通过),2-已驳回(审核失败)
  146. startDatetime:'',
  147. endDatetime:'',
  148. dateType:state.dateType,
  149. }).then(res=>{
  150. if(res.code == 200){
  151. const tableData = res?.data || [];
  152. state.pageLists = tableData;//全部数据
  153. const total = tableData?.length || 0;//总数
  154. state.pages = Math.ceil(total / state.pageSize);//总页数
  155. //默认加载
  156. state.pageList = state.pageLists.slice(0, state.pageSize);
  157. //没有更多了
  158. state.noMoreData = state.pageNum == state.pages;
  159. //分页+1
  160. state.pageNum++;
  161. state.isLoading = false;
  162. state.isRefreshing = false;//下拉刷新未被触发
  163. state.loadStatus = state.noMoreData?'no-more':'more';
  164. }
  165. }).finally(()=>{
  166. // uni.hideLoading();
  167. //返回到页面顶部
  168. if(initPage){
  169. GoTop();
  170. }
  171. })
  172. }else{
  173. const start = (state.pageNum - 1) * state.pageSize;
  174. const end = start + state.pageSize;
  175. const list = state.pageLists.slice(start, end);
  176. state.pageList = [...state.pageList, ...list];
  177. state.noMoreData = state.pageNum == state.pages;
  178. state.pageNum++;
  179. setTimeout(() => {
  180. state.isLoading = false;
  181. state.isRefreshing = false; //下拉刷新未被触发
  182. state.loadStatus = state.noMoreData?'no-more':'more';
  183. }, 0)
  184. }
  185. }
  186. // 自定义下拉刷新被触发 下拉刷新
  187. const OnRefresh = () =>{
  188. state.isRefreshing = true;//下拉刷新已经被触发
  189. OnLoadData(true);
  190. }
  191. //滚动到底部/右边 触发上拉刷新
  192. const OnLoadMore = () => {
  193. if (state.isLoading || state.noMoreData) return;
  194. OnLoadData(false);
  195. }
  196. // 滚动时触发
  197. const OnScroll = (e) => {
  198. state.oldScrollTop = e.detail.scrollTop;
  199. }
  200. //返回到顶部
  201. const GoTop = () => {
  202. // 解决view层不同步的问题
  203. state.scrollTop = state.oldScrollTop;
  204. nextTick(() => {
  205. state.scrollTop = 0
  206. });
  207. }
  208. //返回
  209. const GoBack = () => {
  210. uni.navigateBack({
  211. delta: 1
  212. });
  213. }
  214. const PreviewHonorDetail = () => {
  215. uni.navigateTo({
  216. url: `/pages/teacherHonor/honorTeacher/honorTeacherDetail?teacherId=${teacherId}`
  217. });
  218. }
  219. </script>
  220. <style lang="scss" scoped>
  221. .date_select{
  222. width: 196rpx;
  223. flex: auto;
  224. flex-shrink: 0;
  225. :deep(.uni-select__selector){
  226. position: fixed !important;
  227. top:313rpx !important;
  228. left: 24rpx;
  229. width: 196rpx;
  230. }
  231. }
  232. .page_content{
  233. height: calc(100% - 472rpx);
  234. .scroll_view_y{
  235. height: 100%;
  236. .refresh_loading{
  237. padding: 10rpx 0;
  238. }
  239. }
  240. .page_list{
  241. display: flex;
  242. width: 100%;
  243. flex-direction: column;
  244. .list_item{
  245. display: flex;
  246. width: 100%;
  247. flex-direction: column;
  248. margin-top: 32rpx;
  249. &:nth-child(1){
  250. margin-top: 0;
  251. }
  252. .item_honor_type{
  253. display: flex;
  254. width: 100%;
  255. .honor_type_item{
  256. font-weight: 400;
  257. font-size: 32rpx;
  258. color: #333333;
  259. &:nth-child(1){
  260. font-weight: 500;
  261. margin-right: 24rpx;
  262. }
  263. }
  264. }
  265. .honor_content{
  266. margin-top: 16rpx;
  267. display: flex;
  268. width: 100%;
  269. padding: 16rpx;
  270. box-sizing: border-box;
  271. background-color: #F8FAFE;
  272. border-radius: 15rpx;
  273. border: 2rpx solid #EBEEF5;
  274. .honor_pic{
  275. width: 320rpx;
  276. height: 200rpx;
  277. border-radius: 8rpx;
  278. margin-right: 16rpx;
  279. flex-shrink: 0;
  280. }
  281. .honor_info{
  282. flex:1;
  283. display: flex;
  284. justify-content: space-around;
  285. flex-direction: column;
  286. overflow: hidden;
  287. .honor_name{
  288. font-weight: 500;
  289. font-size: 32rpx;
  290. color: #333333;
  291. width: 100%;
  292. white-space: nowrap;
  293. overflow: hidden;
  294. text-overflow: ellipsis;
  295. }
  296. .teacher_name{
  297. font-weight: 400;
  298. font-size: 28rpx;
  299. color: #333333;
  300. width: 100%;
  301. white-space: nowrap;
  302. overflow: hidden;
  303. text-overflow: ellipsis;
  304. }
  305. .honor_status{
  306. font-weight: 500;
  307. font-size: 28rpx;
  308. width: 100%;
  309. &.waiting{
  310. color: #2E64FA;
  311. }
  312. &.finish{
  313. color: #2BC644;
  314. }
  315. &.reject{
  316. color: #F56C6C;
  317. }
  318. }
  319. .created_at{
  320. width: 100%;
  321. white-space: nowrap;
  322. overflow: hidden;
  323. text-overflow: ellipsis;
  324. font-weight: 400;
  325. font-size: 28rpx;
  326. color: #999999;
  327. }
  328. }
  329. }
  330. }
  331. }
  332. }
  333. </style>