|
|
@@ -11,12 +11,33 @@
|
|
|
v-if="!(elem.elementName.endsWith('审批') && '' == elem.defaultValue && ['0', undefined].includes(elem.canEdit)) && ('' != elem.defaultValue || 1 == elem.canEdit)" :label="elem.elementName" :name="elem.elementId">
|
|
|
<view class="element_value_container">
|
|
|
<view v-if="'1' == elem.canEdit && '8' != elem.type" class="element_value">
|
|
|
- <!-- 富文本框 -->
|
|
|
- <uni-easyinput v-if="'1' == elem.type" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))" placeholder="请输入内容"
|
|
|
- v-model="elem.defaultValue" type="textarea"></uni-easyinput>
|
|
|
- <!-- 文本框 -->
|
|
|
+ <!-- 关联变量输入框 -->
|
|
|
+ <!-- 计算出差天数 -->
|
|
|
+ <uni-easyinput v-if="undefined != elem.bindTimeRange && elem.elementName == '出差天数'"
|
|
|
+ :type="fieldTypeDict[elem.fieldType] || 'text'" :value="calculateBusinessDifference(elem, formElements)"
|
|
|
+ placeholder="" :disabled="true"></uni-easyinput>
|
|
|
+ <uni-easyinput v-else-if="undefined != elem.bindTimeRange"
|
|
|
+ :type="fieldTypeDict[elem.fieldType] || 'text'"
|
|
|
+ :value="calculateTimeDifference(elem, formElements)" placeholder="" :disabled="true"></uni-easyinput>
|
|
|
+ <!-- 金额转大写 -->
|
|
|
+ <uni-easyinput v-else-if="elem.elementName.endsWith('大写')" placeholder=""
|
|
|
+ :value="computedNumberToChineseCurrency(elem, formElements)"></uni-easyinput>
|
|
|
+ <!-- 主表关联变量输入框 -->
|
|
|
+ <!-- 数值输入框 -->
|
|
|
+ <uni-easyinput v-else-if="'1' == elem.fieldType && elem.BddzText"
|
|
|
+ type="digit" :value="computedBddzTextValue(elem)" @input="digitInput($event, elem)" placeholder="" :disabled="true"></uni-easyinput>
|
|
|
+ <!-- 输入框 -->
|
|
|
+ <uni-easyinput v-else-if="elem.BddzText"
|
|
|
+ :type="fieldTypeDict[elem.fieldType] || 'text'"
|
|
|
+ :value="computedBddzTextValue(elem)" placeholder="" :disabled="true"></uni-easyinput>
|
|
|
+ <!-- 数值输入框 -->
|
|
|
+ <uni-easyinput v-else-if="'0' == elem.type && '1' == elem.fieldType" :disabled="'0' == elem.canEdit" type="digit" :placeholder="'0' == elem.canEdit ? '' : '请输入内容'" @input="digitInput($event, elem)"
|
|
|
+ v-model="elem.defaultValue" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))"></uni-easyinput>
|
|
|
+ <!-- 输入框 -->
|
|
|
<uni-easyinput v-else-if="'0' == elem.type" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))" placeholder="请输入内容"
|
|
|
v-model="elem.defaultValue" type="text"></uni-easyinput>
|
|
|
+ <!-- 富文本框 -->
|
|
|
+ <uni-easyinput v-else-if="'1' == elem.type" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))" placeholder="请输入内容" v-model="elem.defaultValue" type="textarea"></uni-easyinput>
|
|
|
<!-- 下拉框 -->
|
|
|
<picker class="picker_container" v-else-if="'2' == elem.type"
|
|
|
@change="bindPickerChange($event, elem)" :value="elem.defaultValue"
|
|
|
@@ -27,6 +48,18 @@
|
|
|
elem.typeDetail.enum[0].enumVname }}
|
|
|
</view>
|
|
|
</picker>
|
|
|
+ <!-- 数据选择器 -->
|
|
|
+ <uni-data-checkbox v-else-if="'5' == elem.type" multiple v-model="elem.defaultValue" :localdata="formatCheckbox(elem)" @change="changeDataCheckBox($event,elem)"></uni-data-checkbox>
|
|
|
+ <!-- 开始时间选择器 -->
|
|
|
+ <uni-datetime-picker :end="formElements[elem.endElemIndex].defaultValue"
|
|
|
+ @change="setTimeRange(elem)"
|
|
|
+ v-else-if="'9' == elem.type && undefined != elem.endElemIndex"
|
|
|
+ v-model="elem.defaultValue" :clear-icon="false" type="datetime" />
|
|
|
+ <!-- 结束时间选择器 -->
|
|
|
+ <uni-datetime-picker :start="formElements[elem.startElemIndex].defaultValue"
|
|
|
+ @change="setTimeRange(elem)"
|
|
|
+ v-else-if="'9' == elem.type && undefined != elem.startElemIndex"
|
|
|
+ v-model="elem.defaultValue" :clear-icon="false" type="datetime" />
|
|
|
<!-- 年月日 时分秒 -->
|
|
|
<uni-datetime-picker v-else-if="'9' == elem.type" v-model="elem.defaultValue"
|
|
|
type="datetime" />
|
|
|
@@ -68,8 +101,12 @@
|
|
|
<uni-forms label-position="left" :label-width="125" :border="true">
|
|
|
<uni-forms-item :name="elem.tableField" v-for="(elem, itemIndex) in table"
|
|
|
:label="repeatingForm.elementItem[itemIndex].elementName.slice(3)" :key="itemIndex">
|
|
|
- <uni-easyinput placeholder="请输入内容" v-model="elem.defaultValue"
|
|
|
- :type="fieldTypeDict[repeatingForm.elementItem[itemIndex].fieldType.value] || 'text'" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))"></uni-easyinput>
|
|
|
+ <!-- 自定义关联变量 -->
|
|
|
+ <uni-easyinput v-if="repeatingForm.elementItem[itemIndex].bddzText" :placeholder="''" :type="fieldTypeDict[repeatingForm.elementItem[itemIndex].fieldType.value] || 'text'" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))" :value="calculateRepeatingFormExpression(elem, table)" :disabled="true"></uni-easyinput>
|
|
|
+ <!-- 数值输入框 -->
|
|
|
+ <uni-easyinput v-else-if="'1' == repeatingForm.elementItem[itemIndex].fieldType.value" placeholder="请输入内容" v-model="elem.defaultValue" @input="digitInput($event, elem)" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))" type="digit"></uni-easyinput>
|
|
|
+ <!-- 输入框 -->
|
|
|
+ <uni-easyinput v-else placeholder="请输入内容" v-model="elem.defaultValue" type="'text'" placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))"></uni-easyinput>
|
|
|
</uni-forms-item>
|
|
|
</uni-forms>
|
|
|
<!-- <view class="repeating_table_button_container">
|
|
|
@@ -224,7 +261,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { computed, onMounted, reactive, ref } from 'vue'
|
|
|
+import { computed, onMounted, reactive, ref, nextTick } from 'vue'
|
|
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
|
|
import { LSignatureToTempFilePathOptions, LSignatureToFileSuccess } from '@/uni_modules/lime-signature'
|
|
|
import attachmentList from '@/components/ygoa/attachmentList.vue'
|
|
|
@@ -232,9 +269,12 @@ import config from '@/config.js'
|
|
|
import $tab from '@/plugins/tab.js'
|
|
|
import $modal from '@/plugins/modal.js'
|
|
|
import { getProcessFlowInfo, getProcessFormInfo, getProcessFormInfoInFlow, getProcessFlow, submitProcessFlow, cancelProcessFlow, uploadSignatureImg, uploadSignatureBoardImg, uploadFile } from '@/api/process.js'
|
|
|
+import { getAttendanceSegment } from '@/api/work.js'
|
|
|
import { useUserStore } from '@/store/user.js'
|
|
|
import {getLoginInfo,getSession,setSession} from '@/utils/auth.js'
|
|
|
import {reLogin} from '@/api/login.js'
|
|
|
+import { convertToChineseCurrency } from '@/utils/ygoa.js'
|
|
|
+import { calCommonExp } from '@/utils/rpn.js'
|
|
|
const fieldTypeDict = {
|
|
|
'0': 'text',
|
|
|
'1': 'digit'
|
|
|
@@ -268,9 +308,9 @@ onShow(()=>{
|
|
|
//如果有登录信息,就自动登录刷session
|
|
|
if(Object.keys(loginInfo).length !== 0){
|
|
|
reLogin(loginInfo.username, loginInfo.password).then((res) => {
|
|
|
- if ("ok" === res.data) {
|
|
|
- setSession(res.cookies[0].split("=")[1].split(";")[0]);
|
|
|
- }
|
|
|
+ if ("ok" === res.data) {
|
|
|
+ setSession(res.cookies[0].split("=")[1].split(";")[0]);
|
|
|
+ }
|
|
|
}).catch(res=>{
|
|
|
console.log(res);
|
|
|
})
|
|
|
@@ -286,6 +326,7 @@ const repeatingForm = ref({
|
|
|
elements: [],
|
|
|
elementItem: [],
|
|
|
})
|
|
|
+// 是否有重复表
|
|
|
const repeatingFormNotEmpty = ref(false)
|
|
|
function repeatingFormHasValue() {
|
|
|
if (repeatingForm.value === undefined) return
|
|
|
@@ -335,6 +376,7 @@ const formInfo = ref({
|
|
|
})
|
|
|
const fileList = ref([])
|
|
|
const isCancel = ref(false)
|
|
|
+// 获取流程表单
|
|
|
function initProcessForm() {
|
|
|
if (processInfo.tinsId) {
|
|
|
// 待办审批流程表单数据
|
|
|
@@ -343,10 +385,12 @@ function initProcessForm() {
|
|
|
formInfo.value = returnParams.formInfo[0]
|
|
|
repeatingForm.value = returnParams.repeatingForm
|
|
|
getMainFormRule()
|
|
|
+ computedMainFormValue()
|
|
|
if (returnParams.isCancel == 1) {
|
|
|
isCancel.value = true
|
|
|
}
|
|
|
repeatingFormHasValue()
|
|
|
+ bindTimeRangeData()
|
|
|
remark.value = flowInfo.value.seModel == '0' ? '同意' : '重新提交'
|
|
|
})
|
|
|
} else {
|
|
|
@@ -367,6 +411,7 @@ const stepActive = ref(-1)
|
|
|
const flowInfo = ref({
|
|
|
seModel: '0'
|
|
|
})
|
|
|
+// 获取流程信息
|
|
|
function initProcessInfo() {
|
|
|
getProcessFlow(userStore.user.useId, processInfo).then(({ returnParams }) => {
|
|
|
options.value = returnParams.list.map((item, index) => {
|
|
|
@@ -408,6 +453,295 @@ function bindPickerChange(e, item) {
|
|
|
function formatDict(dict) {
|
|
|
return dict.map(({ enumVname }) => enumVname)
|
|
|
}
|
|
|
+//数据选择器
|
|
|
+function formatCheckbox(elem){
|
|
|
+ let dict = elem.typeDetail.enum
|
|
|
+ elem['checkBox'] = true
|
|
|
+ return dict.map((item, index) => ({
|
|
|
+ text: item.enumVname,
|
|
|
+ value: item.enumVname
|
|
|
+ }));
|
|
|
+}
|
|
|
+const testValue=ref('')
|
|
|
+function changeDataCheckBox(e,elem){
|
|
|
+ // elem.checkBox=e.detail.value.join(",")
|
|
|
+ testValue.value=e.detail.value.join(",")
|
|
|
+}
|
|
|
+
|
|
|
+const timeRangeItems = ref([
|
|
|
+ ['开始时间', '结束时间', '多少小时'],
|
|
|
+ ['出发时间', '预计返回时间'],
|
|
|
+ ['出差时间', '返回时间', '出差天数'],
|
|
|
+ ['出门时间', '预计返回时间'],
|
|
|
+ ['开始时间', '结束时间', '合计小时'],
|
|
|
+])
|
|
|
+// 关联时间变量
|
|
|
+function bindTimeRangeData() {
|
|
|
+ return new Promise<void>((resolve) => {
|
|
|
+ timeRangeItems.value.forEach((range) => {
|
|
|
+ const [startName, endName, bindName] = range;
|
|
|
+
|
|
|
+ // 找到 startName 和 endName 的索引
|
|
|
+ const startIndex = formElements.value.findIndex((item) => item.elementName === startName);
|
|
|
+ const endIndex = formElements.value.findIndex((item) => item.elementName === endName);
|
|
|
+
|
|
|
+ const formatDate = (date) => {
|
|
|
+ const pad = (num) => num.toString().padStart(2, '0');
|
|
|
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只有找到 startName 和 endName 后,才检查 bindName
|
|
|
+ if (startIndex !== -1 && endIndex !== -1) {
|
|
|
+ formElements.value[startIndex].defaultValue = formatDate(new Date())
|
|
|
+ if (bindName) {
|
|
|
+ const bindIndex = formElements.value.findIndex((item) => item.elementName === bindName);
|
|
|
+ if (bindIndex !== -1) {
|
|
|
+ // 所有匹配项都存在,保存索引
|
|
|
+ formElements.value[startIndex].endElemIndex = endIndex;
|
|
|
+ formElements.value[endIndex].startElemIndex = startIndex;
|
|
|
+ formElements.value[bindIndex].bindTimeRange = {
|
|
|
+ startIndex,
|
|
|
+ endIndex
|
|
|
+ };
|
|
|
+ setAttendanceSegment() // 获取班次信息
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 没有 bindName,仅保存 start 和 end 的索引
|
|
|
+ formElements.value[startIndex].endElemIndex = endIndex;
|
|
|
+ formElements.value[endIndex].startElemIndex = startIndex;
|
|
|
+ }
|
|
|
+ // TODO 加班开始时间默认当天下班时间 请假时间默认当天上班时间
|
|
|
+ }
|
|
|
+ });
|
|
|
+ resolve(); // 返回一个 resolved 状态的 Promise
|
|
|
+ });
|
|
|
+}
|
|
|
+// 计算时间差
|
|
|
+function calculateBusinessDifference(item, form) {
|
|
|
+ return item.defaultValue = (calculateTimeDifference(item, form)/7).toFixed(2)
|
|
|
+}
|
|
|
+function calculateTimeDifference(item, form) {
|
|
|
+ // 获取 开始时间 和 结束时间
|
|
|
+ const { startIndex, endIndex } = item.bindTimeRange;
|
|
|
+ const startTime = new Date(form[startIndex].defaultValue);
|
|
|
+ const endTime = new Date(form[endIndex].defaultValue);
|
|
|
+
|
|
|
+ // 检查时间是否合法
|
|
|
+ if (isNaN(startTime.getTime()) || isNaN(endTime.getTime())) {
|
|
|
+ return item.defaultValue = 0
|
|
|
+ }
|
|
|
+ // 请假申请的时间差 表单项为合计小时
|
|
|
+ const type = item.elementName == '合计小时' ? '非工作时间' : '工作时间'
|
|
|
+ // 计算时间差
|
|
|
+ const timeDifferenceInHours = calculateWorkingHours(startTime, endTime, type);
|
|
|
+ // const timeDifferenceInMs = endTime - startTime;
|
|
|
+ // let timeDifferenceInHours = (timeDifferenceInMs / (1000 * 60 * 60)).toFixed(1);
|
|
|
+ // let timeDifferenceInHours = (timeDifferenceInMs / (1000 * 60 * 60))
|
|
|
+ // // 计算小数部分
|
|
|
+ // const decimalPart = timeDifferenceInHours - Math.floor(timeDifferenceInHours)
|
|
|
+ // if (decimalPart >= 0.5) {
|
|
|
+ // // 如果小数部分大于等于 0.5,向上取整到 0.5 的倍数
|
|
|
+ // timeDifferenceInHours = Math.floor(timeDifferenceInHours) + 0.5;
|
|
|
+ // } else {
|
|
|
+ // // 如果小数部分小于 0.5,向下取整到 0.5 的倍数
|
|
|
+ // timeDifferenceInHours = Math.floor(timeDifferenceInHours);
|
|
|
+ // }
|
|
|
+ // 保存到 defaultValue
|
|
|
+ return item.defaultValue = Number(timeDifferenceInHours.toFixed(2));
|
|
|
+}
|
|
|
+let workingPeriods = []
|
|
|
+let workDays = [] // 0为周日
|
|
|
+function setAttendanceSegment() {
|
|
|
+ getAttendanceSegment(userStore.user.unitId).then(({ returnParams }) => {
|
|
|
+ const workTime = returnParams[0].work_time.split(';')
|
|
|
+ workDays = returnParams[0].work_days.split(',')
|
|
|
+ for (const time of workTime) {
|
|
|
+ if (time == '') continue
|
|
|
+ const times = time.split(',')
|
|
|
+ const obj = {
|
|
|
+ start: times[0],
|
|
|
+ end: times[1]
|
|
|
+ }
|
|
|
+ workingPeriods.push(obj)
|
|
|
+ }
|
|
|
+ if (workingPeriods.length == 0) {
|
|
|
+ workingPeriods = [
|
|
|
+ { start: "09:00", end: "12:00" }, // 上午
|
|
|
+ { start: "13:30", end: "17:30" }, // 下午
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ workDays = workDays.map(item => Number(item))
|
|
|
+ const sundayIndex = workDays.findIndex(item => item == 7)
|
|
|
+ console.log('workDays: ',workDays);
|
|
|
+ if (sundayIndex != -1) {
|
|
|
+ workDays[sundayIndex] = 0
|
|
|
+ }
|
|
|
+ if (workDays.length == 0) {
|
|
|
+ workDays = [1, 2, 3, 4, 5, 6, 0] // 0为周日
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+function calculateWorkingHours(startTime, endTime, type) {
|
|
|
+ // 将时间字符串解析为分钟数
|
|
|
+ const formatTime = (timeString) => {
|
|
|
+ const [hours, minutes] = timeString.split(":").map(Number)
|
|
|
+ return hours * 60 + minutes
|
|
|
+ };
|
|
|
+ // 计算两个时间段的重叠部分
|
|
|
+ const calculateOverlap = (start1, end1, start2, end2) => {
|
|
|
+ const overlapStart = Math.max(start1, start2)
|
|
|
+ const overlapEnd = Math.min(end1, end2)
|
|
|
+ return Math.max(0, overlapEnd - overlapStart) // 如果无重叠返回 0
|
|
|
+ };
|
|
|
+ // 将 Date 转化为当天的分钟数
|
|
|
+ const dateToMinutes = (date) => date.getHours() * 60 + date.getMinutes()
|
|
|
+ // 判断日期是否是工作日
|
|
|
+ const isRestdays = (date) => !workDays.includes(date.getDay())
|
|
|
+ // 确保 startTime 和 endTime 是 Date 类型
|
|
|
+ if (!(startTime instanceof Date) || !(endTime instanceof Date)) {
|
|
|
+ throw new Error("startTime 和 endTime 必须是 Date 类型")
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将时间范围分解为每天的计算
|
|
|
+ const startDate = new Date(startTime)
|
|
|
+ const endDate = new Date(endTime)
|
|
|
+ startDate.setHours(0, 0, 0, 0)
|
|
|
+ endDate.setHours(0, 0, 0, 0)
|
|
|
+
|
|
|
+ let totalMinutes = 0
|
|
|
+ // 遍历时间范围的每一天
|
|
|
+ for (
|
|
|
+ let currentDate = new Date(startDate);
|
|
|
+ currentDate <= endDate;
|
|
|
+ currentDate.setDate(currentDate.getDate() + 1)
|
|
|
+ ) {
|
|
|
+
|
|
|
+ const isStartDay = currentDate.getTime() === startDate.getTime();
|
|
|
+ const isEndDay = currentDate.getTime() === endDate.getTime();
|
|
|
+
|
|
|
+ // 当天的起始和结束时间
|
|
|
+ const dayStart = isStartDay ? dateToMinutes(startTime) : 0;
|
|
|
+ const dayEnd = isEndDay ? dateToMinutes(endTime) : 1440; // 1440 = 24 * 60
|
|
|
+ // TODO 改为配置选择
|
|
|
+ if (type == "工作时间") {
|
|
|
+ // 如果当前日期不是工作日,跳过
|
|
|
+ if (isRestdays(currentDate)) continue;
|
|
|
+ // 计算工作时间段内的时间
|
|
|
+ workingPeriods.forEach((period) => {
|
|
|
+ const periodStart = formatTime(period.start);
|
|
|
+ const periodEnd = formatTime(period.end);
|
|
|
+ totalMinutes += calculateOverlap(dayStart, dayEnd, periodStart, periodEnd);
|
|
|
+ });
|
|
|
+ } else if (type == "非工作时间") {
|
|
|
+ if (isRestdays(currentDate)) {
|
|
|
+ // 计算非工作日时间差
|
|
|
+ const midnight = new Date(currentDate)
|
|
|
+ midnight.setHours(24, 0, 0, 0)
|
|
|
+ const timeDiffInMs = dayEnd - dayStart
|
|
|
+ totalMinutes += timeDiffInMs
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ // 计算非工作时间段的时间
|
|
|
+ let nonWorkingMinutes = 0;
|
|
|
+ let current = dayStart;
|
|
|
+ for (const period of workingPeriods) {
|
|
|
+ const periodStart = formatTime(period.start);
|
|
|
+ const periodEnd = formatTime(period.end);
|
|
|
+
|
|
|
+ if (current < periodStart) {
|
|
|
+ nonWorkingMinutes += calculateOverlap(current, dayEnd, current, periodStart);
|
|
|
+ }
|
|
|
+ current = Math.max(current, periodEnd);
|
|
|
+ }
|
|
|
+ if (current < dayEnd) {
|
|
|
+ nonWorkingMinutes += dayEnd - current;
|
|
|
+ }
|
|
|
+ totalMinutes += nonWorkingMinutes;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转换为小时
|
|
|
+ return totalMinutes / 60;
|
|
|
+}
|
|
|
+function setTimeRange(e) {
|
|
|
+ // console.log('setTimeRange', e)
|
|
|
+}
|
|
|
+// 生成人民币大写
|
|
|
+function computedNumberToChineseCurrency(item, form) {
|
|
|
+ const elem = form.find(elem => elem.elementName == item.BddzText.slice(3))
|
|
|
+ return item.defaultValue = convertToChineseCurrency(elem.defaultValue)
|
|
|
+}
|
|
|
+function computedBddzTextValue(item) {
|
|
|
+ const mainIndex = formElements.value.findIndex(({ elementName }) => elementName == item.BddzText.slice(3))
|
|
|
+ const reIndex = repeatingForm.value.elementItem.findIndex(({ elementName }) => elementName == item.BddzText)
|
|
|
+ if (mainIndex != -1) {
|
|
|
+ return item.defaultValue = formElements.value[mainIndex].defaultValue
|
|
|
+ }
|
|
|
+ if (reIndex != -1) {
|
|
|
+ return computedValueToRepeatingForm(item)
|
|
|
+ }
|
|
|
+}
|
|
|
+function computedValueToRepeatingForm(item) {
|
|
|
+ const index = repeatingForm.value.elementItem.findIndex(({ elementName }) => elementName.slice(3) == item.BddzText.slice(3))
|
|
|
+ let result = 0
|
|
|
+ for (const formItem of repeatingForm.value.elements) {
|
|
|
+ result += Number(formItem[index].defaultValue) || 0
|
|
|
+ }
|
|
|
+ return item.defaultValue = Number(result.toFixed(2))
|
|
|
+}
|
|
|
+function digitInput(event, item) {
|
|
|
+ // 获取输入框当前的值
|
|
|
+ const currentValue = event;
|
|
|
+
|
|
|
+ // 过滤非数字和小数点的字符
|
|
|
+ const filteredValue = currentValue.replace(/[^0-9.]/g, '');
|
|
|
+
|
|
|
+ // 防止多个小数点
|
|
|
+ const parts = filteredValue.split('.');
|
|
|
+ let finalValue;
|
|
|
+ // console.log('event: ',event);
|
|
|
+ if (parts.length > 2) {
|
|
|
+ // 如果有多个小数点,保留第一个小数点及后续数字
|
|
|
+ finalValue = parts[0] + '.' + parts[1];
|
|
|
+ } else {
|
|
|
+ finalValue = filteredValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log('finalValue: ',finalValue);
|
|
|
+ // console.log('item: ',item.defaultValue);
|
|
|
+ nextTick(() => {
|
|
|
+ // 更新最终结果到 item
|
|
|
+ item.defaultValue = finalValue
|
|
|
+ event = finalValue
|
|
|
+ })
|
|
|
+ return event;
|
|
|
+}
|
|
|
+// 计算重复表关联变量表达式结果值
|
|
|
+function calculateRepeatingFormExpression(item, form) {
|
|
|
+ // 提取表达式中的变量名
|
|
|
+ const variablePattern = /my:[\u4e00-\u9fa5]+/g;
|
|
|
+ let match;
|
|
|
+ let expression = item.BddzText
|
|
|
+ // 替换表达式中的变量
|
|
|
+ while ((match = variablePattern.exec(item.BddzText)) !== null) {
|
|
|
+ const variableName = match[0]; // 完整变量名
|
|
|
+ // 找到 重复表 中对应的索引
|
|
|
+ const index = repeatingForm.value.elementItem.findIndex(item => item.elementName === variableName);
|
|
|
+ if (index !== -1) {
|
|
|
+ const value = form[index]?.defaultValue || 0;
|
|
|
+ expression = expression.replace(match[0], value);
|
|
|
+ } else {
|
|
|
+ // 未匹配到的变量替换为 0
|
|
|
+ expression = expression.replace(match[0], 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (/[^0-9\+\-\*\/\(\)\.]/.test(expression)) {
|
|
|
+ console.error('错误的表达式:', expression);
|
|
|
+ $modal.msg('自动计算错误,请手动输入')
|
|
|
+ return item.defaultValue = 0;
|
|
|
+ }
|
|
|
+ return item.defaultValue = Number(calCommonExp(expression).toFixed(2)); // 返回填充后的表达式
|
|
|
+}
|
|
|
|
|
|
const signaturePopup = ref(null)
|
|
|
const signatureRef = ref(null)
|
|
|
@@ -419,12 +753,14 @@ function handleSignature(index) {
|
|
|
signaturePopup.value.open()
|
|
|
initSignature()
|
|
|
}
|
|
|
+// 初始化签字板
|
|
|
function initSignature() {
|
|
|
signaturePopupShow.value = false
|
|
|
setTimeout(() => {
|
|
|
signaturePopupShow.value = true
|
|
|
}, 100)
|
|
|
}
|
|
|
+// 点击签字板按钮
|
|
|
function onclickSignatureButton(event) {
|
|
|
// console.log('onclickSignatureButton: ', event);
|
|
|
switch (event) {
|
|
|
@@ -527,6 +863,7 @@ async function handleFileSelect(files) { // 新增文件
|
|
|
// console.log('UploadFiles', files.tempFiles);
|
|
|
|
|
|
}
|
|
|
+// 文件上传触发事件
|
|
|
function handleFileProgress(file, progress) {
|
|
|
// console.log('handleFileProgress', file, progress);
|
|
|
}
|
|
|
@@ -544,12 +881,21 @@ function handleFileDelete(file) { // 移除文件
|
|
|
const $mainForm = ref(null)
|
|
|
const $mainFormRules = ref({})
|
|
|
const mainFormValue = ref({})
|
|
|
+const repeatingFormsValue = ref([])
|
|
|
const formatTypeDict = {
|
|
|
'0': 'string',
|
|
|
'1': 'number'
|
|
|
}
|
|
|
-function validateMainForm() {
|
|
|
-
|
|
|
+function computedMainFormValue() {
|
|
|
+ // 设置主表校验数据
|
|
|
+ mainFormValue.value = computed(() => {
|
|
|
+ const obj = {};
|
|
|
+ formElements.value.forEach(elem => {
|
|
|
+ if (!('0' != elem.canEdit && '8' != elem.type)) return
|
|
|
+ obj[elem.elementId] = elem.defaultValue;
|
|
|
+ });
|
|
|
+ return obj;
|
|
|
+ }).value
|
|
|
}
|
|
|
// 获取主表校验规则
|
|
|
function getMainFormRule() {
|
|
|
@@ -576,6 +922,33 @@ function getMainFormRule() {
|
|
|
return obj;
|
|
|
}).value
|
|
|
}
|
|
|
+function validateRepeatingForm2() {
|
|
|
+ // 设置重复表校验数据
|
|
|
+ repeatingFormsValue.value = repeatingForm.value.elements.map((item, index) => {
|
|
|
+ return computed(() => {
|
|
|
+ const obj = {};
|
|
|
+ item.forEach(({ name, defaultValue }) => {
|
|
|
+ obj[name] = defaultValue;
|
|
|
+ });
|
|
|
+ return obj;
|
|
|
+ }).value
|
|
|
+ })
|
|
|
+ let flag = false
|
|
|
+ repeatingFormsValue.value.forEach((item, index) => {
|
|
|
+ let ItemIndex = 0
|
|
|
+ for (const elem in item) {
|
|
|
+ if (item[elem] == '') {
|
|
|
+ const name = repeatingForm.value.elementItem[ItemIndex].elementName.slice(3)
|
|
|
+ $modal.msgError(`详情表 ${name} 数据填写错误`)
|
|
|
+ flag = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ ItemIndex++
|
|
|
+ }
|
|
|
+ flag = true
|
|
|
+ })
|
|
|
+ return flag
|
|
|
+}
|
|
|
const button_state = ref(true)
|
|
|
const remark = ref('')
|
|
|
function handleSubmitProcess(result) {
|
|
|
@@ -594,7 +967,13 @@ function handleSubmitProcess(result) {
|
|
|
});
|
|
|
return obj;
|
|
|
}).value
|
|
|
+ // 主表数据校验
|
|
|
$mainForm.value.validate().then(res => {
|
|
|
+ // 重复表数据校验
|
|
|
+ if (!validateRepeatingForm2()) {
|
|
|
+ button_state.value = true
|
|
|
+ return
|
|
|
+ }
|
|
|
submitProcess(result)
|
|
|
})
|
|
|
.catch(err => {
|
|
|
@@ -607,6 +986,7 @@ function handleSubmitProcess(result) {
|
|
|
}).catch(() => { })
|
|
|
}
|
|
|
function submitProcess(result) {
|
|
|
+ let flow = Object.assign({}, flowInfo.value)
|
|
|
formInfo.value.formElements = formElements.value
|
|
|
// 过滤不可编辑的表单项
|
|
|
.filter(({canEdit}) => canEdit == '1')
|
|
|
@@ -623,25 +1003,25 @@ function submitProcess(result) {
|
|
|
})
|
|
|
formInfo.value.formElements.push(...newItem)
|
|
|
})
|
|
|
- let flow = Object.assign({}, flowInfo.value)
|
|
|
flow['staffId'] = userStore.user.useId
|
|
|
flow['gxId'] = userStore.user.gxId
|
|
|
flow['groupId'] = flowInfo.value.groupid
|
|
|
- const seqs = subFileSeqs.value.map(({ seq }) => seq)
|
|
|
- if (processInfo.reqOffice == 1 && seqs.length == 0) {
|
|
|
- button_state.value = true
|
|
|
- $modal.msgError('请上传附件')
|
|
|
- return
|
|
|
- } else {
|
|
|
- flow['fileIds'] = seqs
|
|
|
- }
|
|
|
- if (processInfo.reqRemark == 1 && remark.value == '') {
|
|
|
- button_state.value = true
|
|
|
- $modal.msgError('请填写备注')
|
|
|
- return
|
|
|
- } else {
|
|
|
- flow['remark'] = remark.value
|
|
|
+ if (result == "1") {
|
|
|
+ const seqs = subFileSeqs.value.map(({ seq }) => seq)
|
|
|
+ if (processInfo.reqOffice == 1 && seqs.length == 0) {
|
|
|
+ button_state.value = true
|
|
|
+ $modal.msgError('请上传附件')
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ flow['fileIds'] = seqs
|
|
|
+ }
|
|
|
+ if (processInfo.reqRemark == 1 && remark.value == '') {
|
|
|
+ button_state.value = true
|
|
|
+ $modal.msgError('请填写备注')
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
+ flow['remark'] = remark.value
|
|
|
// result: 1通过 2退回发起人 0退回上一级
|
|
|
flow['result'] = result
|
|
|
flow['nextTmodelId'] = 'undefined'
|