My_filter.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <template>
  2. <view class="container">
  3. <u-popup :show="show" :customStyle="{ width: '88vw' }" :overlayStyle="{ zIndex: '997' }" zIndex="998" mode="right"
  4. @close="close" :closeOnClickOverlay="true">
  5. <view v-if="isBar" :style="{ height: (tovw(CustomBar + (headTop - 0))) }" />
  6. <My_listbox :pullDown="false" ref="box">
  7. <view v-for="(it, i) in filter" :key="it.label">
  8. <view class="label">
  9. {{ it.label }}
  10. </view>
  11. <view class="value-box">
  12. <view class="item" v-for="(item, index) in it.list" :key="index"
  13. :class="it.selectIndex == index ? 'active' : ''" @click="changeValue(i, index)">
  14. {{ it.showKey ? item[it.showKey] : item }}
  15. </view>
  16. </view>
  17. </view>
  18. <block v-if="dateRange">
  19. <view class="label">
  20. 时间区间
  21. </view>
  22. <view class="date-box">
  23. <scroll-view :scroll-x="true">
  24. <view class="options">
  25. <view class="item" :class="day == 1 ? 'active' : ''" @click="fast(1)">
  26. 今天
  27. </view>
  28. <view class="item" :class="day == 7 ? 'active' : ''" @click="fast(7)">
  29. 7天
  30. </view>
  31. <view class="item" :class="day == 30 ? 'active' : ''" @click="fast(30)">
  32. 30天
  33. </view>
  34. <view style="width: 10px;" />
  35. <u-number-box :value="day" @change="valChange" />
  36. </view>
  37. </scroll-view>
  38. <view class="row" style="margin-top: 20px">
  39. <picker mode="date" class="date-box" :style="{ color: begindate ? '#333' : '#ddd' }"
  40. :value="begindate" data-name="begindate" :end="enddate" @change="onDateChange">
  41. {{ begindate || '开始日期' }}
  42. </picker>
  43. <view style="padding: 0 10px;">
  44. -
  45. </view>
  46. <picker mode="date" class="date-box" :style="{ color: enddate ? '#333' : '#ddd' }"
  47. :value="enddate" data-name="enddate" @change="onDateChange" :start="begindate">
  48. {{ enddate || '结束日期' }}
  49. </picker>
  50. </view>
  51. </view>
  52. <!--
  53. <view class="row">
  54. 区间:<picker mode="date" class="date-box" :style="{ color: begindate ? '#333' : '#ddd' }"
  55. :value="begindate" data-name="begindate" :start="start" :end="enddate" @change="onDateChange">
  56. {{ begindate || '开始日期' }}
  57. </picker>
  58. <view style="padding: 0 10px;">
  59. -
  60. </view>
  61. <picker mode="date" class="date-box" :style="{ color: enddate ? '#333' : '#ddd' }" :value="enddate"
  62. data-name="enddate" @change="onDateChange" :start="begindate">
  63. {{ enddate || '结束日期' }}
  64. </picker>
  65. </view>
  66. -->
  67. </block>
  68. </My_listbox>
  69. <view id="bottom">
  70. <view class="bottom">
  71. <view class="bot" @click="show = false" hover-class="navigator-hover">
  72. 关闭
  73. </view>
  74. <view v-if="isReset" @click="reset" class="bot reset" hover-class="navigator-hover">
  75. 重置
  76. </view>
  77. <view v-if="loading" class="bot confirm" hover-class="navigator-hover">
  78. <u-loading-icon color="#007aff" mode="semicircle" /> 查询中...
  79. </view>
  80. <view v-else class="bot confirm" @click="confirm" hover-class="navigator-hover">
  81. 确定
  82. </view>
  83. </view>
  84. <view class="safety" />
  85. </view>
  86. </u-popup>
  87. </view>
  88. </template>
  89. <script>
  90. import { formatTime } from "../utils/getTime";
  91. export default {
  92. name: 'My_filter',
  93. props: {
  94. isReset: {
  95. type: Boolean,
  96. default: true
  97. },
  98. isBar: {
  99. type: Boolean,
  100. default: true
  101. },
  102. headTop: {
  103. type: Number,
  104. default: 0
  105. },
  106. filter1: {
  107. type: Array,
  108. default: () => [{
  109. label: "筛选项",
  110. list: [{
  111. name: 1
  112. }, {
  113. name: 2
  114. }, {
  115. name: 3
  116. }],
  117. selectKey: "name",
  118. selectIndex: null,
  119. default: null,
  120. showKey: "name",
  121. key: "name",
  122. }]
  123. },
  124. dateRange: Boolean,
  125. start: String,
  126. onConfirm: Function
  127. },
  128. data() {
  129. return {
  130. show: false,
  131. CustomBar: this.CustomBar,
  132. day: 0,
  133. begindate: "",
  134. enddate: "",
  135. filter: [],
  136. loading: false
  137. };
  138. },
  139. methods: {
  140. open(num) {
  141. this.show = true;
  142. this.filter = this.filter1;
  143. setTimeout(() => {
  144. this.getHeight("#bottom", this, false).then(({ height }) => this.$refs.box.setHeight('minus', (height - 0) + (num - 0)))
  145. }, 100);
  146. },
  147. close() {
  148. this.show = false;
  149. this.loading = false;
  150. },
  151. changeValue(index1, index2) {
  152. let newltem = this.filter[index1];
  153. newltem.selectIndex = newltem.selectIndex == index2 ? null : index2;
  154. this.$set(this.filter, index1, newltem);
  155. },
  156. reset() {
  157. this.filter = this.filter.map(v => {
  158. v.selectIndex = v.default || null;
  159. return v
  160. });
  161. this.day = 0;
  162. this.begindate = "";
  163. this.enddate = "";
  164. },
  165. confirm() {
  166. let obj = {};
  167. this.filter.forEach(v => {
  168. let value = v.list[v.selectIndex] || "";
  169. if (value && v.selectKey) value = value[v.selectKey]
  170. obj[v.key] = value;
  171. })
  172. if (this.dateRange) {
  173. obj.begindate = this.begindate;
  174. obj.enddate = this.enddate;
  175. }
  176. this.loading = true;
  177. this.$emit("onConfirm", obj)
  178. },
  179. fast(num) {
  180. return new Promise((resolve) => {
  181. this.day = num;
  182. let now = new Date().getTime(),
  183. end = now + 86400000,
  184. beg = end - (num * 86400000);
  185. this.begindate = formatTime(new Date(beg)).split(' ')[0];
  186. this.enddate = formatTime(new Date(end)).split(' ')[0];
  187. resolve()
  188. })
  189. },
  190. valChange(e) {
  191. this.fast(e.value)
  192. },
  193. onDateChange(e) {
  194. this[e.target.dataset.name] = e.detail.value;
  195. if (this.begindate && this.enddate) {
  196. let end = new Date(this.enddate).getTime(),
  197. beg = new Date(this.begindate).getTime();
  198. this.day = (end - beg) / 86400000;
  199. }
  200. },
  201. },
  202. }
  203. </script>
  204. <style lang="scss" scoped>
  205. .label {
  206. line-height: 20px;
  207. font-size: 14px;
  208. color: #333333;
  209. padding: 15px 10px 10px;
  210. }
  211. .date-box {
  212. .options {
  213. display: flex;
  214. .item {
  215. display: flex;
  216. align-items: center;
  217. justify-content: center;
  218. background: #F5F5F5;
  219. border-radius: 4px;
  220. margin-left: 10px;
  221. font-size: 14px;
  222. color: #333333;
  223. overflow: hidden;
  224. box-sizing: border-box;
  225. padding: 6px 12px;
  226. flex-shrink: 0;
  227. }
  228. .active {
  229. background: #0B3F7E !important;
  230. color: #FFFFFF !important;
  231. }
  232. /deep/ .u-number-box__minus,
  233. /deep/.u-number-box__input,
  234. /deep/.u-number-box__plus {
  235. height: 30px !important;
  236. }
  237. /deep/ .u-number-box__input {
  238. width: 35px !important;
  239. }
  240. }
  241. .row {
  242. display: flex;
  243. align-items: center;
  244. font-size: 14px;
  245. color: #646566;
  246. padding: 10px;
  247. padding-top: 0;
  248. border-bottom: 1px solid #ddd;
  249. box-sizing: border-box;
  250. .date-box {
  251. flex: 1;
  252. height: 35px;
  253. line-height: 35px;
  254. background: #FFFFFF;
  255. border-radius: 4px;
  256. border: 1px solid #CCCCCC;
  257. font-size: 14px;
  258. padding-left: 10px;
  259. }
  260. }
  261. }
  262. .value-box {
  263. display: flex;
  264. flex-wrap: wrap;
  265. box-sizing: border-box;
  266. border-bottom: 1px solid #ddd;
  267. .item {
  268. display: flex;
  269. align-items: center;
  270. justify-content: center;
  271. width: 97px;
  272. height: 36px;
  273. background: #F5F5F5;
  274. border-radius: 4px;
  275. margin-left: 10px;
  276. margin-bottom: 10px;
  277. font-size: 14px;
  278. color: #333333;
  279. overflow: hidden;
  280. padding: 0 6px;
  281. box-sizing: border-box;
  282. }
  283. .active {
  284. background: #0B3F7E !important;
  285. color: #FFFFFF !important;
  286. }
  287. }
  288. .row {
  289. display: flex;
  290. align-items: center;
  291. font-size: 14px;
  292. color: #646566;
  293. padding: 10px;
  294. padding-top: 0;
  295. border-bottom: 1px solid #ddd;
  296. box-sizing: border-box;
  297. .date-box {
  298. flex: 1;
  299. height: 45px;
  300. line-height: 45px;
  301. background: #FFFFFF;
  302. border-radius: 4px;
  303. border: 1px solid #CCCCCC;
  304. font-size: 14px;
  305. padding-left: 10px;
  306. }
  307. }
  308. .bottom {
  309. display: flex;
  310. justify-content: space-between;
  311. align-content: center;
  312. width: 100%;
  313. border-top: 1px solid #ddd;
  314. padding: 10px;
  315. box-sizing: border-box;
  316. .bot {
  317. display: flex;
  318. justify-content: center;
  319. align-items: center;
  320. width: 93px;
  321. height: 45px;
  322. background: #FFFFFF;
  323. border-radius: 4px;
  324. border: 1px solid #CCCCCC;
  325. font-size: 15px;
  326. color: #666666;
  327. }
  328. .reset {
  329. border-color: #0B3F7E;
  330. color: #0B3F7E;
  331. }
  332. .confirm {
  333. border-color: #0B3F7E;
  334. background-color: #0B3F7E;
  335. color: #FFFFFF;
  336. }
  337. /deep/ .u-button {
  338. background: #FFFFFF;
  339. border-radius: 4px;
  340. margin: 0 !important;
  341. }
  342. /deep/ .u-button__text {
  343. font-size: 14px !important;
  344. }
  345. }
  346. </style>