Procházet zdrojové kódy

流程意见功能优化

songxy před 1 rokem
rodič
revize
bdec8e12ae

+ 4 - 2
client/src/views/OaSystem/home/components/CardItemThree.vue

@@ -87,7 +87,9 @@ queryContractInfo()
         color: #626b70;
         white-space: nowrap;
       }
-
+      > div {
+        width: 120px;
+      }
       &:nth-child(2n + 1) {
         margin-right: 15px;
       }
@@ -100,7 +102,7 @@ queryContractInfo()
         display: block;
         width: 36px;
         height: 36px;
-        margin-right: 15px;
+        margin-right: 10px;
         font-size: 16px;
         line-height: 36px;
         color: #fff;

+ 1 - 1
client/src/views/OaSystem/marketCenter/contractSubOut/signIndex.vue

@@ -169,7 +169,7 @@ const searchHandle: () => void = () => {
   queryProjectListAjax()
 }
 const queryProjectListAjax = async (): Promise<void> => {
-  const urlApi = `/contract-apply/page`
+  const urlApi = `/contractSub/page`
   const sendData: {
     applyType: number | null
   } = {

+ 1 - 1
client_h5/.env.dev

@@ -1,3 +1,3 @@
-VITE_BASE_URL='http://localhost:6090/'
+VITE_BASE_URL='http://10.10.10.7:48080/'
 
 VITE_AUTHORIZATION='test83e06d0d-af60-4419-9437-c9a68bf1b669'

+ 142 - 10
client_h5/src/components/flowForm.vue

@@ -6,7 +6,65 @@
           <van-tab title="基础信息">
             <slot></slot>
           </van-tab>
-          <van-tab title="审批意见">审批意见</van-tab>
+          <van-tab title="审批意见">
+            <div class="flowOpinionBox">
+              <template  v-for="(tItem,tIndex) in templateOpinions">
+                <template v-if="tItem['opinions'].length > 0">
+                  <div v-for="(item,index) in tItem['opinions']" :key="tIndex-index" :class="{'flowOpinionItem': true, 'disabled': !item['isEditor']}">
+                    <h4>{{ tItem['opinionName'] }}</h4>
+                    <div class="content">
+                      <van-field
+                        v-model="currentOpinion.opinionContent"
+                        rows="3"
+                        autosize
+                        label=""
+                        type="textarea"
+                        :disabled="!item['isEditor']"
+                        maxlength="50"
+                        placeholder="请输入留言"
+                      />
+                    </div>
+                    <div class="footer">
+                      <p>
+                        <span>办理人:</span>
+                        <span>{{item['sign'] ?? currentUserName}}</span>
+                      </p>
+                      <p>
+                        <span>办理时间:</span>
+                        <span>{{currentOpinion['opinionTime']}}</span>
+                      </p>
+                    </div>
+                  </div>
+                </template>
+                <template v-else>
+                  <div class="flowOpinionItem" :key="tIndex">
+                    <h4>{{ tItem['opinionName'] }}</h4>
+                    <div class="content">
+                      <van-field
+                        rows="3"
+                        autosize
+                        label=""
+                        type="textarea"
+                        :disabled="true"
+                        maxlength="50"
+                        placeholder="请输入留言"
+                      />
+                    </div>
+                    <div class="footer">
+                      <p>
+                        <span>办理人:</span>
+                        <span></span>
+                      </p>
+                      <p>
+                        <span>办理时间:</span>
+                        <span></span>
+                      </p>
+                    </div>
+                  </div>
+                </template>
+              </template>
+            </div>
+          </van-tab>
         </van-tabs>
       </template>
       <template v-else>
@@ -16,38 +74,75 @@
     <div class="fixed-btn">
       <van-button round block type="primary" @click="submitHandle">
           转件
-        </van-button>
+      </van-button>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { getOpinionListByFlowInstanceId } from '@/service/flow';
+import { formatDate } from "@/utils/common";
+import { getTemplateOpinionListByFlowInstanceId, getOpinionListByFlowInstanceId } from '@/service/flow';
 
 defineOptions({
   name: 'FlowForm'
 })
-
-const props = defineProps<{
+const userInfo = JSON.parse(localStorage.getItem('_userInfo') as string);
+const currentUserName = userInfo ? userInfo['nickname'] ?? '' : ''
+defineProps<{
   data: any
 }>();
 const emit = defineEmits<{
-  (e: 'submit', payload: any):void
+  (e: 'submit', payload?: any):void
 }>()
 const route = useRoute();
 const tabs = ref<{
   title: string
 }[]>([{}])
 const currentActive = ref<string>('基础信息')
-const { flowInstanceId } = route.query as {
+const { flowInstanceId, activityInstanceId } = route.query as {
   flowInstanceId: string
+  activityInstanceId: string
 }
-getOpinionListByFlowInstanceId(flowInstanceId).then((result) => {
-  tabs.value = result?.data;
+const currentOpinion = ref({
+  id: '',
+  opinionContent: '',
+  opinionTime: '',
+  sign: null
+})
+const templateOpinions = ref<any[]>([]);
+getTemplateOpinionListByFlowInstanceId(flowInstanceId).then((tResult) => {
+  const tList = tResult.data ?? []
+  getOpinionListByFlowInstanceId(flowInstanceId).then((oResult) => {
+    const oList = oResult.data ?? []
+    if (oList.length > 0) { 
+      tList.forEach((tItem: any) => {
+        tItem['opinions'] = []
+        for (let i = 0; i < oList.length; i++) { 
+          const oItem = oList[i]
+          if (tItem['id'] === oItem['flowOpinionId']) {
+            if (oItem['activityInstanceId'] === activityInstanceId) {
+              oItem['isEditor'] = true;
+              currentOpinion.value.id = oItem['id']
+              currentOpinion.value.opinionContent = oItem['opinionContent']
+              currentOpinion.value.opinionTime = formatDate(new Date())
+              if (oItem['sign']) {
+                currentOpinion.value.sign = oItem['sign']
+              }
+            }
+            tItem['opinions'].push(oItem);
+            oList.splice(i, 1)
+            i--;
+          }
+        }
+      })
+    }
+    templateOpinions.value = tList
+  })
 })
 const submitHandle = () => {
-  emit('submit')
+  emit('submit', currentOpinion.value);
 }
+
 </script>
 
 <style scoped lang="scss">
@@ -55,6 +150,7 @@ const submitHandle = () => {
   height: 100%;
   display: flex;
   flex-direction: column;
+  background-color: #f7f8fa;
   >.flow_container {
     flex-grow: 1;
     height: 0px;
@@ -63,5 +159,41 @@ const submitHandle = () => {
   >.fixed-btn {
     padding: 10px 20px;
   }
+  .flowOpinionBox {
+    margin: 10px;
+    >.flowOpinionItem {
+      margin-bottom: 15px;
+      background-color: #fff;
+      padding: 10px 0px;
+      >h4 {
+        font-size: 17px;
+        margin: 0px;
+        padding: 0px 16px;
+      }
+      >.content {
+        :deep(.van-field__value) {
+          border: 1px solid #ececec;
+          border-radius: 5px;
+          padding: 10px
+        }
+      }
+      >.footer {
+        display: flex;
+        padding: 0px 16px;
+        >p {
+          margin: 0px;
+          flex: 1;
+          white-space: nowrap;
+          >span {
+            color: #333;
+            &:first-child {
+              display: inline-block;
+              margin-right: 5px;
+            }
+          }
+        }
+      }
+    }
+  }
 }
 </style>

+ 7 - 6
client_h5/src/pages/home/index.scss

@@ -29,11 +29,9 @@
         }
       }
       >ul {
-        display: flex;
-        align-items: center;
-        justify-content: center;
         >li {
-          flex: 1;
+          display: inline-block;
+          width: 25%;
           text-align: center;
           position: relative;
           >.corner {
@@ -117,8 +115,11 @@
             text-align: center;
             position: relative;
             background: rgba(255,255,255,0.5);
-            border-radius: 12px 12px 12px 12px;
-            padding: 15px 12px;
+            border-radius: 8px;
+            padding: 12px 8px;
+            &:not(:first-child) {
+              margin-left: 10px;
+            }
             >img {
               display: block;
               margin: auto;

+ 10 - 16
client_h5/src/pages/home/index.vue

@@ -14,25 +14,26 @@ interface MenuItem {
 const navMenus: MenuItem[] = [
   {
     title: "办件中心",
-    corner: 0,
+    corner: 1,
     path: "http://10.10.10.7:18080/workflow/HandlerCaseCenter/mobileIndex",
     icon: "../assets/images/bjzx_icon.png",
   },
   {
     title: "日志填写",
-    corner: 0,
     icon: "../assets/images/rztx_icon.png",
     path: "daily",
   },
+  {
+    title: "周报填写",
+    icon: "../assets/images/wdxx_icon.png",
+  },
   {
     title: "我的日志",
-    corner: 0,
     icon: "../assets/images/wdrz_icon.png",
   },
   {
-    title: "我的消息",
-    corner: 0,
-    icon: "../assets/images/wdxx_icon.png",
+    title: "我的周报",
+    icon: "../assets/images/wdrz_icon.png",
   },
 ];
 interface ProcessMenuItem extends MenuItem { 
@@ -68,22 +69,15 @@ const processMenus: ProcessMenuItem[] = [
 const personMenus: MenuItem[] = [
   {
     title: "我的考勤",
-    corner: 0,
     icon: "../assets/images/wdkq_icon.png",
   },
   {
     title: "我的资产",
-    corner: 0,
     icon: "../assets/images/wdzc_icon.png",
   },
-  {
-    title: "学习中心",
-    corner: 0,
-    icon: "../assets/images/xxzx_icon.png",
-  },
   {
     title: "通知公告",
-    corner: 0,
+    corner: 1,
     icon: "../assets/images/tzgg_icon.png",
   },
 ];
@@ -116,7 +110,7 @@ const toProcessHandle = (item: ProcessMenuItem): void => {
         >
           <img :src="getAssetsURI(item['icon'])" />
           <p class="title">{{ item["title"] }}</p>
-          <span class="corner">{{ item["corner"] }}</span>
+          <span class="corner" v-if="item['corner']">{{ item["corner"] }}</span>
         </li>
       </ul>
     </div>
@@ -136,7 +130,7 @@ const toProcessHandle = (item: ProcessMenuItem): void => {
           <li v-for="(item, index) in personMenus" :key="index">
             <img :src="getAssetsURI(item['icon'])" />
             <span class="title">{{ item["title"] }}</span>
-            <span class="corner">{{ item["corner"] }}</span>
+            <span class="corner" v-if="item['corner']">{{ item["corner"] }}</span>
           </li>
         </ul>
       </div>

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

@@ -205,7 +205,8 @@ const onConfirm = ({ selectedOptions }) => {
   formData.value.leaveType = selectedOptions[0]?.value;
   showPicker.value = false;
 };
-const submitNextActivity = async () => {
+const submitNextActivity = async (activeOpinion: any) => {
+  console.log(JSON.stringify(activeOpinion))  //获取意见
   formData.value.leaveTimeCreateList.forEach((x:any) => {
     x.startTime = Date.parse(x.startTime)
     x.endTime = Date.parse(x.endTime)

+ 31 - 0
client_h5/src/utils/common.ts

@@ -34,4 +34,35 @@ export const jsonToFormData = (json: any): FormData | null => {
     });
   }
   return formData;
+}
+/**
+ * 补零函数:将小于10的数补零并返回字符串
+ * @param num number
+ * @return string
+ */
+const zeroFillToString = (num: number): string => {
+  return num < 10? '0' + num : num.toString();
+}
+/**
+ * 格式化日期
+ */
+export const formatDate = (date: Date) => {
+  if(!(date instanceof Date)) throw new Error('date不是Date类型')
+  const year = date.getFullYear()
+  const month = date.getMonth() + 1
+  const day = date.getDate();
+  return `${year}-${zeroFillToString(month)}-${zeroFillToString(day)} `;
+}
+/**
+ * 格式化时间
+ */
+export const formatDateTime = (date: Date) => {
+  if(!(date instanceof Date)) throw new Error('date不是Date类型')
+  const year = date.getFullYear()
+  const month = date.getMonth() + 1
+  const day = date.getDate();
+  const hours = date.getHours();
+  const minute = date.getMinutes()
+  const second = date.getSeconds()
+  return `${year}-${zeroFillToString(month)}-${zeroFillToString(day)} ${zeroFillToString(hours)}:${zeroFillToString(minute)}:${zeroFillToString(second)}`;
 }

+ 1 - 0
zjugis-framework/zjugis-spring-boot-starter-workflow/src/main/java/com/zjugis/framework/workflow/utils/Constant.java

@@ -48,6 +48,7 @@ public class Constant {
 	}
 
 	public static String getUserId() {
+//	    return "dc794fe0-66fe-4b1d-9273-f747950b27c3";
         return SecurityFrameworkUtils.getLoginUserId();
 	}
 }