Преглед изворни кода

Merge branch 'ruiheng' of shuzhihua/pms-app into master

yanghao пре 3 недеља
родитељ
комит
219ea803cc
4 измењених фајлова са 239 додато и 153 уклоњено
  1. 163 143
      pages/entry/index.vue
  2. 40 7
      pages/recordFilling/detail.vue
  3. 35 2
      pages/ruihen/components/form.vue
  4. 1 1
      pages/ruihen/edit.vue

+ 163 - 143
pages/entry/index.vue

@@ -1,169 +1,173 @@
 <template>
   <view class="entry-root">
     <scroll-view class="entry-page" scroll-y>
-    <view class="hero">
-      <image class="hero-bg" src="/static/entry/bg.png" mode="widthFix" />
-      <view class="hero-mask"></view>
-      <view class="hero-content">
-        <view class="status-row"></view>
-
-        <view class="profile-row">
-          <view class="avatar-wrap">
-            <image
-              style="
-                width: 50px;
-                height: 50px;
-                background-color: transparent;
-                border-radius: 50%;
-              "
-              :src="
-                userInfo?.avatar ? userInfo?.avatar : '/static/user/avatar.png'
-              "
-            ></image>
-          </view>
-          <view class="profile-main">
-            <view class="greeting">{{ greetingText }},{{ displayName }}</view>
-          </view>
-          <view
-            class="notice-wrap"
-            @click="navigatorTo('/pages/message/index')"
-          >
-            <uni-badge :text="messageCount" absolute="rightTop" size="small">
-              <view class="notice-button">
-                <image
-                  src="~@/static/home/message.png"
-                  style="
-                    width: 15px;
-                    height: 15px;
-                    background-color: transparent;
-                  "
-                  @click="navigatorTo('/pages/message/index')"
-                />
-              </view>
-            </uni-badge>
+      <view class="hero">
+        <image class="hero-bg" src="/static/entry/bg.png" mode="widthFix" />
+        <view class="hero-mask"></view>
+        <view class="hero-content">
+          <view class="status-row"></view>
+
+          <view class="profile-row">
+            <view class="avatar-wrap">
+              <image
+                style="
+                  width: 50px;
+                  height: 50px;
+                  background-color: transparent;
+                  border-radius: 50%;
+                "
+                :src="
+                  userInfo?.avatar
+                    ? userInfo?.avatar
+                    : '/static/user/avatar.png'
+                "
+              ></image>
+            </view>
+            <view class="profile-main">
+              <view class="greeting"
+                >{{ greetingText }},{{ displayName }}</view
+              >
+            </view>
+            <view
+              class="notice-wrap"
+              @click="navigatorTo('/pages/message/index')"
+            >
+              <uni-badge :text="messageCount" absolute="rightTop" size="small">
+                <view class="notice-button">
+                  <image
+                    src="~@/static/home/message.png"
+                    style="
+                      width: 15px;
+                      height: 15px;
+                      background-color: transparent;
+                    "
+                    @click="navigatorTo('/pages/message/index')"
+                  />
+                </view>
+              </uni-badge>
+            </view>
           </view>
         </view>
       </view>
-    </view>
-
-    <view class="content-shell">
-      <view class="hero-title">工作台</view>
-      <view class="section-card">
-        <view class="section-title">核心功能</view>
-        <scroll-view class="core-scroll" scroll-x show-scrollbar="false">
-          <view class="core-list">
+
+      <view class="content-shell">
+        <view class="hero-title">工作台</view>
+        <view class="section-card">
+          <view class="section-title">核心功能</view>
+          <scroll-view class="core-scroll" scroll-x show-scrollbar="false">
+            <view class="core-list">
+              <view
+                v-for="item in coreFeatures"
+                :key="item.title"
+                class="core-item"
+                :class="{ active: item.active }"
+                @click="handleCoreFeatureClick(item)"
+              >
+                <view class="core-icon">
+                  <image
+                    :src="item.iconText"
+                    mode="aspectFit"
+                    style="
+                      width: 40px;
+                      height: 40px;
+                      background-color: transparent;
+                    "
+                  />
+                </view>
+                <view class="core-name">{{ item.title }}</view>
+                <view class="core-desc">{{ item.desc }}</view>
+                <view class="core-indicator" v-if="item.active"></view>
+              </view>
+            </view>
+          </scroll-view>
+        </view>
+
+        <view class="section-card">
+          <view class="section-title">PMS常用</view>
+          <view class="tool-grid">
             <view
