u-datetime-picker.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. "use strict";
  2. const common_vendor = require("../../../../common/vendor.js");
  3. function times(n, iteratee) {
  4. let index = -1;
  5. const result = Array(n < 0 ? 0 : n);
  6. while (++index < n) {
  7. result[index] = iteratee(index);
  8. }
  9. return result;
  10. }
  11. const _sfc_main = {
  12. name: "datetime-picker",
  13. mixins: [common_vendor.mpMixin, common_vendor.mixin, common_vendor.props$22],
  14. data() {
  15. return {
  16. columns: [],
  17. innerDefaultIndex: [],
  18. innerFormatter: (type, value) => value
  19. };
  20. },
  21. watch: {
  22. show(newValue, oldValue) {
  23. if (newValue) {
  24. this.updateColumnValue(this.innerValue);
  25. this.init();
  26. }
  27. },
  28. propsChange() {
  29. this.init();
  30. }
  31. },
  32. computed: {
  33. // 如果以下这些变量发生了变化,意味着需要重新初始化各列的值
  34. propsChange() {
  35. return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute, this.filter];
  36. }
  37. },
  38. mounted() {
  39. this.init();
  40. },
  41. emits: ["close", "cancel", "confirm", "change", "update:modelValue"],
  42. methods: {
  43. init() {
  44. console.log("初始化开始");
  45. this.innerValue = this.correctValue(this.modelValue);
  46. this.updateColumnValue(this.innerValue);
  47. },
  48. // 在微信小程序中,不支持将函数当做props参数,故只能通过ref形式调用
  49. setFormatter(e) {
  50. this.innerFormatter = e;
  51. },
  52. // 关闭选择器
  53. close() {
  54. if (this.closeOnClickOverlay) {
  55. this.$emit("close");
  56. }
  57. },
  58. // 点击工具栏的取消按钮
  59. cancel() {
  60. this.$emit("cancel");
  61. },
  62. // 点击工具栏的确定按钮
  63. confirm() {
  64. this.$emit("confirm", {
  65. value: this.innerValue,
  66. mode: this.mode
  67. });
  68. this.$emit("update:modelValue", this.innerValue);
  69. },
  70. //用正则截取输出值,当出现多组数字时,抛出错误
  71. intercept(e, type) {
  72. let judge = e.match(/\d+/g);
  73. if (judge.length > 1) {
  74. common_vendor.index.$u.error("请勿在过滤或格式化函数时添加数字");
  75. return 0;
  76. } else if (type && judge[0].length == 4) {
  77. return judge[0];
  78. } else if (judge[0].length > 2) {
  79. common_vendor.index.$u.error("请勿在过滤或格式化函数时添加数字");
  80. return 0;
  81. } else {
  82. return judge[0];
  83. }
  84. },
  85. // 列发生变化时触发
  86. change(e) {
  87. const { indexs, values } = e;
  88. let selectValue = "";
  89. if (this.mode === "time") {
  90. selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`;
  91. } else {
  92. const year = parseInt(this.intercept(values[0][indexs[0]], "year"));
  93. const month = parseInt(this.intercept(values[1][indexs[1]]));
  94. let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1);
  95. let hour = 0, minute = 0;
  96. const maxDate = common_vendor.dayjs(`${year}-${month}`).daysInMonth();
  97. if (this.mode === "year-month") {
  98. date = 1;
  99. }
  100. date = Math.min(maxDate, date);
  101. if (this.mode === "datetime") {
  102. hour = parseInt(this.intercept(values[3][indexs[3]]));
  103. minute = parseInt(this.intercept(values[4][indexs[4]]));
  104. }
  105. selectValue = Number(new Date(year, month - 1, date, hour, minute));
  106. }
  107. selectValue = this.correctValue(selectValue);
  108. this.innerValue = selectValue;
  109. this.updateColumnValue(selectValue);
  110. this.$emit("change", {
  111. value: selectValue,
  112. mode: this.mode
  113. });
  114. },
  115. // 更新各列的值,进行补0、格式化等操作
  116. updateColumnValue(value) {
  117. this.innerValue = value;
  118. this.updateColumns();
  119. this.updateIndexs(value);
  120. },
  121. // 更新索引
  122. updateIndexs(value) {
  123. let values = [];
  124. const formatter = this.formatter || this.innerFormatter;
  125. const padZero = common_vendor.index.$u.padZero;
  126. if (this.mode === "time") {
  127. const timeArr = value.split(":");
  128. values = [formatter("hour", timeArr[0]), formatter("minute", timeArr[1])];
  129. } else {
  130. values = [
  131. formatter("year", `${common_vendor.dayjs(value).year()}`),
  132. // 月份补0
  133. formatter("month", padZero(common_vendor.dayjs(value).month() + 1))
  134. ];
  135. if (this.mode === "date") {
  136. values.push(formatter("day", padZero(common_vendor.dayjs(value).date())));
  137. }
  138. if (this.mode === "datetime") {
  139. values.push(formatter("day", padZero(common_vendor.dayjs(value).date())), formatter("hour", padZero(common_vendor.dayjs(value).hour())), formatter("minute", padZero(common_vendor.dayjs(value).minute())));
  140. }
  141. }
  142. const indexs = this.columns.map((column, index) => {
  143. return Math.max(0, column.findIndex((item) => item === values[index]));
  144. });
  145. this.innerDefaultIndex = indexs;
  146. },
  147. // 更新各列的值
  148. updateColumns() {
  149. const formatter = this.formatter || this.innerFormatter;
  150. const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type, value)));
  151. this.columns = results;
  152. },
  153. getOriginColumns() {
  154. const results = this.getRanges().map(({ type, range }) => {
  155. let values = times(range[1] - range[0] + 1, (index) => {
  156. let value = range[0] + index;
  157. value = type === "year" ? `${value}` : common_vendor.index.$u.padZero(value);
  158. return value;
  159. });
  160. if (this.filter) {
  161. values = this.filter(type, values);
  162. }
  163. return { type, values };
  164. });
  165. return results;
  166. },
  167. // 通过最大值和最小值生成数组
  168. generateArray(start, end) {
  169. return Array.from(new Array(end + 1).keys()).slice(start);
  170. },
  171. // 得出合法的时间
  172. correctValue(value) {
  173. const isDateMode = this.mode !== "time";
  174. if (isDateMode && !common_vendor.index.$u.test.date(value)) {
  175. value = this.minDate;
  176. } else if (!isDateMode && !value) {
  177. value = `${common_vendor.index.$u.padZero(this.minHour)}:${common_vendor.index.$u.padZero(this.minMinute)}`;
  178. }
  179. if (!isDateMode) {
  180. if (String(value).indexOf(":") === -1)
  181. return common_vendor.index.$u.error("时间错误,请传递如12:24的格式");
  182. let [hour, minute] = value.split(":");
  183. hour = common_vendor.index.$u.padZero(common_vendor.index.$u.range(this.minHour, this.maxHour, Number(hour)));
  184. minute = common_vendor.index.$u.padZero(common_vendor.index.$u.range(this.minMinute, this.maxMinute, Number(minute)));
  185. return `${hour}:${minute}`;
  186. } else {
  187. value = common_vendor.dayjs(value).isBefore(common_vendor.dayjs(this.minDate)) ? this.minDate : value;
  188. value = common_vendor.dayjs(value).isAfter(common_vendor.dayjs(this.maxDate)) ? this.maxDate : value;
  189. return value;
  190. }
  191. },
  192. // 获取每列的最大和最小值
  193. getRanges() {
  194. if (this.mode === "time") {
  195. return [
  196. {
  197. type: "hour",
  198. range: [this.minHour, this.maxHour]
  199. },
  200. {
  201. type: "minute",
  202. range: [this.minMinute, this.maxMinute]
  203. }
  204. ];
  205. }
  206. const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary("max", this.innerValue);
  207. const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary("min", this.innerValue);
  208. const result = [
  209. {
  210. type: "year",
  211. range: [minYear, maxYear]
  212. },
  213. {
  214. type: "month",
  215. range: [minMonth, maxMonth]
  216. },
  217. {
  218. type: "day",
  219. range: [minDate, maxDate]
  220. },
  221. {
  222. type: "hour",
  223. range: [minHour, maxHour]
  224. },
  225. {
  226. type: "minute",
  227. range: [minMinute, maxMinute]
  228. }
  229. ];
  230. if (this.mode === "date")
  231. result.splice(3, 2);
  232. if (this.mode === "year-month")
  233. result.splice(2, 3);
  234. return result;
  235. },
  236. // 根据minDate、maxDate、minHour、maxHour等边界值,判断各列的开始和结束边界值
  237. getBoundary(type, innerValue) {
  238. const value = new Date(innerValue);
  239. const boundary = new Date(this[`${type}Date`]);
  240. const year = common_vendor.dayjs(boundary).year();
  241. let month = 1;
  242. let date = 1;
  243. let hour = 0;
  244. let minute = 0;
  245. if (type === "max") {
  246. month = 12;
  247. date = common_vendor.dayjs(value).daysInMonth();
  248. hour = 23;
  249. minute = 59;
  250. }
  251. if (common_vendor.dayjs(value).year() === year) {
  252. month = common_vendor.dayjs(boundary).month() + 1;
  253. if (common_vendor.dayjs(value).month() + 1 === month) {
  254. date = common_vendor.dayjs(boundary).date();
  255. if (common_vendor.dayjs(value).date() === date) {
  256. hour = common_vendor.dayjs(boundary).hour();
  257. if (common_vendor.dayjs(value).hour() === hour) {
  258. minute = common_vendor.dayjs(boundary).minute();
  259. }
  260. }
  261. }
  262. }
  263. return {
  264. [`${type}Year`]: year,
  265. [`${type}Month`]: month,
  266. [`${type}Date`]: date,
  267. [`${type}Hour`]: hour,
  268. [`${type}Minute`]: minute
  269. };
  270. }
  271. }
  272. };
  273. if (!Array) {
  274. const _easycom_u_picker2 = common_vendor.resolveComponent("u-picker");
  275. _easycom_u_picker2();
  276. }
  277. const _easycom_u_picker = () => "../u-picker/u-picker.js";
  278. if (!Math) {
  279. _easycom_u_picker();
  280. }
  281. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  282. return {
  283. a: common_vendor.sr("picker", "e39cc2d0-0"),
  284. b: common_vendor.o($options.close),
  285. c: common_vendor.o($options.cancel),
  286. d: common_vendor.o($options.confirm),
  287. e: common_vendor.o($options.change),
  288. f: common_vendor.p({
  289. show: _ctx.show,
  290. closeOnClickOverlay: _ctx.closeOnClickOverlay,
  291. columns: $data.columns,
  292. title: _ctx.title,
  293. itemHeight: _ctx.itemHeight,
  294. showToolbar: _ctx.showToolbar,
  295. visibleItemCount: _ctx.visibleItemCount,
  296. defaultIndex: $data.innerDefaultIndex,
  297. cancelText: _ctx.cancelText,
  298. confirmText: _ctx.confirmText,
  299. cancelColor: _ctx.cancelColor,
  300. confirmColor: _ctx.confirmColor
  301. })
  302. };
  303. }
  304. const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-e39cc2d0"], ["__file", "F:/兴元/开门柜项目/平台端管理系统小程序/node_modules/uview-plus/components/u-datetime-picker/u-datetime-picker.vue"]]);
  305. wx.createComponent(Component);