From e8fa16a2ddc9a65858f4f2278c1f0ff702b95c38 Mon Sep 17 00:00:00 2001 From: liberty Date: Wed, 10 May 2023 06:45:46 +0800 Subject: [PATCH] feat: time --- package.json | 2 +- .../components/FormTypes/Time/mobile.vue | 8 +- packages/formEditor/componentsConfig.js | 1 + packages/formEditor/preview.vue | 6 + packages/hooks/use-logic/index.js | 79 ++++--- packages/hooks/use-props/index.js | 2 +- packages/utils/addContext.js | 2 +- pnpm-lock.yaml | 13 +- test/logic/logic.test.js | 205 +++++++++++++++++- 9 files changed, 273 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index f52fcdc..05cfc3d 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "axios": "^1.2.2", "dayjs": "^1.11.7", "element-plus": "^2.2.28", - "everright-filter": "^0.0.20", + "everright-filter": "^0.0.21", "jss": "^10.9.2", "jss-preset-default": "^10.9.2", "lodash-es": "^4.17.21", diff --git a/packages/formEditor/components/FormTypes/Time/mobile.vue b/packages/formEditor/components/FormTypes/Time/mobile.vue index 355b8e4..636ec94 100644 --- a/packages/formEditor/components/FormTypes/Time/mobile.vue +++ b/packages/formEditor/components/FormTypes/Time/mobile.vue @@ -2,6 +2,8 @@ import hooks from '@ER/hooks' import { ref, computed, watch } from 'vue' import dayjs from 'dayjs' +import customParseFormat from 'dayjs/plugin/customParseFormat.js' +dayjs.extend(customParseFormat) export default { name: 'er-time', inheritAttrs: false, @@ -16,11 +18,11 @@ const columnsType = ['hour', 'minute', 'second'] watch(() => props.data.options.defaultValue, (newVal) => { let date = '' if (newVal) { - date = dayjs(`${dayjs().format('YYYY/MM/DD')} ${newVal.split(':')}`, 'YYYY/MM/DD HH:mm:ss') + date = dayjs(newVal, props.data.options.valueFormat) } else { date = dayjs() } - currentTime.value = date.format('HH:mm:ss').split(':') + currentTime.value = date.format(props.data.options.valueFormat).split(':') }, { immediate: true }) @@ -28,7 +30,7 @@ const currentValue = computed({ get () { let result = '' if (props.data.options.defaultValue) { - result = dayjs(`${dayjs().format('YYYY/MM/DD')} ${props.data.options.defaultValue.split(':')}`, 'YYYY/MM/DD HH:mm:ss').format(props.data.options.format) + result = dayjs(props.data.options.defaultValue, props.data.options.valueFormat).format(props.data.options.format) } return result }, diff --git a/packages/formEditor/componentsConfig.js b/packages/formEditor/componentsConfig.js index 691bc00..8422e46 100644 --- a/packages/formEditor/componentsConfig.js +++ b/packages/formEditor/componentsConfig.js @@ -240,6 +240,7 @@ export const fieldsConfig = [ options: { clearable: true, format: 'HH:mm:ss', + valueFormat: 'HH:mm:ss', defaultValue: null, placeholder: '', labelWidth: 100, diff --git a/packages/formEditor/preview.vue b/packages/formEditor/preview.vue index 93713ae..5e6a5d0 100644 --- a/packages/formEditor/preview.vue +++ b/packages/formEditor/preview.vue @@ -61,6 +61,9 @@ const setData2 = (data, value) => { }) if (!_.isEmpty(value)) { state.fields.forEach((e) => { + if (e.type === 'time' && !e.options.valueFormat) { + e.options.valueFormat = 'HH:mm:ss' + } if (value[e.key]) { e.options.defaultValue = value[e.key] } @@ -80,6 +83,9 @@ const setData1 = (data, value) => { }) if (!_.isEmpty(value)) { state.fields.forEach((e) => { + if (e.type === 'time' && !e.options.valueFormat) { + e.options.valueFormat = 'HH:mm:ss' + } if (value[e.key]) { e.options.defaultValue = value[e.key] } diff --git a/packages/hooks/use-logic/index.js b/packages/hooks/use-logic/index.js index 3bbc086..aa59a36 100644 --- a/packages/hooks/use-logic/index.js +++ b/packages/hooks/use-logic/index.js @@ -1,6 +1,13 @@ import { computed, watch } from 'vue' import _ from 'lodash-es' +import dayjs from 'dayjs' +import customParseFormat from 'dayjs/plugin/customParseFormat.js' +import isSameOrAfter from 'dayjs/plugin/isSameOrAfter.js' +import isSameOrBefore from 'dayjs/plugin/isSameOrBefore.js' import utils from '@ER/utils' +dayjs.extend(customParseFormat) +dayjs.extend(isSameOrAfter) +dayjs.extend(isSameOrBefore) const findValidityRule = (state) => { const result = {} for (const logicType in state.logic) { @@ -33,10 +40,13 @@ const getDataType = (fieldType) => { } return result } -const equal = (logicValue, value, fieldType) => { +const equal = (logicValue, value, field) => { // console.log(logicValue) // console.log(value) - if (fieldType === 'region') { + if (field.type === 'time') { + return dayjs(value, field.options.valueFormat).isSame(dayjs(logicValue, field.options.valueFormat)) + } + if (field.type === 'region') { return _.includes(logicValue, value) } if (_.isString(value) || _.isNumber(value)) { @@ -52,7 +62,7 @@ const equal = (logicValue, value, fieldType) => { const notEqual = (...e) => { return !equal(...e) } -const contains = (logicValue, value, fieldType) => { +const contains = (logicValue, value, field) => { if (_.isString(value)) { return logicValue.some((v) => _.includes(value, v)) } @@ -63,8 +73,8 @@ const contains = (logicValue, value, fieldType) => { const notContains = (...e) => { return !contains(...e) } -const empty = (logicValue, value, fieldType) => { - if (fieldType === 'rate') { +const empty = (logicValue, value, field) => { + if (field.type === 'rate') { return value === 0 || utils.isEmpty(value) } return utils.isEmpty(value) @@ -72,68 +82,75 @@ const empty = (logicValue, value, fieldType) => { const notEmpty = (...e) => { return !empty(...e) } -const gt = (logicValue, value, fieldType) => { +const gt = (logicValue, value, field) => { + if (field.type === 'time') { + return dayjs(value, field.options.valueFormat).isAfter(dayjs(logicValue, field.options.valueFormat)) + } return _.gt(value, logicValue) } -const gte = (logicValue, value, fieldType) => { +const gte = (logicValue, value, field) => { + if (field.type === 'time') { + return dayjs(value, field.options.valueFormat).isSameOrAfter(dayjs(logicValue, field.options.valueFormat)) + } return _.gte(value, logicValue) } -const lt = (logicValue, value, fieldType) => { +const lt = (logicValue, value, field) => { + if (field.type === 'time') { + return dayjs(value, field.options.valueFormat).isBefore(dayjs(logicValue, field.options.valueFormat)) + } return _.lt(value === undefined ? 0 : value, logicValue) } -const lte = (logicValue, value, fieldType) => { +const lte = (logicValue, value, field) => { + if (field.type === 'time') { + return dayjs(value, field.options.valueFormat).isSameOrBefore(dayjs(logicValue, field.options.valueFormat)) + } return _.lte(value === undefined ? 0 : value, logicValue) } -const between = (logicValue, value, fieldType) => { +const between = (logicValue, value, field) => { const [min, max] = logicValue - return lte(max, value) && gte(min, value) + return lte(max, value, field) && gte(min, value, field) } export const validator = (logic, value, field) => { let result = false switch (logic.operator) { case 'equal': - result = equal(logic.value, value, field.type) + result = equal(logic.value, value, field) break case 'one_of': break case 'not_equal': - result = notEqual(logic.value, value, field.type) + result = notEqual(logic.value, value, field) break case 'contains': - result = contains(logic.value, value, field.type) + result = contains(logic.value, value, field) break case 'not_contain': - result = notContains(logic.value, value, field.type) + result = notContains(logic.value, value, field) break case 'empty': - result = empty(logic.value, value, field.type) + result = empty(logic.value, value, field) break case 'not_empty': - result = notEmpty(logic.value, value, field.type) + result = notEmpty(logic.value, value, field) break case 'greater_than': - // console.log(logic.value) - // console.log(`操作符的值:${logic.value} type: ${typeof logic.value}`) - // console.log(value) - // console.log(`field的值:${value} type: ${typeof value}`) - // console.log(field) - result = gt(logic.value, value, field.type) + result = gt(logic.value, value, field) break case 'greater_than_equal': - result = gte(logic.value, value, field.type) + result = gte(logic.value, value, field) break case 'less_than': - result = lt(logic.value, value, field.type) + result = lt(logic.value, value, field) break case 'less_than_equal': - result = lte(logic.value, value, field.type) + result = lte(logic.value, value, field) break case 'between': - console.log(logic.value) - console.log(`操作符的值:${logic.value} type: ${typeof logic.value}`) - console.log(value) - console.log(`field的值:${value} type: ${typeof value}`) - console.log(field) + // console.log(logic.value) + // console.log(`操作符的值:${logic.value} type: ${typeof logic.value}`) + // console.log(value) + // console.log(`field的值:${value} type: ${typeof value}`) + // console.log(field) result = between(logic.value, value, field.type) break } diff --git a/packages/hooks/use-props/index.js b/packages/hooks/use-props/index.js index 279ac0c..d4cf02c 100644 --- a/packages/hooks/use-props/index.js +++ b/packages/hooks/use-props/index.js @@ -224,7 +224,7 @@ export const useProps = (state, data, isPc = true, isRoot = false, specialHandli case 'time': result.format = options.format if (isPc) { - result.valueFormat = 'HH:mm:ss' + result.valueFormat = options.valueFormat } break case 'date': diff --git a/packages/utils/addContext.js b/packages/utils/addContext.js index cbfb064..c4232ce 100644 --- a/packages/utils/addContext.js +++ b/packages/utils/addContext.js @@ -426,7 +426,7 @@ export const addContext = (node, parent, fn) => { case 'time': result.format = options.format if (isPc) { - result.valueFormat = 'HH:mm:ss' + result.valueFormat = options.valueFormat } break case 'date': diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a787622..fcd67f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,7 +32,7 @@ specifiers: eslint-plugin-n: ^15.6.1 eslint-plugin-promise: ^6.1.1 eslint-plugin-vue: ^9.9.0 - everright-filter: ^0.0.20 + everright-filter: ^0.0.21 express: ^4.18.2 husky: ^8.0.3 jss: ^10.9.2 @@ -63,7 +63,7 @@ dependencies: axios: registry.npmmirror.com/axios/1.3.4 dayjs: registry.npmmirror.com/dayjs/1.11.7 element-plus: registry.npmmirror.com/element-plus/2.3.1_vue@3.2.47 - everright-filter: 0.0.20_ap7lbsygcc6j7vt74w6nzwfhdi + everright-filter: 0.0.21_ap7lbsygcc6j7vt74w6nzwfhdi jss: registry.npmmirror.com/jss/10.10.0 jss-preset-default: registry.npmmirror.com/jss-preset-default/10.10.0 lodash-es: registry.npmmirror.com/lodash-es/4.17.21 @@ -199,7 +199,6 @@ packages: /@vue/shared/3.2.47: resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==} - dev: false /@vuelidate/core/2.0.0_vue@3.2.47: resolution: {integrity: sha512-xIFgdQlScO0aaSZ0wTGPJh8YcTMNAj5veI8yPgiAyxOT+GV7vNQFiU1vpYWCL4cklkkhYvRRSC2OEX7YOZNmPQ==} @@ -563,8 +562,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /everright-filter/0.0.20_ap7lbsygcc6j7vt74w6nzwfhdi: - resolution: {integrity: sha512-8Y/CUkGZYrsSI9nQ5Xocben7R7ad1euRKz/yc89AELiROe+JGEG/njIVhfV7gsBxJDXL2aLq7mMIMjeQrAZ71Q==} + /everright-filter/0.0.21_ap7lbsygcc6j7vt74w6nzwfhdi: + resolution: {integrity: sha512-aODql6Byda4KRAz+5BoXsbeT9dY1xX+Sq211osvHBad8COWa8TQuAfPYwBLmwVnIoa2gnMX3OJ53ADDDjC1Gog==} peerDependencies: element-plus: ^2.2.28 vue: ^3.2.45 @@ -2549,7 +2548,7 @@ packages: name: '@vue/reactivity' version: 3.2.47 dependencies: - '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.47 + '@vue/shared': 3.2.47 registry.npmmirror.com/@vue/runtime-core/3.2.47: resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz} @@ -2557,7 +2556,7 @@ packages: version: 3.2.47 dependencies: '@vue/reactivity': registry.npmmirror.com/@vue/reactivity/3.2.47 - '@vue/shared': registry.npmmirror.com/@vue/shared/3.2.47 + '@vue/shared': 3.2.47 registry.npmmirror.com/@vue/runtime-dom/3.2.47: resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz} diff --git a/test/logic/logic.test.js b/test/logic/logic.test.js index 421b75d..5d044c1 100644 --- a/test/logic/logic.test.js +++ b/test/logic/logic.test.js @@ -975,7 +975,7 @@ describe('validator', () => { field)).toBeFalsy() }) test('Time', () => { - const field = { type: 'time', label: 'Time', icon: 'time', key: 'time_JfeEFqHMQbVI424FbFEHw', id: 'JfeEFqHMQbVI424FbFEHw', options: { clearable: true, format: 'HH时mm分ss秒', defaultValue: null, placeholder: 'Please select', labelWidth: 100, isShowLabel: true, required: false, disabled: false }, style: { width: { pc: '100%', mobile: '100%' } } } + const field = { type: 'time', label: 'Time', icon: 'time', key: 'time_JfeEFqHMQbVI424FbFEHw', id: 'JfeEFqHMQbVI424FbFEHw', options: { clearable: true, format: 'HH时mm分ss秒', valueFormat: 'HH:mm:ss', defaultValue: null, placeholder: 'Please select', labelWidth: 100, isShowLabel: true, required: false, disabled: false }, style: { width: { pc: '100%', mobile: '100%' } } } expect( validator({ operator: 'equal', @@ -1026,6 +1026,209 @@ describe('validator', () => { }, null, field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than', + value: '16:12:47' + }, + '16:12:48', + field)).toBeTruthy() + expect( + validator({ + operator: 'greater_than', + value: '16:12:47' + }, + '16:12:46', + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than', + value: '16:12:47' + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than', + value: '16:12:47' + }, + null, + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than', + value: '16:12:47' + }, + undefined, + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than_equal', + value: '16:12:48' + }, + '16:12:48', + field)).toBeTruthy() + expect( + validator({ + operator: 'greater_than_equal', + value: '16:12:48' + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than_equal', + value: '16:12:48' + }, + undefined, + field)).toBeFalsy() + expect( + validator({ + operator: 'greater_than_equal', + value: '16:12:48' + }, + null, + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than', + value: '16:12:48' + }, + '16:12:47', + field)).toBeTruthy() + expect( + validator({ + operator: 'less_than', + value: '16:12:48' + }, + '16:12:48', + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than', + value: '16:12:48' + }, + null, + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than', + value: '16:12:48' + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than', + value: '16:12:48' + }, + undefined, + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than_equal', + value: '16:12:48' + }, + '16:12:48', + field)).toBeTruthy() + expect( + validator({ + operator: 'less_than_equal', + value: '16:12:48' + }, + '16:12:47', + field)).toBeTruthy() + expect( + validator({ + operator: 'less_than_equal', + value: '16:12:48' + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than_equal', + value: '16:12:48' + }, + null, + field)).toBeFalsy() + expect( + validator({ + operator: 'less_than_equal', + value: '16:12:48' + }, + undefined, + field)).toBeFalsy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + '16:12:48', + field)).toBeTruthy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + '16:12:49', + field)).toBeTruthy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + '16:12:50', + field)).toBeFalsy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + null, + field)).toBeFalsy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + '', + field)).toBeFalsy() + expect( + validator({ + operator: 'between', + value: [ + '16:12:48', + '16:12:49' + ] + }, + undefined, + field)).toBeFalsy() }) // test('Date', () => { // const field = { type: 'time', label: 'Time', icon: 'time', key: 'time_JfeEFqHMQbVI424FbFEHw', id: 'JfeEFqHMQbVI424FbFEHw', options: { clearable: true, format: 'HH时mm分ss秒', defaultValue: null, placeholder: 'Please select', labelWidth: 100, isShowLabel: true, required: false, disabled: false }, style: { width: { pc: '100%', mobile: '100%' } } }