-              v-for="item in coreFeatures"
+              v-for="item in commonTools"
               :key="item.title"
-              class="core-item"
-              :class="{ active: item.active }"
-              @click="handleCoreFeatureClick(item)"
+              class="tool-item"
+              @click="navigatorTo(item.path)"
             >
-              <view class="core-icon">
-                <image
-                  :src="item.iconText"
-                  mode="aspectFit"
-                  style="
-                    width: 40px;
-                    height: 40px;
-                    background-color: transparent;
-                  "
-                />
-              </view>
-              <view class="core-name">{{ item.title }}</view>
-              <view class="core-desc">{{ item.desc }}</view>
-              <view class="core-indicator" v-if="item.active"></view>
+              <image class="tool-icon" :src="item.icon" mode="aspectFit" />
+              <view class="tool-title">{{ item.title }}</view>
             </view>
           </view>
-        </scroll-view>
-      </view>
-
-      <view class="section-card">
-        <view class="section-title">PMS常用</view>
-        <view class="tool-grid">
-          <view
-            v-for="item in commonTools"
-            :key="item.title"
-            class="tool-item"
-            @click="navigatorTo(item.path)"
-          >
-            <image class="tool-icon" :src="item.icon" mode="aspectFit" />
-            <view class="tool-title">{{ item.title }}</view>
-          </view>
         </view>
-      </view>
 
-      <view class="section-card">
-        <view class="section-head">
-          <view class="section-title">日报入口</view>
-          <view class="section-tip">
-            <uni-icons type="personadd" size="16" color="#246BFF" />
-            <text>按角色显示</text>
+        <view class="section-card">
+          <view class="section-head">
+            <view class="section-title">日报入口</view>
+            <view class="section-tip">
+              <uni-icons type="personadd" size="16" color="#246BFF" />
+              <text>按角色显示</text>
+            </view>
           </view>
-        </view>
-        <view class="daily-list">
-          <view
-            v-if="!!userInfo.rhReportFlag"
-            class="daily-item"
-            @click="navigatorTo('/pages/ruihen/index?type=edit')"
-          >
-            <image
-              class="daily-icon"
-              src="/static/entry/ruiheng.png"
-              mode="aspectFit"
-            />
-            <view class="daily-content">
-              <view class="daily-title">瑞恒日报</view>
-
-              <view class="daily-subtitle-wrap">
-                <view class="daily-subtitle">进入瑞恒日报</view>
-                <uni-icons type="right" size="12" color="#8090a8" />
+          <view class="daily-list">
+            <view
+              v-if="!!userInfo.rhReportFlag"
+              class="daily-item"
+              @click="navigatorTo('/pages/ruihen/index?type=edit')"
+            >
+              <image
+                class="daily-icon"
+                src="/static/entry/ruiheng.png"
+                mode="aspectFit"
+              />
+              <view class="daily-content">
+                <view class="daily-title">瑞恒日报</view>
+
+                <view class="daily-subtitle-wrap">
+                  <view class="daily-subtitle">进入瑞恒日报</view>
+                  <uni-icons type="right" size="12" color="#8090a8" />
+                </view>
               </view>
             </view>
-          </view>
 
