소스 검색

'时间选择组件封装'

songxy 1 년 전
부모
커밋
f25bc74ef1

+ 0 - 2
client_h5/index.html

@@ -4,8 +4,6 @@
     <meta charset="UTF-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1">
-    <script src="eruda.js"></script>
-    <script>eruda.init()</script>
     <title></title>
   </head>
   <body>

+ 1 - 0
client_h5/package.json

@@ -17,6 +17,7 @@
   "dependencies": {
     "axios": "^1.6.8",
     "dingtalk-jsapi": "^3.0.33",
+    "moment": "^2.30.1",
     "pinia": "^2.1.7",
     "vant": "^4.8.11",
     "vue": "^3.4.19",

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
client_h5/public/eruda.js


+ 4 - 1
client_h5/src/App.vue

@@ -55,10 +55,13 @@ const getUserInfoById = async (token: Required<string>) => {
 </script>
 
 <template>
-  <div>
+  <div class="app">
     <RouterView />
   </div>
 </template>
 
 <style scoped>
+.app {
+  height: 100%;
+}
 </style>

+ 49 - 0
client_h5/src/components/card.vue

@@ -0,0 +1,49 @@
+<template>
+  <div class="card_box">
+    <div class="card_header">
+      <h4 v-if="title">{{ title }}</h4>
+      <div class="right" v-if="$slots.right">
+        <slot name="right"></slot>
+      </div>
+    </div>
+    <div class="card_content">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+
+defineOptions({
+  name: 'Card'
+})
+
+const props = defineProps<{
+  title: string
+}>();
+
+</script>
+
+<style scoped lang="scss">
+.card_box {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  padding: 15px;
+  background-color: #f7f8fa;
+  >.card_header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0px 0px 15px 0px;
+    >h4 {
+      margin: 0px;
+      color: var(--van-doc-text-color-4);
+      font-weight: 400;
+      font-size: 15px;
+      line-height: 16px;
+      font-weight: bold;
+    }
+  }
+}
+</style>

+ 133 - 0
client_h5/src/components/dateTimeRange.vue

@@ -0,0 +1,133 @@
+<template>
+  <div class="dateTimeRangeBox">
+    <van-field
+      :label="label"
+      :placeholder="placeholder"
+      v-model="dateTime"
+      readonly 
+      @touchstart="clickHandler"
+    />
+    <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
+      <van-picker 
+      v-model="selectDateTime" 
+      title="时间选择" 
+      :columns="dateTimeRangeColumns"
+       @change="changeHandle"
+       @confirm="confirmHandle"
+       @cancel="cancelHandle"
+       />
+    </van-popup>
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+defineOptions({
+  name: 'DateTimeRange'
+})
+const props = defineProps<{
+  label: string
+  placeholder: string
+  modelValue: string[]
+}>()
+const emit = defineEmits<{
+  (e: 'update:modelValue', payload: any): void
+}>()
+const currentYear: number = new Date().getFullYear();
+const currentMonth: number = new Date().getMonth()+1;
+const currentDay: number = new Date().getDay();
+const selectYear = ref<string>(currentYear.toString());
+const selectMonth = ref<string>(currentMonth.toString());
+
+const dateTime = ref<number>()
+const selectDateTime = ref<string[]>([])
+if(props.modelValue.length === 0){
+  selectDateTime.value = [currentYear.toString(), currentMonth.toString(), currentDay.toString()]
+} else {
+  const newVal = props.modelValue
+  selectDateTime.value = [newVal[0], newVal[1], newVal[2], newVal[3], newVal[4]]
+}
+watch(() => props.modelValue, (newVal) => {
+  selectDateTime.value = newVal
+  selectYear.value = newVal[0].toString()
+  selectMonth.value = newVal[1].toString()
+  setMonthByDay(newVal[0],newVal[1]);
+})
+/***
+ * 固定统计年、月、时、分数据
+ */
+const yearList: string[] = []
+const monthList: string[] = []
+for (let i = 2012; i < currentYear + 5; i++){
+  yearList.push(i.toString())
+}
+for (let i = 1; i <= 12; i++){
+  monthList.push(fillZero(i));
+}
+const houseList = [];
+for (let i = 1; i <= 12; i++){
+  houseList.push(fillZero(i));
+}
+const minuteList = ['0', '30']
+
+const dateTimeRangeColumns = reactive([
+    yearList.map(val => {
+      return {text: val, value: val}
+    }),
+    monthList.map(val => {
+      return {text: val, value: val}
+    }),
+    [],
+    houseList.map(val => {
+      return {text: val, value: val}
+    }),
+    minuteList.map(val => {
+      return {text: val, value: val}
+    }),
+]);
+/***
+ * 日单独处理,每个月日期不一样
+ */
+function getDaysInMonth(year: number|string, month: number|string) {
+  return new Date(year as number, month as number, 0).getDate();
+}
+function setMonthByDay(year: number|string, month: number|string) { 
+  const day = getDaysInMonth(year, month);
+  const dayList: any[] = [];
+  for (let i = 1; i <= day; i++){
+    const val = fillZero(i);
+    dayList.push({text: val, value: val});
+  }
+  dateTimeRangeColumns[2] = dayList;
+}
+function fillZero(num: number): string {
+  const num2 = Number(num);
+  return num < 10 ? "0" + num2.toString() : num2.toString()
+}
+setMonthByDay(currentYear, currentMonth);
+const changeHandle = (val: any) => {
+  const arr = val.selectedValues;
+  if (selectYear.value !== arr[0] || selectMonth.value !== arr[1]) {
+    setMonthByDay(arr[0], arr[1]);
+    selectYear.value = arr[0];
+    selectMonth.value = arr[1];
+  }
+}
+const confirmHandle = () => {
+  emit('update:modelValue', `${selectDateTime.value[0]}-${selectDateTime.value[1]}-${selectDateTime.value[2]} ${selectDateTime.value[3]}:${selectDateTime.value[4]}`)
+}
+const cancelHandle = () => {
+  popupShow.value = false;
+}
+const popupShow = ref<boolean>(false)
+const clickHandler = () => {
+  const time = setTimeout(() => { 
+    popupShow.value = !popupShow.value
+    clearTimeout(time)
+  }, 200)
+}
+</script>
+
+<style lang="scope" scoped>
+
+</style>

+ 67 - 0
client_h5/src/components/flowForm.vue

@@ -0,0 +1,67 @@
+<template>
+  <div class="flow_form_box">
+    <div class="flow_container">
+      <template v-if="tabs.length !== 0">
+        <van-tabs v-model:active="currentActive" :sticky="true">
+          <van-tab title="基础信息">
+            <slot></slot>
+          </van-tab>
+          <van-tab title="审批意见">审批意见</van-tab>
+        </van-tabs>
+      </template>
+      <template v-else>
+        <slot></slot>
+      </template>
+    </div>
+    <div class="fixed-btn">
+      <van-button round block type="primary" @click="submitHandle">
+          转件
+        </van-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getOpinionListByFlowInstanceId } from '@/service/flow';
+
+defineOptions({
+  name: 'FlowForm'
+})
+
+const props = defineProps<{
+  data: any
+}>();
+const emit = defineEmits<{
+  (e: 'submit', payload: any):void
+}>()
+const route = useRoute();
+const tabs = ref<{
+  title: string
+}[]>([{}])
+const currentActive = ref<string>('基础信息')
+const { flowInstanceId } = route.query as {
+  flowInstanceId: string
+}
+getOpinionListByFlowInstanceId(flowInstanceId).then((result) => {
+  tabs.value = result?.data;
+})
+const submitHandle = () => {
+  emit('submit')
+}
+</script>
+
+<style scoped lang="scss">
+.flow_form_box {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  >.flow_container {
+    flex-grow: 1;
+    height: 0px;
+    overflow-y: scroll;
+  }
+  >.fixed-btn {
+    padding: 10px 20px;
+  }
+}
+</style>

