刘洋 hai 1 ano
pai
achega
d208ae75de

+ 1 - 1
src/components/common/select-service-unit/index.vue

@@ -32,7 +32,7 @@ const props = defineProps({
     type: Object,
     default() {
       // type:'',statusList:''
-      return { statusList: ['PUBLISH', 'FINISH'] };
+      return { statusList: ['PUBLISH'] };
     },
   },
 });

+ 3 - 1
src/components/global/image-viewer/index.vue

@@ -8,7 +8,9 @@
             class="tdesign-demo-image-viewer__ui-image--img"
           />
           <div class="tdesign-demo-image-viewer__ui-image--hover" @click="open">
-            <span><BrowseIcon size="1.4em" /> 预览</span>
+            <span
+              ><BrowseIcon size="1.4em" />{{ width > 79 ? '预览' : '' }}</span
+            >
           </div>
         </div>
       </template>

+ 4 - 1
src/views/project-quality/project-quality-manage/issues-feedback/index.vue

@@ -12,7 +12,10 @@
     </div>
     <SearchForm :fields="fields" :params="params" :search="search">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #user="{ item, params }">
         <select-url-user

+ 97 - 9
src/views/sop/components/dynamic-form-item/RADIO.vue

@@ -1,22 +1,84 @@
 <template>
-  <t-radio-group
-    v-model="valueData"
-    allow-uncheck
-    :options="options"
-    :disabled="!config.writable"
-    style="min-height: 32px; width: 100%"
-    @change="emitChange"
-  ></t-radio-group>
+  <div class="radio">
+    <t-radio-group
+      v-model="valueData"
+      allow-uncheck
+      :disabled="!config.writable"
+      style="min-height: 32px; width: 100%"
+      @change="emitChange"
+    >
+      <t-radio v-for="item in options" :key="item.value">{{
+        item.label
+      }}</t-radio>
+      <div
+        v-if="needDefineBtnFormNames.includes(config?.formName)"
+        class="define-btn flex items-center"
+        @click="showDefine = !showDefine"
+      >
+        <span class="label">查看定义</span>
+        <ChevronDownIcon color="#165dff" v-if="!showDefine" />
+        <ChevronUpIcon color="#165dff" v-else />
+      </div>
+    </t-radio-group>
+    <template v-if="showDefine">
+      <div class="define-content" v-if="config?.formName === 'problem_type_2'">
+        <p>1.修正类:未执行SOP或未按要求正确操作,需要修正的问题;</p>
+        <p>2.优化类:SOP未定义或无明确要求和流程的,需要进行流程优化的问题;</p>
+        <p>3.不是问题:不是质量问题。</p>
+      </div>
+      <div
+        class="define-content"
+        v-if="config?.formName === 'problem_reason_radio_2'"
+      >
+        <p
+          >1.执行类:在项目关键信息明确的前提下,人员疏忽、失误、处理不当、项目风险预估不足、预估到风险却未及时采取合理措施,或未按流程严格执行到位等;</p
+        >
+        <p
+          >2.管理协调类:项目管理未处理好内外项目关键信息沟通协调、计划延期完成等;</p
+        >
+        <p>3.产品缺陷类:产品设计缺陷、BUG,新应用场景需求等;</p>
+        <p>4.产品运维类:例如服务器高并发崩溃、网络阻塞等;</p>
+        <p>5.流程制度类:流程制度本身缺失、设计不合理导致的问题。</p>
+      </div>
+      <div
+        class="define-content"
+        v-if="config?.formName === 'problem_degree_radio_2'"
+      >
+        <p
+          >1.A级:问题已然导致项目事故发生,造成不可挽回的严重后果,严重后果包括以下情况:</p
+        >
+        <p class="text-indent">1)严重影响项目结果数据; </p>
+        <p class="text-indent">2)致使项目实施计划中断;</p>
+        <p class="text-indent">3)项目赔偿或不回款;</p>
+        <p class="text-indent">4)学校合作取消;</p>
+        <p class="text-indent">5)客户领导或员工岗位变动、撤职;</p>
+        <p class="text-indent">6)社会影响恶劣,公司信誉和形象受损。</p>
+        <p
+          >2.B级:问题已然出现,有客户反馈问题,其影响结果必然导致A级事故发生,但责任人接到问题反馈后,能及时成功解决问题、挽回影响,阻止事故发生;</p
+        >
+        <p
+          >3.C级:问题已然出现,由公司内部除责任人外的第三方反馈问题,其影响结果必然导致A级事故发生,但责任人接到问题反括后,能及时解决问题、挽回影响,阻止事故发生;</p
+        >
+        <p>4.D级:项目结果数据无误,问题仅对客户体验有所影响。</p>
+      </div>
+    </template>
+  </div>
 </template>
 
 <script setup name="RADIO">
 import { ref, computed, watch } from 'vue';
+import { ChevronDownIcon, ChevronUpIcon } from 'tdesign-icons-vue-next';
+const needDefineBtnFormNames = ref([
+  'problem_type_2',
+  'problem_reason_radio_2',
+  'problem_degree_radio_2',
+]);
 const props = defineProps({
   config: { type: Object },
   modelValue: { type: String },
 });
 const emit = defineEmits(['update:modelValue', 'change']);