-          <view
-            class="daily-item"
-            v-if="!!userInfo.rdReportFlag"
-            @click="navigatorTo('/pages/ruiDu/index')"
-          >
-            <image
-              class="daily-icon"
-              src="/static/entry/ruidu.png"
-              mode="aspectFit"
-            />
-            <view class="daily-content">
-              <view class="daily-title">瑞都日报</view>
-
-              <view class="daily-subtitle-wrap">
-                <view class="daily-subtitle">进入瑞都日报</view>
-                <uni-icons type="right" size="12" color="#8090a8" />
+            <view
+              class="daily-item"
+              v-if="!!userInfo.rdReportFlag"
+              @click="navigatorTo('/pages/ruiDu/index')"
+            >
+              <image
+                class="daily-icon"
+                src="/static/entry/ruidu.png"
+                mode="aspectFit"
+              />
+              <view class="daily-content">
+                <view class="daily-title">瑞都日报</view>
+
+                <view class="daily-subtitle-wrap">
+                  <view class="daily-subtitle">进入瑞都日报</view>
+                  <uni-icons type="right" size="12" color="#8090a8" />
+                </view>
               </view>
             </view>
-          </view>
 
-          <view
-            class="daily-item"
-            v-if="!!userInfo.ryReportFlag"
-            @click="navigatorTo('/pages/ruiying/index?type=edit')"
-          >
-            <image
-              class="daily-icon"
-              src="/static/entry/ruiying.png"
-              mode="aspectFit"
-            />
-            <view class="daily-content">
-              <view class="daily-title">瑞鹰日报</view>
-
-              <view class="daily-subtitle-wrap">
-                <view class="daily-subtitle">进入瑞鹰日报</view>
-                <uni-icons type="right" size="12" color="#8090a8" />
+            <view
+              class="daily-item"
+              v-if="!!userInfo.ryReportFlag"
+              @click="navigatorTo('/pages/ruiying/index?type=edit')"
+            >
+              <image
+                class="daily-icon"
+                src="/static/entry/ruiying.png"
+                mode="aspectFit"
+              />
+              <view class="daily-content">
+                <view class="daily-title">瑞鹰日报</view>
+
+                <view class="daily-subtitle-wrap">
+                  <view class="daily-subtitle">进入瑞鹰日报</view>
+                  <uni-icons type="right" size="12" color="#8090a8" />
+                </view>
               </view>
             </view>
           </view>
         </view>
       </view>
-    </view>
     </scroll-view>
     <uni-popup
       ref="operationMeetingPopup"
@@ -194,8 +198,8 @@
 </template>
 
 <script setup>
-import { computed, ref } from "vue";
-import { onShow } from "@dcloudio/uni-app";
+import { computed, ref, nextTick } from "vue";
+import { onShow, onLoad } from "@dcloudio/uni-app";
 import dayjs from "dayjs";
 import { getLoginUserInfo } from "@/api/login";
 import { getUnreadMessageCount } from "@/api/message";
@@ -204,6 +208,7 @@ import { getUserInfo } from "@/utils/auth";
 
 const userInfo = ref({});
 const messageCount = ref(0);
