trainModel.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <template>
  2. <div class="trainModel">
  3. <div class="visit-tips" v-show="activeType == 'visited'">
  4. <span
  5. >上周训练时长不足{{ playTime }}分钟或训练次数小于{{ trainNum }}次的学员<br />
  6. 需在每周三24:00前完成回访</span
  7. >
  8. </div>
  9. <search @onSearch="onSearch" placeholder="学生姓名或手机号">
  10. <template #left>
  11. <van-dropdown-menu style="padding-right: 0.1rem" :close-on-click-outside="false" active-color="#01C1B5">
  12. <van-dropdown-item title="筛选" ref="item" class="visitTime">
  13. <van-cell title="日期" is-link @click="showCalendar = true" title-style="font-size: .14rem;" :value="calendarValue" value-class="calendarColor"></van-cell>
  14. <van-cell title="学员类型" title-style="font-size: .14rem;" class="studentCell">
  15. <van-radio-group v-model="memberFlag" direction="horizontal">
  16. <van-radio name="">全部学员</van-radio>
  17. <van-radio name="1">会员学员</van-radio>
  18. <van-radio name="0">普通学员</van-radio>
  19. </van-radio-group>
  20. </van-cell>
  21. <div style="padding: 14px 16px; display: flex">
  22. <van-button block round @click="onReset" style="margin-right: 12px"> 重置 </van-button>
  23. <van-button type="primary" block round @click="onSubmit"> 确认 </van-button>
  24. </div>
  25. </van-dropdown-item>
  26. </van-dropdown-menu>
  27. </template>
  28. </search>
  29. <van-row class="searchArray">
  30. <van-col span="6" class="title-style" @click="onSort(0)">
  31. 训练时长
  32. <div>
  33. <i class="box box-up" :class="{ active: searchArray[0] == 'ASC' }" style="margin-bottom: 0.03rem"></i>
  34. <i class="box box-down" :class="{ active: searchArray[0] == 'DESC' }"></i>
  35. </div>
  36. </van-col>
  37. <van-col span="6" class="title-style" @click="onSort(1)">
  38. 训练次数
  39. <div>
  40. <i class="box box-up" :class="{ active: searchArray[1] == 'ASC' }" style="margin-bottom: 0.03rem"></i>
  41. <i class="box box-down" :class="{ active: searchArray[1] == 'DESC' }"></i>
  42. </div>
  43. </van-col>
  44. <van-col span="6" class="title-style" @click="onSort(2)">
  45. 训练天数
  46. <div>
  47. <i class="box box-up" :class="{ active: searchArray[2] == 'ASC' }" style="margin-bottom: 0.03rem"></i>
  48. <i class="box box-down" :class="{ active: searchArray[2] == 'DESC' }"></i>
  49. </div>
  50. </van-col>
  51. <van-col span="6" class="title-style" @click="onSort(3)">
  52. 评测次数
  53. <div>
  54. <i class="box box-up" :class="{ active: searchArray[3] == 'ASC' }" style="margin-bottom: 0.03rem"></i>
  55. <i class="box box-down" :class="{ active: searchArray[3] == 'DESC' }"></i>
  56. </div>
  57. </van-col>
  58. </van-row>
  59. <van-calendar v-model="showCalendar" :minDate="minDate" :default-date="defaultDate" :first-day-of-week="1" :formatter="formatterDay" color="#01C1B5" type="range" get-container="body" @select="selectDate" @confirm="onConfirm" @close="onClose" />
  60. </div>
  61. </template>
  62. <script>
  63. import Search from "@/components/Search";
  64. import dayjs from "dayjs";
  65. import { getNowDateAndMonday, getNowDateAndSunday } from "@/common/common";
  66. export default {
  67. props: {
  68. active: {
  69. type: String,
  70. default: "all",
  71. },
  72. defaultTime: {
  73. type: Number,
  74. default: 0,
  75. },
  76. trainNum: {
  77. type: [Number, String],
  78. default: 0,
  79. },
  80. playTime: {
  81. type: [Number, String],
  82. default: 0,
  83. },
  84. },
  85. components: { Search },
  86. data() {
  87. return {
  88. showCalendar: false,
  89. minDate: new Date(2000, 0, 1),
  90. defaultDate: [],
  91. memberFlag: "",
  92. // 类型为全部时
  93. startDay: null,
  94. endDay: null,
  95. search: null,
  96. searchArray: [null, null, null, null],
  97. searchType: {
  98. // ASC DESC
  99. totalPlayTime: null,
  100. trainNum: null,
  101. trainDay: null,
  102. recordNum: null,
  103. },
  104. };
  105. },
  106. async mounted() {
  107. let defaultTime = this.defaultTime;
  108. let day = defaultTime * 7;
  109. let startTime = new Date(),
  110. endTime = new Date();
  111. if (day > 0) {
  112. startTime = getNowDateAndMonday(dayjs().add(day, "day").format("YYYY-MM-DD"));
  113. endTime = getNowDateAndSunday(dayjs().add(day, "day").format("YYYY-MM-DD"));
  114. } else {
  115. startTime = getNowDateAndMonday(dayjs().subtract(Math.abs(day), "day").format("YYYY-MM-DD"));
  116. endTime = getNowDateAndSunday(dayjs().subtract(Math.abs(day), "day").format("YYYY-MM-DD"));
  117. }
  118. this.defaultDate = [new Date(startTime), new Date(endTime)];
  119. this.startDay = startTime;
  120. this.endDay = endTime;
  121. this.onSort();
  122. },
  123. computed: {
  124. calendarValue() {
  125. return `${dayjs(this.startDay).format("YYYY/MM/DD")} - ${dayjs(this.endDay).format("YYYY/MM/DD")}`;
  126. },
  127. activeType() {
  128. return this.active;
  129. },
  130. },
  131. methods: {
  132. onSort(type) {
  133. let searchArray = this.searchArray;
  134. searchArray.forEach((item, index) => {
  135. if (index != type) {
  136. searchArray[index] = null;
  137. }
  138. });
  139. if (searchArray[type] == "ASC") {
  140. searchArray[type] = "DESC";
  141. } else if (searchArray[type] == "DESC") {
  142. searchArray[type] = null;
  143. } else {
  144. searchArray[type] = "ASC";
  145. }
  146. this.$forceUpdate();
  147. // console.log(searchArray)
  148. this.onAllFilter();
  149. },
  150. onSearch(val) {
  151. this.search = val;
  152. this.onAllFilter();
  153. },
  154. onAllFilter() {
  155. const searchArray = this.searchArray;
  156. let currentIndex = null;
  157. let currentType = null;
  158. searchArray.forEach((item, index) => {
  159. if (item) {
  160. currentIndex = index;
  161. currentType = item;
  162. }
  163. });
  164. const searchType = ["totalPlayTime", "trainNum", "trainDay", "recordNum"];
  165. let params = {
  166. search: this.search,
  167. memberFlag: this.memberFlag,
  168. startTime: this.startDay,
  169. endTime: this.endDay,
  170. page: 1,
  171. sort: searchType[currentIndex],
  172. order: currentType,
  173. };
  174. this.$listeners.onLoad(params);
  175. },
  176. changeDropDownItemStatus() {
  177. this.$refs.item.toggle(false);
  178. },
  179. selectDate(date) {
  180. let [start, end] = date;
  181. if (start) {
  182. const num = dayjs(start).get("day");
  183. if (num === 0) {
  184. start = dayjs(start).subtract(6, "day");
  185. } else {
  186. start = dayjs(start).subtract(num - 1, "day");
  187. }
  188. }
  189. if (start) {
  190. const num = 7 - dayjs(start).get("day");
  191. if (num < 7) {
  192. end = dayjs(start).add(num, "day");
  193. }
  194. }
  195. this.defaultDate = [new Date(start.valueOf()), new Date(end.valueOf())];
  196. },
  197. onConfirm(date) {
  198. let [start, end] = date;
  199. this.showCalendar = false;
  200. if (start) {
  201. const num = dayjs(start).get("day");
  202. if (num === 0) {
  203. start = dayjs(start).subtract(6, "day");
  204. } else {
  205. start = dayjs(start).subtract(num - 1, "day");
  206. }
  207. }
  208. if (end) {
  209. const num = 7 - dayjs(end).get("day");
  210. if (num < 7) {
  211. end = dayjs(end).add(num, "day");
  212. }
  213. }
  214. this.startDay = dayjs(start).format("YYYY-MM-DD");
  215. this.endDay = dayjs(end).format("YYYY-MM-DD");
  216. //
  217. // this.changeDropDownItemStatus();
  218. // this.onAllFilter();
  219. },
  220. onSubmit() {
  221. this.changeDropDownItemStatus();
  222. this.onAllFilter();
  223. },
  224. onReset() {
  225. let defaultTime = this.defaultTime;
  226. let day = defaultTime * 7;
  227. let startTime = new Date(),
  228. endTime = new Date();
  229. if (day > 0) {
  230. startTime = getNowDateAndMonday(dayjs().add(day, "day").format("YYYY-MM-DD"));
  231. endTime = getNowDateAndSunday(dayjs().add(day, "day").format("YYYY-MM-DD"));
  232. } else {
  233. startTime = getNowDateAndMonday(dayjs().subtract(Math.abs(day), "day").format("YYYY-MM-DD"));
  234. endTime = getNowDateAndSunday(dayjs().subtract(Math.abs(day), "day").format("YYYY-MM-DD"));
  235. }
  236. this.defaultDate = [new Date(startTime), new Date(endTime)];
  237. this.startDay = startTime;
  238. this.endDay = endTime;
  239. this.memberFlag = "";
  240. this.onSubmit();
  241. },
  242. onClose() {
  243. // 关闭弹窗时初始化默认日期
  244. this.defaultDate = [new Date(this.startDay), new Date(this.endDay)];
  245. },
  246. formatterDay(day) {
  247. const month = day.date.getMonth() + 1;
  248. const date = day.date.getDate();
  249. let nowDate = new Date();
  250. if (month == nowDate.getMonth() + 1 && date == nowDate.getDate()) {
  251. day.text = "今天";
  252. }
  253. return day;
  254. },
  255. },
  256. };
  257. </script>
  258. <style lang="less" scoped>
  259. /deep/.van-dropdown-menu__title::after {
  260. border-color: transparent transparent #01c1b5 #01c1b5;
  261. }
  262. .calendarColor {
  263. color: #333;
  264. font-size: 0.14rem;
  265. }
  266. .visit-tips {
  267. background-color: #fff;
  268. // padding: 10px 10px 0;
  269. padding: 10px 12px 0;
  270. text-align: center;
  271. span {
  272. display: block;
  273. padding: 6px 12px;
  274. background-color: #fff6de;
  275. font-size: 12px;
  276. color: #ff802c;
  277. text-align: left;
  278. }
  279. }
  280. .searchArray {
  281. font-size: 0.14rem;
  282. padding-top: 0.15rem;
  283. padding-bottom: 0.12rem;
  284. color: #1a1a1a;
  285. background-color: #f5f5f5;
  286. }
  287. .title-style {
  288. display: flex;
  289. align-items: center;
  290. justify-content: center;
  291. }
  292. .box {
  293. display: flex;
  294. flex-direction: row;
  295. align-items: center;
  296. margin-left: 0.02rem;
  297. }
  298. .box-up {
  299. width: 0;
  300. height: 0;
  301. border-left: 4px solid transparent;
  302. border-right: 4px solid transparent;
  303. border-bottom: 5px solid #ccc;
  304. &.active {
  305. border-bottom-color: #01c1b5;
  306. }
  307. }
  308. .box-down {
  309. width: 0;
  310. height: 0;
  311. border-left: 4px solid transparent;
  312. border-right: 4px solid transparent;
  313. border-top: 5px solid #ccc;
  314. &.active {
  315. border-top-color: #01c1b5;
  316. }
  317. }
  318. .studentCell {
  319. /deep/.van-cell__title {
  320. flex-shrink: 0;
  321. flex: auto;
  322. }
  323. /deep/.van-cell__value {
  324. flex: 1 auto;
  325. }
  326. /deep/.van-radio-group--horizontal {
  327. justify-content: flex-end;
  328. font-size: 0.12rem;
  329. }
  330. }
  331. </style>