+ 24 - 0
client_h5/src/pages/leave/index.scss

@@ -0,0 +1,24 @@
+.van-cell-group {
+  margin: 0px;
+}
+.van-overlay {
+  background: rgba(0,0,0,0.3);
+}
+.add_btn {
+  background-color: #1989fa;
+  padding: 5px 10px;
+  border: 0px;
+  outline: none;
+  font-size: 13px;
+  color: #fff;
+  border-radius: 2px;
+}
+.detail-popup {
+  >.title {
+    font-size: 15px;
+    padding-left: 10px;
+  }
+  >.fixed-btn {
+    padding: 15px;
+  }
+}

+ 192 - 69
client_h5/src/pages/leave/index.vue

@@ -1,82 +1,202 @@
 
 <template>
-  <van-form @submit="submitNextActivity" required="true">
+  <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>
-      <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"
+      <date-time-range 
+        label="起始时间"
+        v-model="dateTimeRange"
+        placeholder="请选择起始时间"
         />
-      </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-cell-group>
-    <div style="margin: 16px;">
-      <van-button round block type="primary" native-type="submit">
-        转件
-      </van-button>
+    <div class="fixed-btn">
+      <van-button round block type="primary" @click="saveHandle">
+          保存
+       </van-button>
     </div>
-  </van-form>
+  </van-popup>
 </template>
 
 <script setup lang="ts">
-import { onMounted } from  'vue'
 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,
@@ -89,8 +209,9 @@ const formData = ref({
   leaveType: undefined,
   leaveDays: undefined,
   leaveReason: undefined,
-  leaveTimeCreateList: []
+  leaveTimeCreateList: [],
 })
+const dateTimeRange = ref(['2025', '02', '30', '09', '30']) 
 const showPicker = ref(false);
 const columns = [
       { text: '事假', value: '11' },
@@ -148,10 +269,12 @@ const initFormData= async () => {
   const result = await reqest.get(`/business/Leave/mobileAdd?flowInstanceId=${flowInstanceId}`)
   formData.value = result.data
 }
-
+const saveHandle = () => {
+  
+}
 /** 初始化 */
 onMounted(() => {
-  initFormData()
+  // initFormData()
 })
 </script>
 

+ 2 - 1
client_h5/src/style.css

@@ -1,5 +1,6 @@
-html,body {
+html,body,#app {
   margin: 0px;
+  height: 100%;
 }
 ul,li {
   margin: 0px;

+ 5 - 0
client_h5/vite.config.ts

@@ -22,5 +22,10 @@ export default defineConfig({
       }
     ]
   },
+  // 服务端渲染
+  server: {
+    // 端口号
+    host: "0.0.0.0",
+  },
   plugins: createVitePlugins(),
 })

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.