+let source = ref("");
 const todoStats = ref({
   maintenance: 0,
   fault: 0,
@@ -442,6 +447,10 @@ const navigatorTo = (url) => {
 };
 
 const operationMeetingPopup = ref(null);
+const openOperationMeetingPopup = async () => {
+  await nextTick();
+  operationMeetingPopup.value?.open();
+};
 
 const handleCoreFeatureClick = (item) => {
   if (item.title === "生产运营双周会") {
@@ -462,6 +471,17 @@ const navigateToOperationMeeting = (url) => {
 
 onShow(() => {
   loadPageData();
+  if (source.value === "yyhy") {
+    openOperationMeetingPopup();
+  }
+});
+
+onLoad((options) => {
+  console.log("entry-onload", options);
+  source.value = options?.source || "";
+  if (source.value === "yyhy") {
+    openOperationMeetingPopup();
+  }
 });
 </script>
 

+ 40 - 7
pages/recordFilling/detail.vue

@@ -1413,9 +1413,38 @@ const isSubmitting = ref(false); // 添加提交状态
 //   submitDataWithDisable();
 // };
 
-const formRef = ref(null);
-
-const onSubmit = async () => {
+const formRef = ref(null);
+
+const isBlankValue = (value) =>
+  value === null || value === undefined || value === "";
+
+const validateReportMalfunction = (item) => {
+  if (
+    !["ry", "rh"].includes(deptName.value) ||
+    item.deviceName !== "生产日报"
+  ) {
+    return true;
+  }
+
+  const nonSumList = Array.isArray(item.nonSumList) ? item.nonSumList : [];
+  const accidentTime = nonSumList.find((nosum) => nosum.name === "工程质量H");
+  const malfunction = nonSumList.find((nosum) => nosum.name === "故障情况");
+
+  if (
+    Number(accidentTime?.fillContent || 0) > 0 &&
+    isBlankValue(malfunction?.fillContent)
+  ) {
+    uni.showToast({
+      title: "工程质量H大于0时,故障情况必填",
+      icon: "none",
+    });
+    return false;
+  }
+
+  return true;
+};
+
+const onSubmit = async () => {
   try {
     if (formRef.value) {
       for (const item of formRef.value) {
@@ -1438,10 +1467,14 @@ const onSubmit = async () => {
   }
 
   // 1. 校验所有必填项 - 在这里进行所有基础校验
-  for (const item of dataList.value) {
-    const nonSumList = Array.isArray(item.nonSumList) ? item.nonSumList : [];
-
-    // 查找当日运转时间H项目
+  for (const item of dataList.value) {
+    const nonSumList = Array.isArray(item.nonSumList) ? item.nonSumList : [];
+
+    if (!validateReportMalfunction(item)) {
+      return;
+    }
+
+    // 查找当日运转时间H项目
 
     const otherNptTime = nonSumList.find((i) => i.name === "其他非生产时间H");
     const runtimeItem = nonSumList.find((i) => i.name === "当日运转时间H");

+ 35 - 2
pages/ruihen/components/form.vue

@@ -34,6 +34,7 @@ const FORM_KEYS = [
   "deptName",
   "contractName",
   "taskName",
+  "relatedTasks",
   "dailyGasInjection",
   "dailyWaterInjection",
   "dailyPowerUsage",
@@ -125,6 +126,30 @@ const dictStore = useDataDictStore();
 const nptReasonOptions = ref([]);
 const constructionStatusOptions = ref([]);
 
+const relatedTaskOptions = computed(() => {
+  const relatedTasks = form.value.relatedTasks;
+  if (!relatedTasks || Object.keys(relatedTasks).length === 0) {
+    const taskId = form.value.taskId;
+    if (taskId === null || taskId === undefined || taskId === "") return [];
+    return [
+      {
+        text: form.value.taskName || String(taskId),
+        value: taskId,
+      },
+    ];
+  }
+
+  return Object.entries(relatedTasks).map(([key, value]) => ({
+    text: value,
+    value: Number.isNaN(Number(key)) ? key : Number(key),
+  }));
+});
+
+const handleTaskChange = (value) => {
+  const current = relatedTaskOptions.value.find((item) => item.value === value);
+  if (current) form.value.taskName = current.text;
+};
+
 const loadOptions = () => {
   nptReasonOptions.value = dictStore
     .getStrDictOptions("nptReason")
@@ -292,8 +317,16 @@ defineExpose({ formRef, form, loadDetail });
       <uni-forms-item label="项目" name="contractName">
         <span class="readOnly">{{ form.contractName }}</span>
       </uni-forms-item>
-      <uni-forms-item label="任务" name="taskName">
-        <span class="readOnly">{{ form.taskName }}</span>
+      <uni-forms-item label="任务" name="taskId">
+        <uni-data-select
+          :clear="false"
+          align="right"
+          placeholder="请选择"
+          :localdata="relatedTaskOptions"
+          placement="top"
+          :disabled="disabled('edit')"
+          v-model="form.taskId"
+          @change="handleTaskChange" />
       </uni-forms-item>
       <uni-forms-item label="施工区域" name="location">
         <span class="readOnly">{{ form.location }}</span>

+ 1 - 1
pages/ruihen/edit.vue

@@ -24,7 +24,7 @@ const submitForm = async () => {
 
     formLoading.value = true;
 
-    const { createTime, ...other } = form;
+    const { createTime, relatedTasks, ...other } = form;
     const data = { ...other, fillOrderCreateTime: createTime };
 
     await createIotRhDailyReport(data);