tm-pickersDateView - 副本 (2).vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. <!-- 日期组件 -->
  2. <template>
  3. <view class="tm-pickersDateView flex-start px-24" :class="[black_tmeme ? 'grey-darken-5' : bgColor]">
  4. <!-- :value="value_default" @change="change" -->
  5. <picker-view
  6. @pickstart="$emit('aniStart')"
  7. @pickend="$emit('aniEnd')"
  8. @change="change"
  9. v-if="list_cD != null"
  10. :value="value_default"
  11. :mask-style="black_tmeme ? 'opacity:0;' : ''"
  12. indicator-style="height:50px;"
  13. indicator-class="tm-pickersCView-item-h"
  14. class="tm-pickersCView-wk"
  15. >
  16. <picker-view-column v-for="(item, key) in list_cD" :key="key">
  17. <view
  18. class="tm-pickersCView-item fulled-height flex-center "
  19. style="margin: 0 5px;"
  20. :class="[value_default[reIndex(key)] == index_pub ? ' text-weight-b active' : '', black_tmeme ? 'bk' : '', 'text-size-n']"
  21. v-for="(item_data, index_pub) in item"
  22. :key="index_pub"
  23. >
  24. <text>{{ buqi(item_data) }}</text>
  25. <text v-if="mode">{{ modhz[key] }}</text>
  26. </view>
  27. </picker-view-column>
  28. </picker-view>
  29. </view>
  30. </template>
  31. <script>
  32. /**
  33. * 日期下拉选择器(嵌入式)
  34. * @description 多级关联,单级关联选择
  35. * @property {Array} default-value = [] 默认:当前的时间,初始显示的时间
  36. * @property {String|Number} item-height = [34|42|50|58|62] 项目的高度单位px
  37. * @property {String|Boolean} black = [true|false] 是否开启暗黑模式。
  38. * @property {String|Boolean} disabled = [true|false] 是否禁用
  39. * @property {String} bg-color = [white|blue] 默认:white,白色背景;请填写背景的主题色名称。
  40. * @property {Object} show-detail = [{year:true,month:true,day:true,hour:false,min:false,sec:false}] 默认:{year:true,month:true,day:true,hour:false,min:false,sec:false}
  41. * @property {String} start = [1900-1-1 00:00:00] 默认:1900-1-1 00:00:00,开始的时间
  42. * @property {String} end = [] 默认:当前,结束的时间
  43. * @property {String|Boolean} mode = [true|false] 默认:true,是否显示中文年,月后缀
  44. * @property {String|Boolean} full-number = [true|false] 默认:true,是否把个位数补齐双位数
  45. */
  46. export default {
  47. name: 'tm-pickersDateView',
  48. props: {
  49. // 行高。
  50. itemHeight: {
  51. type: String | Number,
  52. default: 40
  53. },
  54. black: {
  55. type: String | Boolean,
  56. default: null
  57. },
  58. // 是否禁用
  59. disabled: {
  60. type: String | Boolean,
  61. default: false
  62. },
  63. // 背景颜色,主题色名称。
  64. bgColor: {
  65. type: String,
  66. default: 'white'
  67. },
  68. //要展示的时间。
  69. showDetail: {
  70. type: Object,
  71. default: () => {
  72. return {
  73. year: true, //年
  74. month: true, //月
  75. day: true, //天
  76. hour: false, //小时
  77. min: false, //分
  78. sec: false //秒
  79. };
  80. }
  81. },
  82. start: {
  83. type: String,
  84. default: '1949-1-1 00:00:00'
  85. },
  86. end: {
  87. type: String,
  88. default: ''
  89. },
  90. defaultValue: '',
  91. // 是否显示中文年,月后缀
  92. mode: {
  93. type: String | Boolean,
  94. default: true
  95. },
  96. //要展示的时间。
  97. modeValue: {
  98. type: Object,
  99. default: () => {
  100. return {
  101. year: '年', //年
  102. month: '月', //月
  103. day: '日', //天
  104. hour: '时', //小时
  105. min: '分', //分
  106. sec: '秒' //秒
  107. };
  108. }
  109. },
  110. // 是否把个位数补齐双位数
  111. fullNumber: {
  112. type: String | Boolean,
  113. default: true
  114. }
  115. },
  116. data() {
  117. return {
  118. scrollEvent: 0,
  119. childrenIndex: 0,
  120. scrollChildrenIndex: 0,
  121. listIndex: [],
  122. listData: [[], [], [], [], [], []],
  123. dataCauser: {
  124. year: false, //年
  125. month: false, //月
  126. day: false, //天
  127. hour: false, //小时
  128. min: false, //分
  129. sec: false //秒
  130. },
  131. hoz: {
  132. year: '年', //年
  133. month: '月', //月
  134. day: '日', //天
  135. hour: '时', //小时
  136. min: '分', //分
  137. sec: '秒' //秒
  138. },
  139. startTime: null,
  140. endTime: null,
  141. value_default: [],
  142. pre_value: [],
  143. syheng_key: [],
  144. list_cD: null
  145. };
  146. },
  147. created() {
  148. this.dataCauser = { ...this.dataCauser, ...this.showDetail };
  149. let ls = Object.keys(this.dataCauser);
  150. for (let i = 0; i < this.listData.length; i++) {
  151. let p = {
  152. itemIndex: 0,
  153. childrenIndex: 0,
  154. wz: 0
  155. };
  156. p[ls[i]] = this.dataCauser[ls[i]];
  157. this.listIndex.push(p);
  158. }
  159. },
  160. async mounted() {
  161. this.chulisdata();
  162. await uni.$tm.sleep(60);
  163. this.chulishijian();
  164. this.setDefaultValue();
  165. },
  166. watch: {
  167. defaultValue: async function() {
  168. if (this.list_cD == null) return;
  169. await this.setDefaultValue();
  170. },
  171. start: async function() {
  172. if (this.list_cD == null) return;
  173. this.chulisdata();
  174. this.chulishijian();
  175. await this.setDefaultValue();
  176. },
  177. end: async function() {
  178. if (this.list_cD == null) return;
  179. await this.setDefaultValue();
  180. }
  181. },
  182. computed: {
  183. black_tmeme: function() {
  184. if (this.black !== null) return this.black;
  185. return this.$tm.vx.state().tmVuetify.black;
  186. },
  187. modhz: function() {
  188. return { ...this.hoz, ...this.modeValue };
  189. }
  190. },
  191. methods: {
  192. reIndex(key) {
  193. let id = 0;
  194. for (let i = 0; i < this.syheng_key.length; i++) {
  195. if (this.syheng_key[i] == key) {
  196. id = i;
  197. break;
  198. }
  199. }
  200. return id;
  201. },
  202. chulishijian() {
  203. let kl = Object.keys(this.dataCauser);
  204. let d = {};
  205. let pk = [];
  206. for (let i = 0; i < kl.length; i++) {
  207. if (this.dataCauser[kl[i]] == true) {
  208. let sj = null;
  209. let key = '';
  210. if (kl[i] == 'year') {
  211. sj = this.listData[0];
  212. key = 'year';
  213. } else if (kl[i] == 'month') {
  214. sj = this.listData[1];
  215. key = 'month';
  216. } else if (kl[i] == 'day') {
  217. sj = this.listData[2];
  218. key = 'day';
  219. } else if (kl[i] == 'hour') {
  220. sj = this.listData[3];
  221. key = 'hour';
  222. } else if (kl[i] == 'min') {
  223. sj = this.listData[4];
  224. key = 'min';
  225. } else if (kl[i] == 'sec') {
  226. sj = this.listData[5];
  227. key = 'sec';
  228. }
  229. d[kl[i]] = {...sj};
  230. pk.push(key);
  231. }
  232. }
  233. this.list_cD = {...d};
  234. this.syheng_key = [...pk];
  235. },
  236. buqi(val) {
  237. return val > 9 ? '' + val : '0' + val;
  238. },
  239. SeletecdeIndexdefault() {
  240. let kl = Object.keys(this.dataCauser);
  241. let d = [];
  242. for (let i = 0; i < this.listIndex.length; i++) {
  243. if (this.listIndex[i][kl[i]] == true) {
  244. d.push(this.listIndex[i].itemIndex);
  245. }
  246. }
  247. this.value_default = d;
  248. },
  249. // 获取当前选中的数据。
  250. getSelectedValue() {
  251. let t = this;
  252. let ap = [];
  253. this.listIndex.forEach((item, index) => {
  254. ap.push(t.listData[index][item.itemIndex]);
  255. });
  256. let jg = {
  257. year: ap[0], //年
  258. month: ap[1], //月
  259. day: ap[2], //天
  260. hour: ap[3], //小时
  261. min: ap[4], //分
  262. sec: ap[5] //秒
  263. };
  264. let ar = Object.keys(this.dataCauser);
  265. ar.forEach(item => {
  266. if (t.dataCauser[item] === false) {
  267. delete jg[item];
  268. }
  269. });
  270. return jg;
  271. },
  272. chulisdata() {
  273. if (typeof this.showDetail === 'object') {
  274. this.dataCauser = { ...this.dataCauser, ...this.showDetail };
  275. }
  276. this.startTime = new Date(this.start.replace(/-/g, '/'));
  277. if (isNaN(this.startTime.getFullYear())) {
  278. this.startTime = new Date('1949/1/1 00:00:00');
  279. }
  280. this.endTime = new Date(this.end.replace(/-/g, '/'));
  281. if (isNaN(this.endTime.getFullYear())) {
  282. this.endTime = new Date();
  283. }
  284. let s_y = this.startTime.getFullYear();
  285. let s_m = this.startTime.getMonth() + 1;
  286. let s_d = this.startTime.getDate();
  287. let s_h = this.startTime.getHours();
  288. let s_mm = this.startTime.getMinutes();
  289. let s_s = this.startTime.getSeconds();
  290. let e_y = this.endTime.getFullYear();
  291. let e_m = this.endTime.getMonth() + 1;
  292. let e_d = this.endTime.getDate();
  293. let e_h = this.endTime.getHours();
  294. let e_mm = this.endTime.getMinutes();
  295. let e_s = this.endTime.getSeconds();
  296. let n_y = this.listData[0][this.listIndex[0].itemIndex];
  297. n_y = n_y == undefined ? 1949 : n_y;
  298. let n_m = this.listData[1][this.listIndex[1].itemIndex];
  299. n_m = n_m == undefined ? 1 : n_m;
  300. let n_d = this.listData[2][this.listIndex[2].itemIndex];
  301. n_d = n_d == undefined ? 1 : n_d;
  302. let n_h = this.listData[3][this.listIndex[3].itemIndex];
  303. n_h = n_h == undefined ? 0 : n_h;
  304. let n_mm = this.listData[4][this.listIndex[4].itemIndex];
  305. n_mm = n_mm == undefined ? 0 : n_mm;
  306. let n_s = this.listData[5][this.listIndex[5].itemIndex];
  307. n_s = n_s == undefined ? 0 : n_s;
  308. let nowDate = new Date(n_y + '/' + n_m + '/' + n_d + ' ' + n_h + ':' + n_mm + ':' + n_s);
  309. function monthDay(year, month) {
  310. let date = new Date(year, month, 1, 0, 0, 0);
  311. let yesterDay = new Date(date - 1000);
  312. return yesterDay.getDate();
  313. }
  314. //年,开始,结束。
  315. let tsb = [[s_y, e_y]];
  316. for (let i = 1; i < 6; i++) {
  317. let st = 0;
  318. let et = 0;
  319. if (i == 1) {
  320. st = 1;
  321. et = 12;
  322. if (n_y === s_y) {
  323. st = s_m;
  324. et = 12;
  325. }
  326. if (n_y === e_y) {
  327. st = 1;
  328. et = e_m;
  329. }
  330. if(s_y===e_y&&n_y===s_y){
  331. st = s_m;
  332. et = e_m;
  333. }
  334. }
  335. if (i == 2) {
  336. let months = [31, monthDay(n_y, 2), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  337. st = 1;
  338. et = months[n_m - 1];
  339. if (n_y === s_y && n_m === s_m) {
  340. st = s_d;
  341. }
  342. if (n_y === e_y && n_m === e_m) {
  343. et = e_d;
  344. }
  345. }
  346. if (i == 3) {
  347. st = 0;
  348. et = 23;
  349. if (n_y === s_y && n_m === s_m && n_d === s_d) {
  350. st = s_h;
  351. }
  352. if (n_y === e_y && n_m === e_m && n_d === e_d) {
  353. et = e_h;
  354. }
  355. }
  356. if (i == 4) {
  357. st = 0;
  358. et = 59;
  359. if (n_y === s_y && n_m === s_m && n_d === s_d && n_h === s_h) {
  360. st = s_mm;
  361. }
  362. if (n_y === e_y && n_m === e_m && n_d === e_d && n_h === e_h) {
  363. et = e_mm;
  364. }
  365. }
  366. if (i == 5) {
  367. st = 0;
  368. et = 59;
  369. if (n_y === s_y && n_m === s_m && n_d === s_d && n_h === s_h && n_mm === s_mm) {
  370. st = s_s;
  371. }
  372. if (n_y === e_y && n_m === e_m && n_d === e_d && n_h === e_h && n_mm === e_mm) {
  373. et = e_s;
  374. }
  375. }
  376. tsb.push([st, et]);
  377. }
  378. for (let ik = 0; ik < tsb.length; ik++) {
  379. let idate = tsb[ik];
  380. let py_data = [];
  381. for (let i = idate[0]; i <= idate[1]; i++) {
  382. py_data.push(i);
  383. }
  384. this.listData.splice(ik, 1, py_data);
  385. }
  386. return this.listData;
  387. },
  388. setDefaultValue(date) {
  389. this.chulisdata();
  390. this.chulishijian();
  391. uni.$tm.sleep(50)
  392. .then(()=>this.inits(date))
  393. .then(()=>{
  394. this.chulisdata();
  395. this.chulishijian();
  396. return uni.$tm.sleep(50);
  397. }).then(()=>{
  398. this.SeletecdeIndexdefault();
  399. this.chulisdata();
  400. })
  401. },
  402. async inits(date) {
  403. let t = this;
  404. let mobj;
  405. if (date) {
  406. mobj = new Date(date.replace(/-/g, '/'));
  407. } else {
  408. try {
  409. mobj = new Date(this.defaultValue.replace(/-/g, '/'));
  410. } catch (e) {
  411. mobj = new Date();
  412. }
  413. if (!this.defaultValue || isNaN(mobj.getFullYear())) {
  414. mobj = new Date();
  415. }
  416. }
  417. let s_y = this.startTime.getFullYear();
  418. let s_m = this.startTime.getMonth() + 1;
  419. let s_d = this.startTime.getDate();
  420. let s_h = this.startTime.getHours();
  421. let s_mm = this.startTime.getMinutes();
  422. let s_s = this.startTime.getSeconds();
  423. let e_y = this.endTime.getFullYear();
  424. let e_m = this.endTime.getMonth() + 1;
  425. let e_d = this.endTime.getDate();
  426. let e_h = this.endTime.getHours();
  427. let e_mm = this.endTime.getMinutes();
  428. let e_s = this.endTime.getSeconds();
  429. let n_y = mobj.getFullYear();
  430. let n_m = mobj.getMonth() + 1;
  431. let n_d = mobj.getDate();
  432. let n_h = mobj.getHours();
  433. let n_mm = mobj.getMinutes();
  434. let n_s = mobj.getSeconds();
  435. if (mobj.getTime() >= this.endTime.getTime()) {
  436. n_y = e_y;
  437. n_m = e_m;
  438. n_d = e_d;
  439. n_h = e_h;
  440. n_mm = e_mm;
  441. n_s = e_s;
  442. }
  443. if (mobj.getTime() <= this.startTime.getTime()) {
  444. n_y = s_y;
  445. n_m = s_m;
  446. n_d = s_d;
  447. n_h = s_h;
  448. n_mm = s_mm;
  449. n_s = s_s;
  450. }
  451. let tsb = [n_y, n_m, n_d, n_h, n_mm, n_s];
  452. for (let ik = 0; ik < tsb.length; ik++) {
  453. let itemIndex_y = this.listData[ik].findIndex(item => item == tsb[ik]);
  454. if (itemIndex_y > -1) {
  455. this.$set(this.listIndex[ik], 'itemIndex', itemIndex_y);
  456. } else {
  457. this.$set(this.listIndex[ik], 'itemIndex', 0);
  458. }
  459. }
  460. },
  461. change(e, index) {
  462. console.log(this.list_cD);
  463. let pl = e.detail.value;
  464. this.pre_value = [...this.value_default];
  465. if (this.disabled) {
  466. this.value_default = this.pre_value;
  467. return;
  468. }
  469. for (let i = 0; i < this.syheng_key.length; i++) {
  470. for (let j = 0; j < this.listIndex.length; j++) {
  471. if (this.listIndex[j][this.syheng_key[i]] == true) {
  472. this.$set(this.listIndex[j], 'itemIndex', pl[i]);
  473. }
  474. }
  475. }
  476. this.chulisdata();
  477. this.chulishijian();
  478. this.value_default = pl;
  479. },
  480. jswid() {
  481. let wd = this.gridNum - 1 - 2;
  482. if (wd <= 0) wd = 1;
  483. return 100 / wd;
  484. },
  485. scrllEnd(e) {
  486. function monthDay(year, month) {
  487. var date = new Date(year, month, 1, 0, 0, 0);
  488. var yesterDay = new Date(date - 1000);
  489. return yesterDay.getDate();
  490. }
  491. if (!this.scrollEvent) return;
  492. let dNum = this.gridNum;
  493. let d;
  494. let t = this;
  495. let idb = 88;
  496. let idc = 884;
  497. let srcllTop = this.scrollEvent.detail.scrollTop;
  498. if (srcllTop <= 0) {
  499. srcllTop = 0;
  500. } else if (srcllTop >= this.scrollEvent.detail.srcollHeigh) {
  501. srcllTop = this.scrollEvent.detail.srcollHeigh;
  502. }
  503. d = Math.ceil((srcllTop - this.itemHeight / 2) / this.itemHeight);
  504. if (d >= t.listData[t.childrenIndex].length - 1) {
  505. d = t.listData[t.childrenIndex].length - 1;
  506. }
  507. t.$set(t.listIndex[t.childrenIndex], 'wz', srcllTop);
  508. let old_index = this.listIndex[this.childrenIndex].itemIndex || 0;
  509. if (t.disabled) {
  510. clearTimeout(idb);
  511. idb = setTimeout(function() {
  512. t.$nextTick(function() {
  513. t.$set(t.listIndex[t.childrenIndex], 'wz', old_index * t.itemHeight);
  514. });
  515. }, 5);
  516. return;
  517. }
  518. this.$set(this.listIndex[t.childrenIndex], 'itemIndex', d);
  519. t.chulisdata();
  520. clearTimeout(idb);
  521. idb = setTimeout(function() {
  522. t.$nextTick(function() {
  523. t.$set(t.listIndex[t.childrenIndex], 'wz', d * t.itemHeight);
  524. for (let lsindex = t.childrenIndex + 1; lsindex < 6; lsindex++) {
  525. if (t.listData[lsindex][t.listIndex[lsindex].itemIndex] == undefined) {
  526. let pda = t.listData[lsindex].length - 1;
  527. if (d >= pda) {
  528. this.$set(this.listIndex[lsindex], 'itemIndex', pda);
  529. t.$set(t.listIndex[lsindex], 'wz', pda * t.itemHeight);
  530. } else {
  531. this.$set(this.listIndex[lsindex], 'itemIndex', 0);
  532. t.$set(t.listIndex[lsindex], 'wz', 0);
  533. }
  534. } else {
  535. let srcllTop_s = t.listIndex[lsindex].wz;
  536. const tsdd = t.listIndex[lsindex].itemIndex;
  537. t.$set(t.listIndex[lsindex], 'wz', tsdd * t.itemHeight - 1);
  538. this.$nextTick(function() {
  539. t.$set(t.listIndex[lsindex], 'wz', tsdd * t.itemHeight);
  540. });
  541. }
  542. }
  543. });
  544. }, 10);
  545. }
  546. }
  547. };
  548. </script>
  549. <style>
  550. .tm-pickersDateView .tm-pickersCView-item-h {
  551. height: 50px;
  552. background-color: rgba(0, 0, 0, 0.03);
  553. width: calc(100% - 10px);
  554. margin-left: 5px;
  555. border-radius: 20rpx;
  556. border: none;
  557. }
  558. .tm-pickersDateView .tm-pickersCView-item-h::after,
  559. .tm-pickersDateView .tm-pickersCView-item-h::before {
  560. border: none;
  561. }
  562. .tm-pickersDateView .tm-pickersCView-wk {
  563. position: relative;
  564. width: 750rpx;
  565. height: 500rpx;
  566. }
  567. .tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.bk {
  568. opacity: 0.4;
  569. }
  570. .tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.active {
  571. opacity: 1;
  572. border-radius: 20rpx;
  573. border: none;
  574. background-color: rgba(0, 0, 0, 0.06);
  575. }
  576. .tm-pickersDateView .tm-pickersCView-wk .tm-pickersCView-item.active.bk {
  577. background-color: rgba(255, 255, 255, 0.06);
  578. }
  579. </style>