t-datetime.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. <template>
  2. <view class="jnpf-dateTime">
  3. <u-input input-align='right' type="select" :select-open="selectShow" v-model="innerValue"
  4. :placeholder="placeholder" @click="openSelect" :disabled="disabled">
  5. </u-input>
  6. <u-popup v-model="selectShow" mode="bottom" @click="colse()">
  7. <view class="t-pop" @tap.stop>
  8. <view class="pop-main">
  9. <view class="top">
  10. <view class="top-l">
  11. <view @click="changeSwp('1')" :style="{color:sindex==1?'#1E79FF':'#333333'}">
  12. <text>{{checkyear}}</text>
  13. </view>
  14. <view @click="changeSwp('2')" :style="{color:sindex==2?'#1E79FF':'#333333'}"
  15. v-if="allDay==0">
  16. <text>{{checkhour}}:{{checkminute}}</text>
  17. </view>
  18. </view>
  19. <view class="top-r" @click="onOK()">
  20. <text>确定</text>
  21. </view>
  22. </view>
  23. <swiper class="swiper" circular :current-item-id="sindex">
  24. <swiper-item :item-id="'1'">
  25. <view class="mid">
  26. <scroll-view scroll-y="true" style="height: 960rpx" @scrolltolower="tolower">
  27. <uni-calendar ref="calendar" :insert="insert" :lunar='lunar'
  28. @change='calendarChange' :date='today' />
  29. </scroll-view>
  30. </view>
  31. </swiper-item>
  32. <swiper-item :item-id="'2'" v-if="allDay==0">
  33. <picker-view :indicator-style="indicatorStyle" :value="swiperTime" @change="bindChange"
  34. class="picker-view">
  35. <picker-view-column>
  36. <view class="item" v-for="(v,i) in 24" :key="i">{{i<10?'0'+i:i}}时</view>
  37. </picker-view-column>
  38. <picker-view-column>
  39. <view class="item" v-for="(v,i) in 12" :key="i">{{i<2?'0'+i*5:i*5}}分
  40. </view>
  41. </picker-view-column>
  42. </picker-view>
  43. </swiper-item>
  44. </swiper>
  45. </view>
  46. </view>
  47. </u-popup>
  48. </view>
  49. </template>
  50. <script>
  51. export default {
  52. name: "t-datetime",
  53. props: {
  54. type: {
  55. type: Number,
  56. default: 0 //默认时间后推0分钟
  57. },
  58. allDay: {
  59. type: Number,
  60. default: 0
  61. },
  62. modelValue: {
  63. type: String,
  64. default: ''
  65. },
  66. date: {
  67. type: Object,
  68. default: () => {}
  69. },
  70. placeholder: {
  71. type: String,
  72. default: '请选择'
  73. },
  74. delayMin: {
  75. type: Number,
  76. default: 0 //默认时间后推0分钟
  77. },
  78. disabled: {
  79. type: Boolean,
  80. default: false
  81. },
  82. canToday: { //是否可选择当天之前的时间
  83. type: Boolean,
  84. default: false
  85. },
  86. },
  87. data() {
  88. return {
  89. textList: ['日', '一', '二', '三', '四', '五', '六'],
  90. mList: [],
  91. checkyear: 0,
  92. checkmonth: 0,
  93. checkdate: 0,
  94. checkhour: 0,
  95. checkminute: 0,
  96. indicatorStyle: `height: 50px;`,
  97. sindex: '1',
  98. nowYear: 0,
  99. nowMonth: 0,
  100. nowDate: 0,
  101. lunar: false,
  102. insert: true,
  103. innerValue: '',
  104. selectShow: false,
  105. swiperTime: [],
  106. year: 0,
  107. hours: '',
  108. minutes: '',
  109. today: ''
  110. };
  111. },
  112. watch: {
  113. allDay(val) {
  114. let allTime = this.date.year + '-' + this.date.month + '-' + this.date.date
  115. this.today = allTime
  116. let srt = this.time(allTime)
  117. this.innerValue = ''
  118. if (srt) {
  119. this.innerValue = srt + this.date.month + '月' + this.date.date + '日'
  120. } else {
  121. if (this.date.year == this.year) {
  122. this.innerValue = this.date.month + '月' + this.date.date + '日'
  123. } else {
  124. this.innerValue = this.date.year + '年' + this.date.month + '月' + this.date.date + '日'
  125. }
  126. }
  127. if (this.allDay == 0) {
  128. this.innerValue = this.innerValue + ' ' + this.hours + ':' +
  129. this.minutes
  130. }
  131. },
  132. date(val) {
  133. this.init()
  134. },
  135. },
  136. created() {
  137. this.timestampToTime(+new Date())
  138. this.init()
  139. },
  140. methods: {
  141. tolower() {
  142. this.init()
  143. },
  144. openSelect() {
  145. if (this.disabled) return
  146. this.selectShow = true
  147. this.init()
  148. },
  149. calendarChange(e) {
  150. this.date.year = e.year
  151. this.date.month = e.month
  152. this.date.date = e.date
  153. this.date.date = this.date.date < 10 ? '0' + Number(this.date.date) : this.date.date
  154. this.date.month = this.date.month < 10 ? '0' + Number(this.date.month) : this.date.month
  155. this.checkyear = this.year == this.date.year ? this.date.month + '月' + this.date.date + '日' : this.date
  156. .year +
  157. '年' + this.date.month + '月' + this.date.date + '日'
  158. this.sindex = '2'
  159. },
  160. init() {
  161. this.innerValue = ''
  162. this.today = this.date.year + '-' + this.date.month + '-' + this.date.date
  163. this.date.minutes = this.date.minutes < 10 ? '0' + Number(this.date.minutes) : this.date.minutes
  164. this.date.hours = this.date.hours < 10 ? '0' + Number(this.date.hours) : this.date.hours
  165. this.date.date = this.date.date < 10 ? '0' + Number(this.date.date) : this.date.date
  166. this.date.month = this.date.month < 10 ? '0' + Number(this.date.month) : this.date.month
  167. this.checkyear = this.year == this.date.year ? this.date.month + '月' + this.date.date + '日' : this.date
  168. .year + '年' + this.date.month + '月' + this.date.date + '日'
  169. this.checkhour = this.date.hours
  170. this.checkminute = this.date.minutes < 10 ? '0' + Number(this.date.minutes) : this.date.minutes
  171. let checkminute = this.date.minutes / 5
  172. this.swiperTime = [Number(this.checkhour), checkminute]
  173. this.hours = this.date.hours
  174. this.minutes = this.date.minutes
  175. let allTime = this.date.year + '-' + this.date.month + '-' + this.date.date
  176. let srt = this.time(allTime)
  177. if (srt) {
  178. this.innerValue = srt + this.date.month + '月' + this.date.date + '日'
  179. } else {
  180. if (this.date.year == this.year) {
  181. this.innerValue = this.date.month + '月' + this.date.date + '日'
  182. } else {
  183. this.innerValue = this.date.year + '年' + this.date.month + '月' + this.date.date + '日'
  184. }
  185. }
  186. if (this.allDay == 0) {
  187. this.innerValue = this.innerValue + ' ' + this.hours + ':' +
  188. this.checkminute
  189. }
  190. },
  191. colse() {
  192. this.selectShow = false
  193. },
  194. bindChange(e) {
  195. const val = e.detail.value
  196. this.swiperTime = [val[0], val[1]]
  197. this.checkhour = Number(val[0]) < 10 ? '0' + val[0] : val[0]
  198. this.checkminute = val[1] == '天' ? '00' : val[1] < 2 ? '0' + val[1] * 5 : val[1] * 5
  199. },
  200. changeSwp(i) {
  201. this.sindex = i
  202. },
  203. onOK() {
  204. if (this.allDay == 1) {
  205. this.date.hours = '00'
  206. this.date.minutes = '00'
  207. } else {
  208. this.date.hours = this.checkhour
  209. this.date.minutes = this.checkminute
  210. }
  211. this.selectShow = false
  212. let allTime = this.date.year + '-' + this.date.month + '-' + this.date.date
  213. let srt = this.time(allTime)
  214. if (srt) {
  215. this.innerValue = srt + this.date.month + '月' + this.date.date + '日'
  216. if (this.allDay == 0) {
  217. this.innerValue = this.innerValue + ' ' + this.date.hours +
  218. ':' + this.date.minutes
  219. }
  220. } else {
  221. if (this.date.year == this.year) {
  222. this.innerValue = this.date.month + '月' + this.date.date + '日'
  223. } else {
  224. this.innerValue = this.date.year + '年' + this.date.month + '月' + this.date.date + '日'
  225. }
  226. if (this.allDay == 0) {
  227. this.innerValue = this.innerValue + ' ' + this.date.hours +
  228. ':' + this.date.minutes
  229. }
  230. }
  231. this.selectShow = false
  232. this.$emit('confirm', this.date, this.type)
  233. },
  234. timestampToTime(timestamp) {
  235. var date = new Date(timestamp);
  236. this.year = date.getFullYear();
  237. },
  238. time(date) {
  239. if (this.date.year != this.year) return false
  240. let time_str = "";
  241. if (new Date(date).getDate() === new Date().getDate()) {
  242. time_str = "今天 · ";
  243. } else if (new Date(date).getDate() === (new Date().getDate() - 1)) {
  244. time_str = "昨天 · ";
  245. } else if (new Date(date).getDate() === (new Date().getDate() + 1)) {
  246. time_str = "明天 · ";
  247. } else if (new Date(date).getDate() < new Date().getDate()) {
  248. time_str = "";
  249. }
  250. return time_str;
  251. }
  252. }
  253. }
  254. </script>
  255. <style lang="scss" scoped>
  256. .jnpf-dateTime {
  257. width: 100%;
  258. :deep(.u-drawer) {
  259. z-index: 999 !important;
  260. }
  261. }
  262. :deep(.uni-calendar-item__weeks-box-item) {
  263. line-height: 36rpx;
  264. }
  265. .t-pop {
  266. width: 100%;
  267. display: flex;
  268. justify-content: center;
  269. align-items: center;
  270. .pop-main {
  271. display: flex;
  272. flex-direction: column;
  273. justify-content: space-between;
  274. align-items: center;
  275. background-color: #fff;
  276. border-radius: 24px;
  277. height: 900rpx;
  278. width: 100%;
  279. }
  280. }
  281. .swiper {
  282. height: 840rpx;
  283. width: 100vw;
  284. }
  285. .top {
  286. display: flex;
  287. flex-direction: row;
  288. justify-content: space-between;
  289. align-items: center;
  290. width: 100%;
  291. margin: 20rpx 0;
  292. .top-l {
  293. display: flex;
  294. flex-direction: row;
  295. margin-left: 30rpx;
  296. }
  297. .top-r {
  298. margin-right: 30rpx;
  299. color: #1E79FF;
  300. }
  301. }
  302. .calendar {
  303. display: flex;
  304. flex-wrap: wrap;
  305. flex-direction: row;
  306. align-items: center;
  307. width: 100vw;
  308. position: relative;
  309. }
  310. .ca-top {
  311. width: 14.2vw;
  312. display: flex;
  313. justify-content: center;
  314. align-items: center;
  315. height: 66rpx;
  316. z-index: 10;
  317. }
  318. .cell {
  319. width: 60rpx;
  320. height: 60rpx;
  321. display: flex;
  322. justify-content: center;
  323. align-items: center;
  324. align-content: center;
  325. border-radius: 30rpx;
  326. }
  327. .cell-active {
  328. background-color: #1E79FF;
  329. color: #fff;
  330. }
  331. .cabg {
  332. display: flex;
  333. justify-content: center;
  334. width: 100vw;
  335. font-size: 180rpx;
  336. color: beige;
  337. position: absolute;
  338. z-index: 9;
  339. }
  340. .picker-view {
  341. width: 750rpx;
  342. height: 600rpx;
  343. margin-top: 20rpx;
  344. }
  345. .item {
  346. height: 50px;
  347. display: flex;
  348. align-items: center;
  349. justify-content: center;
  350. text-align: center;
  351. }
  352. </style>