| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- <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>
|