Procházet zdrojové kódy

H5表单嵌套实现

songxy před 1 rokem
rodič
revize
64570c60cb

+ 54 - 14
client_h5/src/components/dateTimeRange.vue

@@ -3,7 +3,7 @@
     <van-field
       :label="label"
       :placeholder="placeholder"
-      v-model="dateTime"
+      v-model="currentDateTime"
       readonly 
       @touchstart="clickHandler"
     />
@@ -21,14 +21,13 @@
 </template>
 
 <script lang="ts" setup>
-
 defineOptions({
   name: 'DateTimeRange'
 })
 const props = defineProps<{
   label: string
   placeholder: string
-  modelValue: string[]
+  modelValue: string
 }>()
 const emit = defineEmits<{
   (e: 'update:modelValue', payload: any): void
@@ -39,19 +38,19 @@ const currentDay: number = new Date().getDay();
 const selectYear = ref<string>(currentYear.toString());
 const selectMonth = ref<string>(currentMonth.toString());
 
-const dateTime = ref<number>()
+const currentDateTime = ref<string>()
 const selectDateTime = ref<string[]>([])
-if(props.modelValue.length === 0){
-  selectDateTime.value = [currentYear.toString(), currentMonth.toString(), currentDay.toString()]
+if (props.modelValue) {
+  selectDateTime.value = formatDateTimeArr(props.modelValue);
 } else {
-  const newVal = props.modelValue
-  selectDateTime.value = [newVal[0], newVal[1], newVal[2], newVal[3], newVal[4]]
+  selectDateTime.value = [currentYear.toString(), currentMonth.toString(), currentDay.toString()]
 }
 watch(() => props.modelValue, (newVal) => {
-  selectDateTime.value = newVal
-  selectYear.value = newVal[0].toString()
-  selectMonth.value = newVal[1].toString()
-  setMonthByDay(newVal[0],newVal[1]);
+  const newArr = formatDateTimeArr(newVal);
+  selectDateTime.value = newArr
+  selectYear.value = newArr[0].toString()
+  selectMonth.value = newArr[1].toString()
+  setMonthByDay(newArr[0],newArr[1]);
 })
 /***
  * 固定统计年、月、时、分数据
@@ -68,7 +67,7 @@ const houseList = [];
 for (let i = 1; i <= 12; i++){
   houseList.push(fillZero(i));
 }
-const minuteList = ['0', '30']
+const minuteList = ['00', '30']
 
 const dateTimeRangeColumns = reactive([
     yearList.map(val => {
@@ -104,6 +103,41 @@ function fillZero(num: number): string {
   const num2 = Number(num);
   return num < 10 ? "0" + num2.toString() : num2.toString()
 }
+/***
+ * 格式化YYYY-MM-DD HH:MM:SS转成[yyy, mm, dd, hh, mm, dd]
+ */
+function formatDateTimeArr(dateTime: string): string[] {
+  if (!dateTime){
+    console.warn('formatDateTimeArr方法参数dateTime值不能为空!')
+    return []
+  }
+  const dateTimeArr = dateTime.split(' ');
+  if (dateTimeArr.length < 2) {
+    throw new Error('dateTime格式不正确! 请符合:YYYY-MM-DD HH:MM:SS');
+  }
+  const dateArr: string[] = dateTimeArr[0].split('-');
+  const timeArr: string[] = dateTimeArr[1].split(':');
+  return dateArr.concat(timeArr) as string[];
+}
+/**
+ * 格式化[yyy, mm, dd, hh, mm, dd]转成 YYYY-MM-DD HH:MM:SS
+ **/
+function formatDateTimeByArr(arr: string[]): string {
+  if (!arr || arr.length === 0) {
+    console.warn('formatDateTimeByArr方法参数arr值不能为空!')
+    return ''
+  }
+  const dateArr: string[] = []
+  arr[0] ? dateArr.push(arr[0]) : null
+  arr[1] ? dateArr.push(arr[1]) : null
+  arr[2] ? dateArr.push(arr[2]) : null
+
+  const timeArr: string[] = []
+  arr[3] ? timeArr.push(arr[3]) : null
+  arr[4] ? timeArr.push(arr[4]) : null
+  arr[5] ? timeArr.push(arr[5]) : null
+  return dateArr.join('-') +' ' + timeArr.join(':')
+}
 setMonthByDay(currentYear, currentMonth);
 const changeHandle = (val: any) => {
   const arr = val.selectedValues;
@@ -111,10 +145,16 @@ const changeHandle = (val: any) => {
     setMonthByDay(arr[0], arr[1]);
     selectYear.value = arr[0];
     selectMonth.value = arr[1];
+    const dateTimeStr:string = formatDateTimeByArr(arr);
+    currentDateTime.value = dateTimeStr
+    emit('update:modelValue', dateTimeStr)
   }
 }
 const confirmHandle = () => {
-  emit('update:modelValue', `${selectDateTime.value[0]}-${selectDateTime.value[1]}-${selectDateTime.value[2]} ${selectDateTime.value[3]}:${selectDateTime.value[4]}`)
+  const dateTimeStr:string = formatDateTimeByArr(selectDateTime.value);
+  currentDateTime.value = dateTimeStr
+  emit('update:modelValue', dateTimeStr)
+  popupShow.value = false;
 }
 const cancelHandle = () => {
   popupShow.value = false;

+ 283 - 0
client_h5/src/pages/leave/index copy 2.vue

@@ -0,0 +1,283 @@
+
+<template>
+  <flow-form :data="formData" @submit="submitNextActivity">
+        <card title="基础信息">
+          <van-form required="true">
+            <van-cell-group inset>
+              <van-field
+                v-model="formData.userNickname"
+                name="请假人"
+                label="请假人"
+                placeholder="请假人"
+                readonly 
+                :rules="[{ required: true, message: '未获取请假人' }]"
+              />
+              <van-field
+                v-model="formData.deptName"
+                name="所在部门"
+                label="所在部门"
+                placeholder="所在部门"
+                readonly 
+                :rules="[{ required: true, message: '未获取所在部门' }]"
+              />
+              <van-field
+                v-model="formData.createTime"
+                name="申请时间"
+                label="申请时间"
+                placeholder="申请时间"
+                readonly 
+                :rules="[{ required: true, message: '请填写申请时间' }]"
+              />
+              <van-field
+                v-model="formData.leaveType"
+                is-link
+                readonly
+                name="休假类型"
+                label="休假类型"
+                placeholder="点击选择休假类型"
+                :rules="[{ required: true, message: '请选择休假类型' }]"
+                @click="showPicker = true"
+              />
+              <van-popup v-model:show="showPicker" position="bottom">
+                <van-picker
+                  :columns="columns"
+                  @confirm="onConfirm"
+                  @cancel="showPicker = false"
+                />
+              </van-popup>
+              <van-field
+                v-model="formData.leaveDays"
+                name="休假天数"
+                label="休假天数"
+                placeholder="休假天数"
+                readonly
+                :rules="[{ required: true, message: '请填写休假天数' }]"
+              />
+              <van-field
+                v-model="formData.leaveReason"
+                name="请假原因"
+                label="请假原因"
+                placeholder="请假原因"
+                type="textarea"
+                rows="3"
+                autosize
+                :rules="[{ required: true, message: '请填写休假原因' }]"
+              />
+              <van-field
+                v-model="formData.leaveDays"
+                name="休假天数"
+                label="休假天数"
+                placeholder="休假天数"
+                readonly
+                :rules="[{ required: true, message: '请填写休假天数' }]"
+              />
+              <van-field
+                v-model="formData.leaveReason"
+                name="请假原因"
+                label="请假原因"
+                placeholder="请假原因"
+                type="textarea"
+                rows="3"
+                autosize
+                :rules="[{ required: true, message: '请填写休假原因' }]"
+              />
+            </van-cell-group>
+          </van-form>
+        </card>
+        <card title="详情信息">
+            <template #right>
+              <button class="add_btn" @click="popupShow = true">新增</button>
+            </template>
+            <template #default>
+              <van-cell-group inset>
+                <van-field
+                  v-model="formData.userNickname"
+                  name="请假人"
+                  label="请假人"
+                  placeholder="请假人"
+                  readonly 
+                  :rules="[{ required: true, message: '未获取请假人' }]"
+                />
+                <van-field
+                  v-model="formData.deptName"
+                  name="所在部门"
+                  label="所在部门"
+                  placeholder="所在部门"
+                  readonly 
+                  :rules="[{ required: true, message: '未获取所在部门' }]"
+                />
+                <van-field
+                  v-model="formData.createTime"
+                  name="申请时间"
+                  label="申请时间"
+                  placeholder="申请时间"
+                  readonly 
+                  :rules="[{ required: true, message: '请填写申请时间' }]"
+                />
+                <van-field
+                  v-model="formData.leaveType"
+                  is-link
+                  readonly
+                  name="休假类型"
+                  label="休假类型"
+                  placeholder="点击选择休假类型"
+                  :rules="[{ required: true, message: '请选择休假类型' }]"
+                  @click="showPicker = true"
+                />
+                <van-popup v-model:show="showPicker" position="bottom">
+                  <van-picker
+                    :columns="columns"
+                    @confirm="onConfirm"
+                    @cancel="showPicker = false"
+                  />
+                </van-popup>
+                <van-field
+                  v-model="formData.leaveDays"
+                  name="休假天数"
+                  label="休假天数"
+                  placeholder="休假天数"
+                  readonly
+                  :rules="[{ required: true, message: '请填写休假天数' }]"
+                />
+                <van-field
+                  v-model="formData.leaveReason"
+                  name="请假原因"
+                  label="请假原因"
+                  placeholder="请假原因"
+                  type="textarea"
+                  rows="3"
+                  autosize
+                  :rules="[{ required: true, message: '请填写休假原因' }]"
+                />
+                <van-field
+                  v-model="formData.leaveDays"
+                  name="休假天数"
+                  label="休假天数"
+                  placeholder="休假天数"
+                  readonly
+                  :rules="[{ required: true, message: '请填写休假天数' }]"
+                />
+                <van-field
+                  v-model="formData.leaveReason"
+                  name="请假原因"
+                  label="请假原因"
+                  placeholder="请假原因"
+                  type="textarea"
+                  rows="3"
+                  autosize
+                  :rules="[{ required: true, message: '请填写休假原因' }]"
+                />
+              </van-cell-group>
+            </template>
+        </card>
+  </flow-form>
+  <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
+    <h4 class="title">详细信息新增</h4>
+    <van-cell-group inset>
+      <date-time-range 
+        label="起始时间"
+        v-model="dateTimeRange"
+        placeholder="请选择起始时间"
+        />
+    </van-cell-group>
+    <div class="fixed-btn">
+      <van-button round block type="primary" @click="saveHandle">
+          保存
+       </van-button>
+    </div>
+  </van-popup>
+</template>
+
+<script setup lang="ts">
+import { useRoute } from 'vue-router';
+import { FlowDTO, getNextActivity } from '@/service/flow';
+import reqest from "@/utils/request";
+import DateTimeRange from '@/components/dateTimeRange.vue';
+import FlowForm from '@/components/flowForm.vue';
+import Card from '@/components/card.vue';
+
+const popupShow = ref<boolean>(false)
+const route = useRoute();
+const formData = ref({
+  instanceId: undefined,
+  id: undefined,
+  leaveHours: undefined,
+  userNickname: undefined,
+  deptName: undefined,
+  createTime: undefined,
+  leaveNo: undefined,
+  leaveType: undefined,
+  leaveDays: undefined,
+  leaveReason: undefined,
+  leaveTimeCreateList: [],
+})
+const dateTimeRange = ref("2025-10-02 10:30:00") 
+const showPicker = ref(false);
+const columns = [
+      { text: '事假', value: '11' },
+      { text: '病假', value: '12' },
+      { text: '婚假', value: '13' },
+      { text: '产假', value: '14' },
+      { text: '陪产假', value: '15' },
+      { text: '工伤', value: '16' },
+      { text: '年假', value: '17' },
+      { text: '调休', value: '18' },
+      { text: '其他', value: '20' },
+    ];
+const { activityInstanceId, participantId,flowInstanceId } = route.query as {
+  activityInstanceId: string;
+  participantId: string;
+  flowInstanceId: string;
+};
+const activityData: FlowDTO = {
+  activityInstanceId,
+  participantId,
+  flowOpinion: ''
+}
+const onConfirm = ({ selectedOptions }) => {
+  formData.leaveType = selectedOptions[0]?.text;
+  showPicker.value = false;
+};
+const submitNextActivity = async () => {
+  //更新表单业务数据
+  await reqest.post("/business/Leave/update",formData)
+  //工作流转件
+  activityData.activityInstanceId='018f23b914660a07729e8f224db60203'
+  activityData.participantId='018f23b9148b0a07729e8f224db60205'
+  activityData.flowOpinion='{"id":"018f23b914970a07729e8f224db60206","opinionContent":"同意","opinionTime":"2024-04-28"}'
+  const result = await getNextActivity(jsonToFormData(activityData))
+  // getNextActivity(activityData).then(result => {
+  //   console.log(result)
+  // }).catch((err) => {
+  //   console.error(err)
+  // })
+}
+const jsonToFormData = (json: any): FormData | null => {
+  const keys: string[] = Object.keys(json)
+  if (keys.length > 0) { 
+    const formData = new FormData();
+    keys.forEach((key) => { 
+      formData.append(key, (json[key] instanceof Object) ? JSON.stringify(json[key]) : json[key]);
+    });
+    return formData;
+  }
+  return null;
+}
+
+/** 初始化表单数据 */
+const initFormData= async () => {
+  const result = await reqest.get(`/business/Leave/mobileAdd?flowInstanceId=${flowInstanceId}`)
+  formData.value = result.data
+}
+const saveHandle = () => {
+  
+}
+/** 初始化 */
+onMounted(() => {
+  // initFormData()
+})
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 283 - 0
client_h5/src/pages/leave/index copy.vue

@@ -0,0 +1,283 @@
+
+<template>
+  <flow-form :data="formData" @submit="submitNextActivity">
+        <card title="基础信息">
+          <van-form required="true">
+            <van-cell-group inset>
+              <van-field
+                v-model="formData.userNickname"
+                name="请假人"
+                label="请假人"
+                placeholder="请假人"
+                readonly 
+                :rules="[{ required: true, message: '未获取请假人' }]"
+              />
+              <van-field
+                v-model="formData.deptName"
+                name="所在部门"
+                label="所在部门"
+                placeholder="所在部门"
+                readonly 
+                :rules="[{ required: true, message: '未获取所在部门' }]"
+              />
+              <van-field
+                v-model="formData.createTime"
+                name="申请时间"
+                label="申请时间"
+                placeholder="申请时间"
+                readonly 
+                :rules="[{ required: true, message: '请填写申请时间' }]"
+              />
+              <van-field
+                v-model="formData.leaveType"
+                is-link
+                readonly
+                name="休假类型"
+                label="休假类型"
+                placeholder="点击选择休假类型"
+                :rules="[{ required: true, message: '请选择休假类型' }]"
+                @click="showPicker = true"
+              />
+              <van-popup v-model:show="showPicker" position="bottom">
+                <van-picker
+                  :columns="columns"
+                  @confirm="onConfirm"
+                  @cancel="showPicker = false"
+                />
+              </van-popup>
+              <van-field
+                v-model="formData.leaveDays"
+                name="休假天数"
+                label="休假天数"
+                placeholder="休假天数"
+                readonly
+                :rules="[{ required: true, message: '请填写休假天数' }]"
+              />
+              <van-field
+                v-model="formData.leaveReason"
+                name="请假原因"
+                label="请假原因"
+                placeholder="请假原因"
+                type="textarea"
+                rows="3"
+                autosize
+                :rules="[{ required: true, message: '请填写休假原因' }]"
+              />
+              <van-field
+                v-model="formData.leaveDays"
+                name="休假天数"
+                label="休假天数"
+                placeholder="休假天数"
+                readonly
+                :rules="[{ required: true, message: '请填写休假天数' }]"
+              />
+              <van-field
+                v-model="formData.leaveReason"
+                name="请假原因"
+                label="请假原因"
+                placeholder="请假原因"
+                type="textarea"
+                rows="3"
+                autosize
+                :rules="[{ required: true, message: '请填写休假原因' }]"
+              />
+            </van-cell-group>
+          </van-form>
+        </card>
+        <card title="详情信息">
+            <template #right>
+              <button class="add_btn" @click="popupShow = true">新增</button>
+            </template>
+            <template #default>
+              <van-cell-group inset>
+                <van-field
+                  v-model="formData.userNickname"
+                  name="请假人"
+                  label="请假人"
+                  placeholder="请假人"
+                  readonly 
+                  :rules="[{ required: true, message: '未获取请假人' }]"
+                />
+                <van-field
+                  v-model="formData.deptName"
+                  name="所在部门"
+                  label="所在部门"
+                  placeholder="所在部门"
+                  readonly 
+                  :rules="[{ required: true, message: '未获取所在部门' }]"
+                />
+                <van-field
+                  v-model="formData.createTime"
+                  name="申请时间"
+                  label="申请时间"
+                  placeholder="申请时间"
+                  readonly 
+                  :rules="[{ required: true, message: '请填写申请时间' }]"
+                />
+                <van-field
+                  v-model="formData.leaveType"
+                  is-link
+                  readonly
+                  name="休假类型"
+                  label="休假类型"
+                  placeholder="点击选择休假类型"
+                  :rules="[{ required: true, message: '请选择休假类型' }]"
+                  @click="showPicker = true"
+                />
+                <van-popup v-model:show="showPicker" position="bottom">
+                  <van-picker
+                    :columns="columns"
+                    @confirm="onConfirm"
+                    @cancel="showPicker = false"
+                  />
+                </van-popup>
+                <van-field
+                  v-model="formData.leaveDays"
+                  name="休假天数"
+                  label="休假天数"
+                  placeholder="休假天数"
+                  readonly
+                  :rules="[{ required: true, message: '请填写休假天数' }]"
+                />
+                <van-field
+                  v-model="formData.leaveReason"
+                  name="请假原因"
+                  label="请假原因"
+                  placeholder="请假原因"
+                  type="textarea"
+                  rows="3"
+                  autosize
+                  :rules="[{ required: true, message: '请填写休假原因' }]"
+                />
+                <van-field
+                  v-model="formData.leaveDays"
+                  name="休假天数"
+                  label="休假天数"
+                  placeholder="休假天数"
+                  readonly
+                  :rules="[{ required: true, message: '请填写休假天数' }]"
+                />
+                <van-field
+                  v-model="formData.leaveReason"
+                  name="请假原因"
+                  label="请假原因"
+                  placeholder="请假原因"
+                  type="textarea"
+                  rows="3"
+                  autosize
+                  :rules="[{ required: true, message: '请填写休假原因' }]"
+                />
+              </van-cell-group>
+            </template>
+        </card>
+  </flow-form>
+  <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
+    <h4 class="title">详细信息新增</h4>
+    <van-cell-group inset>
+      <date-time-range 
+        label="起始时间"
+        v-model="dateTimeRange"
+        placeholder="请选择起始时间"
+        />
+    </van-cell-group>
+    <div class="fixed-btn">
+      <van-button round block type="primary" @click="saveHandle">
+          保存
+       </van-button>
+    </div>
+  </van-popup>
+</template>
+
+<script setup lang="ts">
+import { useRoute } from 'vue-router';
+import { FlowDTO, getNextActivity } from '@/service/flow';
+import reqest from "@/utils/request";
+import DateTimeRange from '@/components/dateTimeRange.vue';
+import FlowForm from '@/components/flowForm.vue';
+import Card from '@/components/card.vue';
+
+const popupShow = ref<boolean>(false)
+const route = useRoute();
+const formData = ref({
+  instanceId: undefined,
+  id: undefined,
+  leaveHours: undefined,
+  userNickname: undefined,
+  deptName: undefined,
+  createTime: undefined,
+  leaveNo: undefined,
+  leaveType: undefined,
+  leaveDays: undefined,
+  leaveReason: undefined,
+  leaveTimeCreateList: [],
+})
+const dateTimeRange = ref("2025-10-02 10:30:00") 
+const showPicker = ref(false);
+const columns = [
+      { text: '事假', value: '11' },
+      { text: '病假', value: '12' },
+      { text: '婚假', value: '13' },
+      { text: '产假', value: '14' },
+      { text: '陪产假', value: '15' },
+      { text: '工伤', value: '16' },
+      { text: '年假', value: '17' },
+      { text: '调休', value: '18' },
+      { text: '其他', value: '20' },
+    ];
+const { activityInstanceId, participantId,flowInstanceId } = route.query as {
+  activityInstanceId: string;
+  participantId: string;
+  flowInstanceId: string;
+};
+const activityData: FlowDTO = {
+  activityInstanceId,
+  participantId,
+  flowOpinion: ''
+}
+const onConfirm = ({ selectedOptions }) => {
+  formData.leaveType = selectedOptions[0]?.text;
+  showPicker.value = false;
+};
+const submitNextActivity = async () => {
+  //更新表单业务数据
+  await reqest.post("/business/Leave/update",formData)
+  //工作流转件
+  activityData.activityInstanceId='018f23b914660a07729e8f224db60203'
+  activityData.participantId='018f23b9148b0a07729e8f224db60205'
+  activityData.flowOpinion='{"id":"018f23b914970a07729e8f224db60206","opinionContent":"同意","opinionTime":"2024-04-28"}'
+  const result = await getNextActivity(jsonToFormData(activityData))
+  // getNextActivity(activityData).then(result => {
+  //   console.log(result)
+  // }).catch((err) => {
+  //   console.error(err)
+  // })
+}
+const jsonToFormData = (json: any): FormData | null => {
+  const keys: string[] = Object.keys(json)
+  if (keys.length > 0) { 
+    const formData = new FormData();
+    keys.forEach((key) => { 
+      formData.append(key, (json[key] instanceof Object) ? JSON.stringify(json[key]) : json[key]);
+    });
+    return formData;
+  }
+  return null;
+}
+
+/** 初始化表单数据 */
+const initFormData= async () => {
+  const result = await reqest.get(`/business/Leave/mobileAdd?flowInstanceId=${flowInstanceId}`)
+  formData.value = result.data
+}
+const saveHandle = () => {
+  
+}
+/** 初始化 */
+onMounted(() => {
+  // initFormData()
+})
+</script>
+
+<style lang="scss" scoped>
+@import "./index.scss";
+</style>

+ 1 - 1
client_h5/src/pages/leave/index.vue

@@ -211,7 +211,7 @@ const formData = ref({
   leaveReason: undefined,
   leaveTimeCreateList: [],
 })
-const dateTimeRange = ref(['2025', '02', '30', '09', '30']) 
+const dateTimeRange = ref("2025-10-02 10:30:00") 
 const showPicker = ref(false);
 const columns = [
       { text: '事假', value: '11' },