tm-calendarView.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. <template>
  2. <view class="tm-calendarView">
  3. <view class="tm-calendarView-wk">
  4. <view class="shadow-10">
  5. <view class="tm-calendarView-title pa-32 pb-16">
  6. <view class="text-size-g text-align-center">{{title}}</view>
  7. </view>
  8. <view class="flex-center pa-32 " style="width: 70%;margin: auto;">
  9. <view>
  10. <tm-icons dense @click="preYear" name="icon-angle-double-left" color="grey-lighten-1"></tm-icons>
  11. <text class="px-24"></text>
  12. <tm-icons dense @click="preMonth" name="icon-angle-left" color="grey-lighten-1"></tm-icons>
  13. </view>
  14. <view class="text-size-n text-weight-b px-40">{{titleValue}}</view>
  15. <view>
  16. <tm-icons dense @click="nextMonth" name="icon-angle-right" color="grey-lighten-1"></tm-icons>
  17. <text class="px-24"></text>
  18. <tm-icons dense @click="nextYear" name="icon-angle-double-right" color="grey-lighten-1"></tm-icons>
  19. </view>
  20. </view>
  21. </view>
  22. </view>
  23. <view class="tm-calendarView-body">
  24. <view class="tm-calendarView-bg flex-center">
  25. <text class="text" :class="[black?' opacity-5 ':'']">{{centerValue}}</text>
  26. </view>
  27. <view class="tm-calendarView-content">
  28. <view style="height: 32upx;"></view>
  29. <tm-row>
  30. <!-- #ifdef H5 || APP-VUE || APP-PLUS -->
  31. <tm-col color="" align="center" width="14.28%" v-for="(item,index) in ['一','二','三','四','五','六','日']"
  32. :key="index+'_a'"><text class="text-size-s py-16">{{item}}</text>
  33. </tm-col>
  34. <!-- #endif -->
  35. <!-- #ifdef MP-->
  36. <tm-col color="" align="center" width="14.28%" v-for="(item,index) in ['一','二','三','四','五','六','日']"
  37. :key="index"><text class="text-size-s py-16">{{item}}</text>
  38. </tm-col>
  39. <!-- #endif -->
  40. <tm-col
  41. @click="day_danxuanclick(item,index)"
  42. color=""
  43. :custom-class="isSelectedDateClass(item)"
  44. justify="center" width="14.28%"
  45. v-for="(item,index) in nowData"
  46. :key="index"
  47. >
  48. <view class="tm-calendar-col flex-center flex-col "
  49. :style="[mode=='rang'?{width:'100%',height:'90rpx'}:{width:'90rpx',height:'90rpx',overflow: 'hidden','border-radius': '50% !important'}]"
  50. :class="[
  51. item.start?'round-l-24':'',
  52. item.end?'round-r-24':'',
  53. item.beginEnd?(item.checked===true||item.start||item.end?color_tmeme+(black_tmeme?' bk ':''):(item.guocheng?color_tmeme+' text opacity-7 '+(black_tmeme?'bk':''):'')):'',
  54. black_tmeme&&!item.beginEnd?' opacity-2 ':'']">
  55. <text class="text-size-n"
  56. :class="[
  57. !item.nowMonth&&!item.guocheng&&!item.checked&&!item.start&&!item.end?(black_tmeme?'text-grey-darken-3':'text-grey-lighten-1'):'',
  58. item.checked||item.start||item.end?'text-white':'',
  59. item.guocheng?' text text-'+color_tmeme:'',
  60. !item.beginEnd?'text-grey-lighten-3':''
  61. ]"
  62. >{{item.day}}</text>
  63. <view class="text-size-xs text_bl"
  64. >
  65. <block v-if="item.start">
  66. </block>
  67. <block v-if="item.end">
  68. -止
  69. </block>
  70. <block v-if="!item.start&&!item.end">
  71. {{item.text?item.text:(showNongli?item.nongli.day:'')}}
  72. </block>
  73. </view>
  74. </view>
  75. </tm-col>
  76. </tm-row>
  77. </view>
  78. <view class="" style="height: 40rpx;"></view>
  79. <view v-if="showConfirm">
  80. <view class="text-align-center px-32 text-grey ">{{selectedVal}}</view>
  81. <view class="pa-32">
  82. <tm-button @click="confirm" block itemeClass="round-24" :theme="btnColor?btnColor:color_tmeme" fontSize="32">{{btnText}}</tm-button>
  83. </view>
  84. </view>
  85. </view>
  86. </view>
  87. </template>
  88. <script>
  89. /**
  90. * 日历,这是一个内嵌版,可以直接嵌入页面显示,属性基本等同:tm-calendar
  91. * @description 日历组件,提供节气、农历公历显示,时间范围选择等功能。
  92. * @property {String} mode = [day|rang] 默认:day单选日期,rang范围选择日期。
  93. * @property {Function} confirm = [] 当选择日期确认后触发,如果未选择确认后不会触发事件。
  94. * @property {String} title = [] 弹层层标题
  95. * @property {String} btn-text = [] 底部按钮确认的文字
  96. * @property {String} btn-color = [primary|green|orange|red|blue|bg-gradient-blue-lighten] 默认:bg-gradient-blue-lighten底部按钮确认的背景颜色仅支持主题色名称
  97. * @property {String} color = [primary|green|orange|red|blue] 主题默认:primary,提供是请写主题色名称
  98. * @property {String} default-value = [] 默认时间默认:当前时间,格式:'2021-7-21'
  99. * @property {String} bing-end = [] 时间格式:'2021-7-21',当mode=rang时有效
  100. * @property {String} bing-start = [] 时间格式:'2021-7-21',当mode=rang时有效
  101. * @property {Boolean|String} disabled = [true|false] 是否禁用,只读,默认false
  102. * @property {Function} confirm = [] 按钮点击确认时会发送当前选中的数据。如果数据为空,则不触发。
  103. * @property {String} time-start = [] 日历时间可选范围开始日期格式'2021-7-21'
  104. * @property {String} time-end = [] 日历时间可选范围结束日期格式'2021-7-21'
  105. * @property {Array<object>} txt = [] 设置日期下标文本;格式[{date:'2021-7-21',text:"测试"}]
  106. * @property {Array<object>} selected-date-class = [] 设置指定日期的样式,格式[{date:'2021-7-21',class:"类名"}]
  107. * @property {Boolean|String} black = [true|false] 是否开启暗黑模式
  108. * @property {Boolean} show-nongli = [true|false] 是否显示农历
  109. * @property {Boolean} show-confirm = [true|false] true,是否显示底部按钮和详细信息。
  110. * @property {Array} formart = [] 默认['年','月','日'],时间的分割符。
  111. * @example <tm-calendarView :txt="bbc" ref='calendar' mode="rang" time-start="2021-7-1" time-end="2021-7-31" @confirm="next" v-model="tts" ></tm-calendarView>
  112. */
  113. import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
  114. import tmCol from "@/tm-vuetify/components/tm-col/tm-col.vue"
  115. import tmRow from "@/tm-vuetify/components/tm-row/tm-row.vue"
  116. import tmButton from "@/tm-vuetify/components/tm-button/tm-button.vue"
  117. export default {
  118. components:{tmIcons,tmCol,tmRow,tmButton},
  119. name: "tm-calendarView",
  120. props:{
  121. black:{
  122. type:Boolean|String,
  123. default:false
  124. },
  125. disabled:{
  126. type:Boolean|String,
  127. default:false
  128. },
  129. // 默认时间。
  130. defaultValue:{
  131. type:String,
  132. default:''
  133. },
  134. mode:{
  135. type:String,
  136. default:'day'
  137. },
  138. bingStart:{
  139. type:String,
  140. default:null
  141. },
  142. timeStart:{
  143. type:String,
  144. default:null
  145. },
  146. timeEnd:{
  147. type:String,
  148. default:null
  149. },
  150. bingEnd:{
  151. type:String,
  152. default:null
  153. },
  154. // 顶部标题。
  155. title:{
  156. type:String,
  157. default:'选择时间'
  158. },
  159. // 底部按钮文件
  160. btnText:{
  161. type:String,
  162. default:'确认'
  163. },
  164. // 底部按钮背景主题色名称
  165. btnColor:{
  166. type:String,
  167. default:''
  168. },
  169. // 主题色。
  170. color:{
  171. type:String,
  172. default:'primary'
  173. },
  174. // 主题色。
  175. txt:{
  176. type:Array,
  177. default:()=>{ return []}
  178. },
  179. // 指定日期的样式类格式同txt
  180. selectedDateClass:{
  181. type:Array,
  182. default:()=>{ return []}
  183. },
  184. // 是否显示家历
  185. showNongli:{
  186. type:Boolean,
  187. default:false
  188. },
  189. showConfirm:{
  190. type:Boolean,
  191. default:true
  192. },
  193. // 跟随主题色的改变而改变。
  194. fllowTheme:{
  195. type:Boolean|String,
  196. default:true
  197. },
  198. formart:{
  199. type:Array,
  200. default:()=>{
  201. return ['年','月','日'];
  202. }
  203. }
  204. },
  205. watch:{
  206. bingStart:function(){
  207. this.watchRangeTime();
  208. },
  209. bingEnd:function(){
  210. this.watchRangeTime();
  211. },
  212. txt:function(val){
  213. if(this.cal){
  214. this.cal.setTimeArrayText(this.txt);
  215. }
  216. },
  217. defaultValue:function(val){
  218. // 自动更新默认的显示时间。
  219. if(this.mode=='day'){
  220. let d = new Date().toLocaleDateString().replace(/\//g,'-');
  221. if(this.defaultValue){
  222. d = this.defaultValue;
  223. }
  224. this.cal.setValue(d)
  225. let index = this.findItemToindexByDate(this.cal.now_day_month)
  226. if(index>-1){
  227. this.nowData = this.cal.getData();
  228. let item = this.nowData[index];
  229. item.checked = true;
  230. this.selectedDay = item;
  231. this.fanxuanDate();
  232. }
  233. }
  234. }
  235. },
  236. data() {
  237. return {
  238. showCarlader: false,
  239. nowData:[],//当前月份数据。
  240. cal:null,//日历对象数据。
  241. selectedDay:null,
  242. start:null,
  243. end:null,
  244. fanwei:[]
  245. };
  246. },
  247. computed:{
  248. black_tmeme: function() {
  249. if (this.black !== null) return this.black;
  250. return this.$tm.vx.state().tmVuetify.black;
  251. },
  252. color_tmeme:function(){
  253. if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
  254. return this.$tm.vx.state().tmVuetify.color;
  255. }
  256. return this.color;
  257. },
  258. show:{
  259. get:function(){
  260. return this.showCarlader;
  261. },set:function(val){
  262. this.showCarlader = val
  263. }
  264. },
  265. titleValue:function(){
  266. if(! this.cal) return ''
  267. return this.cal.value.getFullYear()+(this.formart[0]??'年')+(this.cal.value.getMonth()+1)+(this.formart[1]??'月');
  268. },
  269. centerValue:function(){
  270. if(! this.cal) return ''
  271. return this.cal.value.getMonth()+1;
  272. },
  273. selectedVal:function(){
  274. if(this.mode=='day'&&this.selectedDay){
  275. return this.selectedDay.year+(this.formart[0]??'年')+this.selectedDay.month+(this.formart[1]??'月')+this.selectedDay.day+(this.formart[2]??'日');
  276. }
  277. if(this.mode=='rang'&&this.start&&!this.end){
  278. let p = this.start.year+(this.formart[0]??'年')+this.start.month+(this.formart[1]??'月')+this.start.day+(this.formart[2]??'日');
  279. let et = '' ;
  280. return p + " ~ " + et;
  281. }
  282. if(this.mode=='rang'&&this.start&&this.end){
  283. let p = this.start.year+(this.formart[0]??'年')+this.start.month+(this.formart[1]??'月')+this.start.day+(this.formart[2]??'日');
  284. let p2 = this.end.year+(this.formart[0]??'年')+this.end.month+(this.formart[1]??'月')+this.end.day+(this.formart[2]??'日');
  285. return p + " ~ " +p2;
  286. }
  287. }
  288. },
  289. mounted() {
  290. this.watchRangeTime();
  291. },
  292. methods: {
  293. watchRangeTime(){
  294. let d = new Date().toLocaleDateString().replace(/\//g,'-');
  295. if(this.defaultValue){
  296. d = this.defaultValue;
  297. }
  298. this.cal = new this.$tm.calendar({value:d,start:this.timeStart,end:this.timeEnd})
  299. if(this.txt){
  300. this.cal.setTimeArrayText(this.txt);
  301. }
  302. this.nowData = this.cal.getData();
  303. if(this.mode=='day'){
  304. let index = this.findItemToindexByDate(this.cal.now_day_month)
  305. if(index>-1){
  306. let item = this.nowData[index];
  307. item.checked = true;
  308. this.selectedDay = item;
  309. this.fanxuanDate();
  310. }
  311. // 反选选区。
  312. }else if(this.mode=='rang'){
  313. if(this.bingStart&&this.bingEnd){
  314. this.fanxuanxuanwuBydate(
  315. new Date(this.bingStart.replace(/-/g,'/')),
  316. new Date(this.bingEnd.replace(/-/g,'/')),
  317. )
  318. }
  319. }
  320. },
  321. isSelectedDateClass(date){
  322. let rangeL = 'round-l-24 round-tr-0 round-br-0'
  323. let rangeR = 'round-r-24 round-tl-0 round-bl-0'
  324. let index = this.selectedDateClass.findIndex((item)=>{
  325. let val = date.year+'-'+date.month+'-'+date.day;
  326. return val == item.date;
  327. })
  328. let pc = '';
  329. if(date.start&&!date.end){
  330. pc = ` ${rangeL} `;
  331. }else if(date.end&&!date.start){
  332. pc = ` ${rangeR} `;
  333. }else if(date.start&&date.end){
  334. pc = ` `
  335. }
  336. if(index >-1){
  337. return this.selectedDateClass[index].class + pc
  338. }
  339. return pc;
  340. },
  341. // 获取当前月份的数据。
  342. getNowMonthData(){
  343. return this.cal.getData();
  344. },
  345. // 设置时间文本数据。
  346. setNowMonthData(e){
  347. if(!Array.isArray(e)) return;
  348. this.cal.setTimeArrayText(e);
  349. this.nowData = this.cal.getData();
  350. let index = this.findItemToindexByDate(this.cal.now_day_month)
  351. if(index>-1){
  352. let item = this.nowData[index];
  353. item.checked = true;
  354. this.selectedDay = item;
  355. }
  356. this.fanxuanDate()
  357. },
  358. confirm(){
  359. if(this.mode=='day'){
  360. if(this.selectedDay){
  361. this.$emit('confirm',this.selectedDay);
  362. this.$emit('update:defaultValue',this.selectedDay.year+'-'+this.selectedDay.month+'-'+this.selectedDay.day)
  363. }
  364. }else if(this.mode=='rang'){
  365. if(this.start&&this.end){
  366. let bts = this.start.year+'-'+this.start.month+'-'+this.start.day;
  367. this.$emit('update:bingStart',bts)
  368. this.$emit('update:defaultValue',bts)
  369. let ets = this.end.year+'-'+this.end.month+'-'+this.end.day;
  370. this.$emit('update:bingEnd',ets)
  371. this.$emit('confirm',[this.start,this.end]);
  372. // this.fanwei
  373. }
  374. }
  375. return null;
  376. },
  377. preMonth(){
  378. if(!this.cal) return;
  379. this.nowData = this.cal.prevMonth().getData();
  380. this.$nextTick(function(){
  381. this.fanxuanDate();
  382. })
  383. },
  384. nextMonth(){
  385. if(!this.cal) return;
  386. this.nowData = this.cal.nextMonth().getData();
  387. this.$nextTick(function(){
  388. this.fanxuanDate();
  389. })
  390. },
  391. preYear(){
  392. if(!this.cal) return;
  393. this.nowData = this.cal.prevYear().getData();
  394. this.$nextTick(function(){
  395. this.fanxuanDate();
  396. })
  397. },
  398. nextYear(){
  399. if(!this.cal) return;
  400. this.nowData = this.cal.nexYear().getData();
  401. this.$nextTick(function(){
  402. this.fanxuanDate();
  403. })
  404. },
  405. fanxuanDate(){
  406. if(this.mode=='day'){
  407. if(this.selectedDay){
  408. let index = this.findItemToindex(this.selectedDay);
  409. if(index>-1){
  410. this.nowData.splice(index,1,this.selectedDay);
  411. }
  412. }
  413. }else if(this.mode=='rang'){
  414. if(this.start&&!this.end){
  415. let index = this.findItemToindex(this.start);
  416. if(index>-1){
  417. this.nowData.splice(index,1,this.start);
  418. }
  419. return;
  420. }
  421. if(this.start&&this.end){
  422. let index = this.findItemToindex(this.start);
  423. if(index>-1){
  424. this.nowData.splice(index,1,this.start);
  425. }
  426. index = this.findItemToindex(this.end);
  427. if(index>-1){
  428. this.nowData.splice(index,1,this.end);
  429. }
  430. for(let i=0;i<this.fanwei.length;i++){
  431. let idx = this.fanwei[i];
  432. index = this.findItemToindex(idx);
  433. if(index>-1){
  434. this.nowData.splice(index,1,idx);
  435. }
  436. }
  437. return;
  438. }
  439. }
  440. },
  441. isSelected:function(item){
  442. let index = this.selectedDay.indexOf(idx=>{
  443. return idx.year===item.year&&idx.month===item.month&&idx.day===item.day;
  444. })
  445. if(index===-1) return false;
  446. return true;
  447. },
  448. // 查找选中的
  449. findChecked(){
  450. let xz = [];
  451. this.nowData.forEach((item,index)=>{
  452. if(item.checked===true){
  453. xz.push({
  454. item:item,
  455. index:index
  456. })
  457. }
  458. })
  459. return xz;
  460. },
  461. // 查找index
  462. findItemToindex(item){
  463. let index=-1;
  464. for(let i=0;i<this.nowData.length;i++){
  465. let idx = this.nowData[i];
  466. if(idx.year==item.year&&idx.month==item.month&&idx.day==item.day){
  467. index=i;
  468. break;
  469. }
  470. }
  471. return index;
  472. },
  473. // 根据时间选取查找。
  474. findItemToindexByDate(date){
  475. let index=-1;
  476. for(let i=0;i<this.nowData.length;i++){
  477. let idx = this.nowData[i];
  478. if(idx.year==date.getFullYear()&&idx.month==(date.getMonth()+1)&&idx.day==date.getDate()){
  479. index=i;
  480. break;
  481. }
  482. }
  483. return index;
  484. },
  485. // 清除当前日历中选中的部分。
  486. clearCheckedNowDay(){
  487. let xz = [];
  488. this.nowData.forEach((item,index)=>{
  489. item.checked = false;
  490. xz.push(item);
  491. })
  492. this.nowData = xz;
  493. },
  494. // 清除选区的内容。
  495. clearRangeNowDay(){
  496. let xz = [];
  497. let dqdata = this.cal.value;
  498. for(let i=0;i<this.nowData.length;i++){
  499. let item = this.nowData[i];
  500. let index = i;
  501. item.start = false;
  502. item.end = false;
  503. item.guocheng = false;
  504. item.checked = false;
  505. if(item.year==dqdata.getFullYear()&&item.month==dqdata.getMonth()+1){
  506. item.nowMonth =true;
  507. }else{
  508. item.nowMonth =false;
  509. }
  510. xz.push(item);
  511. }
  512. this.nowData = xz;
  513. },
  514. // 通过外围 时间默认的选中
  515. fanxuanxuanwuBydate(start,end){
  516. if(!start||!end) return;
  517. this.$nextTick(function(){
  518. if(start.getTime()>end.getTime()) return;
  519. // 获取开始月份的数据。
  520. let sobj = new this.$tm.calendar({value:start.toLocaleDateString().replace(/\//g,'-')});
  521. // 获取结束月份的数据。
  522. let eobj = new this.$tm.calendar({value:end.toLocaleDateString().replace(/\//g,'-')});
  523. function findItemToindex_only(obj,type){
  524. let item=null;
  525. for(let i=0;i<obj.length;i++){
  526. let idx = obj[i];
  527. if(idx.nowDay==true){
  528. item = idx;
  529. break;
  530. }
  531. }
  532. if(type == 'start'&&item){
  533. item.start=true;
  534. item.end=false;
  535. item.checked=false;
  536. item.guocheng=false;
  537. }else if(type == 'end'&&item){
  538. item.start=false;
  539. item.end=true;
  540. item.checked=false;
  541. item.guocheng=false;
  542. }
  543. return item;
  544. }
  545. let sodata = sobj.getData();
  546. let eodata = eobj.getData();
  547. let start_obj = null;
  548. let end_obj = null;
  549. start_obj = findItemToindex_only(sodata,'start')
  550. let s_index = this.findItemToindex(start_obj)
  551. if(s_index>-1){
  552. this.nowData.splice(s_index,1,start_obj)
  553. }
  554. end_obj = findItemToindex_only(eodata,'end')
  555. let e_index = this.findItemToindex(end_obj)
  556. if(e_index>-1){
  557. this.nowData.splice(e_index,1,end_obj)
  558. }
  559. this.start = start_obj
  560. this.end = end_obj
  561. // 如果结束和开始相等。
  562. if(start.getTime()==end.getTime()){
  563. this.start = {...this.start,start:true,end:true}
  564. this.end = {...this.end,start:true,end:true}
  565. }
  566. // 计算包含的时间 区域。
  567. let start_time = new Date(this.start.year+"/"+this.start.month+"/"+this.start.day).getTime()
  568. let start_bdm = new Date(this.start.year+"/"+this.start.month).getTime()
  569. let end_time = new Date(this.end.year+"/"+this.end.month+"/"+this.end.day).getTime()
  570. let end_bdm = new Date(this.end.year+"/"+this.end.month).getTime()
  571. this.fanwei=[];
  572. let m=[];
  573. let testc = new this.$tm.calendar({value:this.start.year+"/"+this.start.month+"/"+this.start.day})
  574. testc.setTimeArrayText(this.txt);
  575. function findItemToindex_only_nob(item,obj){
  576. let istrue = false;
  577. for(let i=0;i<obj.length;i++){
  578. let idx = obj[i];
  579. if(item.year==idx.year&&item.month==idx.month&&item.day==idx.day){
  580. istrue = true;
  581. break;
  582. }
  583. }
  584. return istrue;
  585. }
  586. for(let j=0;j<1000;j++){
  587. let pds = new Date(testc.value.getFullYear()+"/"+(testc.value.getMonth()+1)).getTime();
  588. let testod = testc.getData();
  589. if(pds<=end_bdm&&pds>=start_bdm){
  590. for(let k=0;k<testod.length;k++){
  591. if(!findItemToindex_only_nob(testod[k],m)){
  592. m.push(testod[k]);
  593. }
  594. }
  595. testc.nextMonth()
  596. }else{
  597. break;
  598. }
  599. }
  600. for(let i=0;i<m.length;i++){
  601. let dod = {...m[i]};
  602. let npds = new Date(dod.year+"/"+(dod.month)+"/"+dod.day);
  603. let dq = npds.getTime()
  604. if(dq > start_time && dq < end_time){
  605. dod.start=false;
  606. dod.end=false;
  607. dod.checked=false;
  608. dod.guocheng=true;
  609. let isindex =this.findItemToindex(dod);
  610. if(isindex>-1){
  611. this.nowData.splice(isindex,1,dod);
  612. }
  613. this.fanwei.push(dod)
  614. }
  615. }
  616. // 开始反选。
  617. this.fanxuanDate();
  618. })
  619. },
  620. day_danxuanclick(e,index) {
  621. // 是否禁用。
  622. if(this.disabled||this.disabled=='true'){
  623. this.$tm.toast("已被禁用")
  624. return;
  625. }
  626. if(!e.beginEnd){
  627. this.$tm.toast("不可选!")
  628. return;
  629. };
  630. if(this.mode=='day'){
  631. this.clearCheckedNowDay();
  632. let p = {...e};
  633. p.checked = true;
  634. this.selectedDay = p;
  635. this.nowData.splice(index,1,p);
  636. }else{
  637. let p = {...e};
  638. if(!this.start&&!this.end){
  639. this.clearRangeNowDay();
  640. p.start = true;
  641. p.end = false;
  642. p.guocheng = false;
  643. this.start = p
  644. this.nowData.splice(index,1,p);
  645. //发布选中开始的事件。
  646. this.$emit("rang-start",{start:p,end:null})
  647. return;
  648. }
  649. if(this.start&&this.end){
  650. this.clearRangeNowDay();
  651. p.start = true;
  652. p.end = false;
  653. p.guocheng = false;
  654. this.start = p
  655. this.nowData.splice(index,1,p);
  656. this.end=null;
  657. //发布选中开始的事件。
  658. this.$emit("rang-start",{start:p,end:null})
  659. return;
  660. }
  661. if(this.start&&!this.end){
  662. this.$nextTick(function(){
  663. let selected = new Date(e.year+"/"+e.month+"/"+e.day).getTime();
  664. let selectedStart = new Date(this.start.year+"/"+this.start.month+"/"+this.start.day).getTime()
  665. if(selected <= selectedStart)
  666. {
  667. // this.clearRangeNowDay();
  668. let enjh = uni.$tm.deepClone(this.start);
  669. enjh.start = selected<selectedStart?false:true;
  670. enjh.end = true;
  671. enjh.guocheng = false;
  672. this.end = enjh
  673. let index_check =-1;
  674. for(let ix =0 ; ix <this.nowData.length;ix++){
  675. let item_check = this.nowData[ix]
  676. if( item_check.month==enjh.month&&item_check.year==enjh.year&&item_check.day==enjh.day){
  677. index_check=ix;
  678. break;
  679. }
  680. }
  681. if(index_check>-1){
  682. this.nowData.splice(index_check,1,this.end);
  683. }
  684. p.start = true;
  685. p.end = selected<selectedStart?false:true;
  686. p.guocheng = false;
  687. this.start = p
  688. }else if(selected > selectedStart)
  689. {
  690. p.start = false;
  691. p.end = true;
  692. p.guocheng = false;
  693. this.end = p
  694. }
  695. this.nowData.splice(index,1,p);
  696. //发布选中开始的事件。
  697. this.$emit("rang-start",{start:p,end:this.end})
  698. //发布选中开始的事件。
  699. this.$emit("rang-end",{start:this.start,end:this.end})
  700. // 计算包含的时间 区域。
  701. let start_time = new Date(this.start.year+"/"+this.start.month+"/"+this.start.day).getTime()
  702. let start_bdm = new Date(this.start.year,this.start.month-1).getTime()
  703. let end_time = new Date(this.end.year+"/"+this.end.month+"/"+this.end.day).getTime()
  704. let end_bdm = new Date(this.end.year,this.end.month-1).getTime()
  705. this.fanwei=[];
  706. let m=[];
  707. let testc = new this.$tm.calendar({value:this.start.year+"-"+this.start.month+"-"+this.start.day})
  708. testc.setTimeArrayText(this.txt);
  709. function findItemToindex_only(item,obj){
  710. let istrue = false;
  711. for(let i=0;i<obj.length;i++){
  712. let idx = obj[i];
  713. if(item.year==idx.year&&item.month==idx.month&&item.day==idx.day){
  714. istrue = true;
  715. break;
  716. }
  717. }
  718. return istrue;
  719. }
  720. for(let j=0;j<1000;j++){
  721. let npsDate = new Date(testc.value.getFullYear(),testc.value.getMonth());
  722. let pds = npsDate.getTime();
  723. let testod = testc.getData();
  724. if(pds<=end_bdm&&pds>=start_bdm){
  725. for(let k=0;k<testod.length;k++){
  726. if(!findItemToindex_only(testod[k],m)){
  727. m.push(testod[k]);
  728. }
  729. }
  730. testc.nextMonth()
  731. }else{
  732. break;
  733. }
  734. }
  735. for(let i=0;i<m.length;i++){
  736. let dod = {...m[i]};
  737. let npds = new Date(dod.year+"/"+(dod.month)+"/"+dod.day);
  738. let dq = npds.getTime()
  739. if(dq > start_time && dq < end_time){
  740. dod.start=false;
  741. dod.end=false;
  742. dod.checked=false;
  743. dod.guocheng=true;
  744. let isindex =this.findItemToindex(dod);
  745. if(isindex>-1){
  746. this.nowData.splice(isindex,1,dod);
  747. }
  748. this.fanwei.push(dod)
  749. }
  750. }
  751. })
  752. }
  753. }
  754. }
  755. },
  756. }
  757. </script>
  758. <style lang="scss" scoped>
  759. .tm-calendarView-col{
  760. width: 100%;
  761. height: 80upx;
  762. // text-align: center;
  763. // line-height: 80upx;
  764. line-height: inherit;
  765. position: relative;
  766. .text_bl{
  767. // position: absolute;
  768. bottom: 14upx;
  769. }
  770. }
  771. .textOn{
  772. color:#1976d2 !important;
  773. }
  774. .tm-calendarView-wk {
  775. width: 100%;
  776. .tm-calendarView-title {
  777. position: relative;
  778. .tm-calendarView-close {
  779. position: absolute;
  780. top: 32upx;
  781. right: 32upx;
  782. }
  783. }
  784. }
  785. .tm-calendarView-body {
  786. position: relative;
  787. .tm-calendarView-bg {
  788. height: 570rpx;
  789. .text {
  790. font-size: 400upx;
  791. color: rgba(225, 225, 225, 0.4);
  792. }
  793. }
  794. .tm-calendarView-content {
  795. width: 100%;
  796. position: absolute;
  797. top: 0;
  798. left: 0;
  799. }
  800. }
  801. </style>