初始提交
This commit is contained in:
221
components/Jnpf/DateCalculate/index.vue
Normal file
221
components/Jnpf/DateCalculate/index.vue
Normal file
@@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<view class="jnpf-calculation jnpf-calculation-right">
|
||||
<u-input input-align='right' :modelValue="jnpf.toDate(innerValue, format)" disabled placeholder='' />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
dayjs
|
||||
} from '@/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js'
|
||||
|
||||
const calcRPN = rpnExps => {
|
||||
rpnExps = rpnExps.concat()
|
||||
const calc = (x, y, type) => {
|
||||
let a1 = Number(x),
|
||||
a2 = Number(y)
|
||||
switch (type) {
|
||||
case '+':
|
||||
return a1 + a2;
|
||||
case '-':
|
||||
return a1 - a2;
|
||||
case '×':
|
||||
return a1 * a2;
|
||||
case '÷':
|
||||
return a1 / a2;
|
||||
}
|
||||
}
|
||||
for (let i = 2; i < rpnExps.length; i++) {
|
||||
if ('+-×÷'.includes(rpnExps[i])) {
|
||||
let val = calc(rpnExps[i - 2], rpnExps[i - 1], rpnExps[i])
|
||||
rpnExps.splice(i - 2, 3, val)
|
||||
i = i - 2
|
||||
}
|
||||
}
|
||||
return rpnExps[0]
|
||||
}
|
||||
const mergeNumberOfExps = expressions => {
|
||||
const res = []
|
||||
const isNumChar = n => /^[\d|\.]$/.test(n)
|
||||
for (let i = 0; i < expressions.length; i++) {
|
||||
if (i > 0 && isNumChar(expressions[i - 1]) && isNumChar(expressions[i])) {
|
||||
res[res.length - 1] += expressions[i]
|
||||
continue
|
||||
}
|
||||
res.push(expressions[i])
|
||||
}
|
||||
return res
|
||||
}
|
||||
export default {
|
||||
name: 'jnpf-date-calculation',
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
expression: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
formData: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
rowIndex: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
startRelationField: String,
|
||||
startTimeValue: [String, Number],
|
||||
startTimeType: {
|
||||
default: 1,
|
||||
type: Number,
|
||||
},
|
||||
format: {
|
||||
default: 'yyyy-MM-dd',
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
innerValue: '',
|
||||
startTime: new Date(),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getExp() {
|
||||
return mergeNumberOfExps(this.expression)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
formData: {
|
||||
handler(val, oldVal) {
|
||||
setTimeout(() => {
|
||||
this.execRPN()
|
||||
}, 0)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
modelValue: {
|
||||
handler(val, oldVal) {
|
||||
this.innerValue = val
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 计算表达式
|
||||
*/
|
||||
execRPN() {
|
||||
const temp = this.getExp.map(t => typeof t === 'object' ? this.getFormVal(t.__vModel__) : t)
|
||||
if (this.startTimeType == 1) this.startTime = this.startTimeValue;
|
||||
if (this.startTimeType == 2) this.startTime = this.getFormVal(this.startRelationField);
|
||||
this.innerValue = this.calcDate(this.startTime, this.getDateInfo(temp));
|
||||
this.$emit('update:modelValue', this.innerValue)
|
||||
},
|
||||
getDateInfo(exp) {
|
||||
let days = 0;
|
||||
let months = 0;
|
||||
let years = 0;
|
||||
let hours = 0;
|
||||
let minutes = 0;
|
||||
let seconds = 0;
|
||||
for (let i = 0; i < exp.length; i += 3) {
|
||||
const sign = exp[i];
|
||||
const value = Number.parseInt(exp[i + 1], 10);
|
||||
const unit = exp[i + 2];
|
||||
const factor = sign === '+' ? 1 : -1;
|
||||
switch (unit) {
|
||||
case 'd': {
|
||||
days += factor * value;
|
||||
break;
|
||||
}
|
||||
case 'h': {
|
||||
hours += factor * value;
|
||||
break;
|
||||
}
|
||||
case 'M': {
|
||||
months += factor * value;
|
||||
break;
|
||||
}
|
||||
case 'm': {
|
||||
minutes += factor * value;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
seconds += factor * value;
|
||||
break;
|
||||
}
|
||||
case 'Y': {
|
||||
years += factor * value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
months,
|
||||
seconds,
|
||||
years
|
||||
};
|
||||
},
|
||||
calcDate(date, change) {
|
||||
if (!date) return '';
|
||||
const newDate = new Date(date);
|
||||
newDate.setFullYear(newDate.getFullYear() + change.years);
|
||||
newDate.setMonth(newDate.getMonth() + change.months);
|
||||
newDate.setDate(newDate.getDate() + change.days);
|
||||
newDate.setHours(newDate.getHours() + change.hours);
|
||||
newDate.setMinutes(newDate.getMinutes() + change.minutes);
|
||||
newDate.setSeconds(newDate.getSeconds() + change.seconds);
|
||||
return dayjs(newDate).startOf(this.jnpf.getDateTimeUnit(this.format)).valueOf();
|
||||
},
|
||||
/**
|
||||
* 获取指定组件的值
|
||||
*/
|
||||
getFormVal(vModel) {
|
||||
try {
|
||||
if (vModel.indexOf('.') > -1) {
|
||||
let [tableVModel, cmpVModel] = vModel.split('.');
|
||||
if (typeof this.rowIndex === 'number') {
|
||||
if (!Array.isArray(this.formData[tableVModel]) || this.formData[tableVModel].length < this
|
||||
.rowIndex + 1) return 0;
|
||||
return this.formData[tableVModel][this.rowIndex][cmpVModel] || 0;
|
||||
} else {
|
||||
if (!this.formData[tableVModel].length) return 0;
|
||||
return this.formData[tableVModel].reduce((sum, c) => (c[cmpVModel] ? Number(c[cmpVModel]) :
|
||||
0) + sum, 0);
|
||||
}
|
||||
}
|
||||
return this.formData[vModel] || 0
|
||||
} catch (error) {
|
||||
console.warn('计算公式出错, 可能包含无效的组件值', error)
|
||||
return 0
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.jnpf-calculation {
|
||||
width: 100%;
|
||||
|
||||
&.jnpf-calculation-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tips {
|
||||
color: #999999;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.unit {
|
||||
padding-left: 10rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user