-
+const showDefine = ref(false);
 const valueData = ref(null);
 const options = computed(() => {
   const config = props.config || {};
@@ -44,3 +106,29 @@ watch(
   }
 );
 </script>
+<style lang="less" scoped>
+.define-content {
+  background: #f2f3f5;
+  border-radius: 3px;
+  padding: 10px;
+  p {
+    font-size: 12px;
+    color: #8c8c8c;
+    line-height: 20px;
+  }
+}
+.define-btn {
+  border-radius: 3px;
+  padding: 2px 6px 2px 8px;
+  cursor: pointer;
+  transition: 0.3s;
+  &:hover {
+    background: #e8f3ff;
+  }
+  .label {
+    color: #165dff;
+    margin-right: 4px;
+    font-size: 12px;
+  }
+}
+</style>

+ 127 - 3
src/views/sop/sop-manage/quality-issue/index.vue

@@ -80,6 +80,64 @@
                 @change="itemValueChange"
               ></dynamic-form-item>
             </t-col>
+            <t-col
+              :span="11"
+              v-if="
+                curStepData.taskKey == 'f_usertask_quality_problem_check_3' ||
+                curStepData.taskKey ==
+                  'f_usertask_quality_problem_third_check_4'
+              "
+            >
+              <div class="form-group-title m-l-15px m-b-10px">{{
+                `历史${
+                  curStepData.taskKey == 'f_usertask_quality_problem_check_3'
+                    ? '甲'
+                    : '乙'
+                }方复核意见:`
+              }}</div>
+              <div class="history-box m-l-15px">
+                <div
+                  v-for="(item, index) in flowFormSuggestionResultList"
+                  :key="index"
+                  class="history-item flex items-center"
+                >
+                  <div class="left-info">
+                    <div class="left-head flex justify-between items-center">
+                      <div class="flex items-center h-full">
+                        <span class="u-name">{{ item.approveUserName }}</span>
+                        <t-tag
+                          v-if="item.approveOperation == '同意'"
+                          theme="success"
+                          variant="light"
+                          >同意</t-tag
+                        >
+                        <t-tag v-else theme="danger" variant="light"
+                          >不同意</t-tag
+                        >
+                      </div>
+                      <div class="time">{{
+                        dateFormat(item.createTime, 'yyyy-MM-dd HH:mm')
+                      }}</div>
+                    </div>
+                    <div class="left-body">
+                      <div class="label">初审意见:</div>
+                      <div class="content">
+                        {{ item.approveFormSuggestion }}
+                      </div>
+                    </div>
+                  </div>
+                  <div class="img-box">
+                    <div class="img-wrap">
+                      <image-view
+                        :width="46"
+                        :height="46"
+                        :images="[item.approveFormSign]"
+                      ></image-view>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </t-col>
           </t-row>
         </t-form>
         <t-space v-if="showAction" class="sop-step-footer">
@@ -163,9 +221,8 @@ import { flowFormPropertiesApi, sopFlowViewApi } from '@/api/sop';
 import { MessagePlugin } from 'tdesign-vue-next';
 import DynamicFormItem from '../../components/dynamic-form-item/index.vue';
 import { CUSTOMER_TYPE } from '@/config/constants';
-import { timeNumberToText } from '@/utils/tool';
+import { timeNumberToText, dateFormat } from '@/utils/tool';
 import { timestampFilter } from '@/utils/filter';
-
 const props = defineProps({
   sop: {
     type: Object,
@@ -218,7 +275,13 @@ const sopInfo = reactive({
   crmName: props.sop.crmName,
   statusStr: props.sop.statusStr,
 });
-
+const flowFormSuggestionJiaResultList = ref([]);
+const flowFormSuggestionYiResultList = ref([]);
+const flowFormSuggestionResultList = computed(() => {
+  return curStepData.taskKey == 'f_usertask_quality_problem_check_3'
+    ? flowFormSuggestionJiaResultList.value
+    : flowFormSuggestionYiResultList.value;
+});
 const needValueCodes = [
   'NUMBER', //新增
   'TEXT',
@@ -286,6 +349,10 @@ const initFill = async () => {
   sopInfo.serviceName = crmInfo.value.serviceUnitName;
   sopInfo.sopNo = res.sopNo;
   sopInfo.customManagerTypeStr = CUSTOMER_TYPE[crmInfo.value.customType];
+  flowFormSuggestionJiaResultList.value =
+    res.flowFormSuggestionJiaResultList || [];
+  flowFormSuggestionYiResultList.value =
+    res.flowFormSuggestionYiResultList || [];
 
   res.flowTaskHistoryList = res.flowTaskHistoryList || [];
   res.flowTaskHistoryList.forEach((item) => {
@@ -469,4 +536,61 @@ const submitHandle = async (flowApprove = 'START') => {
 const cancelHandle = () => {
   emit('cancel');
 };
+const curStepData = computed(
+  () => allSteps.value.find((item) => item.taskName === curStep.value) || {}
+);
 </script>
+<style lang="less" scoped>
+.history-box {
+  border: 1px solid #e5e5e5;
+  border-radius: 4px;
+  padding: 4px 15px;
+  .history-item {
+    width: 100%;
+    padding: 8px 0;
+    &:not(:last-child) {
+      border-bottom: 1px solid #e5e5e5;
+    }
+    .left-info {
+      width: calc(100% - 75px);
+      .left-head {
+        height: 26px;
+        .u-name {
+          font-size: 14px;
+          color: #262626;
+          font-weight: 500;
+          margin-right: 12px;
+        }
+        .time {
+          color: #8c8c8c;
+        }
+      }
+      .left-body {
+        padding: 6px 0;
+        display: flex;
+        .label {
+          color: #595959;
+          width: 70px;
+        }
+        .content {
+          width: calc(100% - 70px);
+          color: #262626;
+        }
+      }
+    }
+    .img-box {
+      padding: 5px 0 5px 20px;
+      .img-wrap {
+        width: 52px;
+        height: 52px;
+        border-radius: 4px;
+        border: 1px solid #e5e5e5;
+        background-color: #f0f0f0;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+  }
+}
+</style>

+ 8 - 2
src/views/system/config-manage/checkin-manage/edit-checkin-dialog.vue

@@ -21,6 +21,7 @@
               v-model="formData.dingRoleIds"
               :min-collapsed-num="1"
               :filterable="false"
+              :disabled="isEdit"
               multiple
             >
             </select-role>
@@ -47,7 +48,11 @@
             name="supplierId"
             required-mark
           >
-            <select-supplier v-model="formData.supplierId" type="HUMAN">
+            <select-supplier
+              v-model="formData.supplierId"
+              type="HUMAN"
+              :disabled="isEdit"
+            >
             </select-supplier>
           </t-form-item>
         </t-col>
@@ -112,8 +117,9 @@
         <t-col :span="6">
           <t-form-item label="服务单元" name="serviceId">
             <select-service-unit
+              :disabled="isEdit"
               v-model="formData.serviceId"
-              :filterParams="{}"
+              :filterParams="{ statusList: ['NEW', 'PUBLISH'] }"
             >
             </select-service-unit>
           </t-form-item>

+ 1 - 1
src/views/system/config-manage/checkin-manage/index.vue

@@ -10,7 +10,7 @@
       <template #service="{ item, params }">
         <select-service-unit
           v-model="params[item.prop]"
-          :filterParams="{}"
+          :filterParams="{ statusList: ['NEW', 'PUBLISH'] }"
         ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">

+ 4 - 1
src/views/work-hours/work-hours-manage/abnormal-check/done-check.vue

@@ -2,7 +2,10 @@
   <div class="wait-check">
     <SearchForm :fields="fields" :params="params" showAll :search="search">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">
         <select-supplier v-model="params[item.prop]"> </select-supplier>

+ 4 - 1
src/views/work-hours/work-hours-manage/abnormal-check/wait-check.vue

@@ -22,7 +22,10 @@
     </div>
     <SearchForm :fields="fields" :params="params" showAll :search="search">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">
         <select-supplier v-model="params[item.prop]"> </select-supplier>

+ 4 - 1
src/views/work-hours/work-hours-manage/work-attendance-detail/index.vue

@@ -2,7 +2,10 @@
   <div class="flex flex-col h-full">
     <SearchForm :fields="fields" :params="params" showAll :search="mixinSearch">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">
         <select-supplier v-model="params[item.prop]"> </select-supplier>

+ 7 - 2
src/views/work-hours/work-hours-manage/work-attendance/index.vue

@@ -18,7 +18,10 @@
     </div>
     <SearchForm :fields="fields" :params="params" :search="mixinSearch">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">
         <select-supplier v-model="params[item.prop]"> </select-supplier>
@@ -37,7 +40,9 @@
           <span>已提交:{{ statisticsInfo.submitCount }}</span>
           <span>待提交:{{ statisticsInfo.willSubmitCount }}</span>
           <span>累计人天:{{ statisticsInfo.totalActualDays }}天</span>
-          <span>累计工时:{{ statisticsInfo.totalWorkHours?.toFixed(1) }}小时</span>
+          <span
+            >累计工时:{{ statisticsInfo.totalWorkHours?.toFixed(1) }}小时</span
+          >
           <template #separator>
             <t-divider layout="vertical" />
           </template>

+ 4 - 1
src/views/work-hours/work-hours-manage/work-statistics/index.vue

@@ -8,7 +8,10 @@
     </div>
     <SearchForm :fields="fields" :params="params" :search="mixinSearch">
       <template #service="{ item, params }">
-        <select-service-unit v-model="params[item.prop]"></select-service-unit>
+        <select-service-unit
+          v-model="params[item.prop]"
+          :filterParams="{ statusList: ['PUBLISH', 'FINISH'] }"
+        ></select-service-unit>
       </template>
       <template #supplier="{ item, params }">
         <select-supplier v-model="params[item.prop]"> </select-supplier>