songxy 1 год назад
Родитель
Сommit
26c64353a9

+ 10 - 1
client/src/interface/contract.ts

@@ -162,6 +162,15 @@ export interface Contract {
    * 税率与金额_综合税率
    */
   taxZhsl?: number
+
+  /**
+   * 流程状态 0-未开始 1-进行中 90-已完成
+   */
+  flowStatus: number
+  /**
+   * 分包理由
+   */
+  subReason?: string
 }
 
 export interface ExtraConstract {
@@ -216,7 +225,7 @@ export interface ExtraConstract {
   /**
    * 合同类型,1-主合同 2-分包合同 3-外包合同
    */
-  'contractType;'?: number
+  contractType?: number
   /**
    * 是否已签订
    */

+ 3 - 6
client/src/service/contract.ts

@@ -21,7 +21,7 @@ export const getContractsById = async (contractId: ContractId): Promise<Contract
  * 合同详情与分包合同列表
  * @param projectId
  */
-export const getContractsByProject = async (projectId: ProjectId): Promise<Contract> => {
+export const getContractsByProject = async (projectId: ProjectId): Promise<Contract[]> => {
   const data = await request.get(
     {
       url: '/contract-with-children',
@@ -29,10 +29,7 @@ export const getContractsByProject = async (projectId: ProjectId): Promise<Contr
     },
     '/business'
   )
-  if ((data?.length ?? 0) === 0) {
-    return data
-  }
-  return data?.find((item) => item?.flowStatus === 90) ?? data?.[0]
+  return data
 }
 
 /**
@@ -205,7 +202,7 @@ export const queryCompanyTree = async () => {
  * 发起分开票申请流程
  * @param contractId
  */
-export const startContractInvoice = async (projectId: string) => {
+export const startContractInvoice = async (projectId?: string) => {
   return await request.get(
     {
       url: '/contractInvoice/process',

+ 18 - 5
client/src/views/OaSystem/projectCenter/projectDetail/components/xmcb/index.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="_ProjectDetail_xmxx">
     <div class="header">
-      <el-form v-if="projectTypeList.length == 1">
+      <el-form v-if="projectTypeList.length > 1">
         <el-form-item label="项目选择:">
           <el-select
             v-model="projectId"
@@ -17,7 +17,7 @@
             >
               <span class="select_label" :title="item.label">{{ item.label }}</span>
               <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">{{
-                item.type === 0 ? '主项目' : '子项目'
+                item.type === 0 ? '主项目' : item.type === 1 ? '子项目' : ''
               }}</span>
             </el-option>
           </el-select>
@@ -115,14 +115,27 @@ interface ProjectTypeInterface {
   label: string
   type: number // 0 主项目 1 子项目
 }
-const projectTypeList = reactive<ProjectTypeInterface[]>([])
+const projectTypeList = ref<ProjectTypeInterface[]>([
+  {
+    label: '全部',
+    value: '',
+    type: -1
+  }
+])
 
 /**
  * 根据项目ID获取项目和子项目Select
  * ** */
 const queryProjectWithChildrenById = async (projectId: string) => {
+  projectTypeList.value = [
+    {
+      label: '全部',
+      value: '',
+      type: -1
+    }
+  ]
   const resultData = await getProjectWithChildrenById(projectId)
-  projectTypeList.push({
+  projectTypeList.value.push({
     label: resultData['xmmc'],
     value: resultData['id'],
     type: 0
@@ -135,7 +148,7 @@ const queryProjectWithChildrenById = async (projectId: string) => {
         type: 1
       }
     })
-    projectTypeList.push(...lists)
+    projectTypeList.value.push(...lists)
   }
 }
 queryProjectWithChildrenById(projectId?.value as string)

+ 1 - 1
client/src/views/OaSystem/projectCenter/projectDetail/components/xmht/ContractReturnedMoney.vue

@@ -51,6 +51,7 @@ const invoiceTypeFilter: (val: number | string) => string = (val: number | strin
           <td>{{ item['contractMilestoneName'] }}</td>
           <td>{{ item['flowStatus'] }}</td>
           <td>{{ item['invoiceAmount'] }}</td>
+          <td>{{ item['actualReturnAmount'] }}</td>
           <td>{{ item['invoiceContent'] }}</td>
           <td>{{ item['invoiceDate'] }}</td>
           <td>{{ item['invoiceNo'] }}</td>
@@ -59,7 +60,6 @@ const invoiceTypeFilter: (val: number | string) => string = (val: number | strin
           <td>
             <span>查看流程</span>
           </td>
-          <td></td>
         </tr>
       </tbody>
     </table>

+ 0 - 55
client/src/views/OaSystem/projectCenter/projectDetail/components/xmht/ContractSharing.vue

@@ -1,55 +0,0 @@
-<script setup lang="ts">
-import { useQuery } from '@tanstack/vue-query'
-import { ContractQueryParams } from '@/interface/contract'
-import { getContractSharingList } from '@/service/contract'
-
-/**
- * 项目合同分包金额承担
- */
-const props = defineProps<ContractQueryParams>()
-const { contractId } = toRefs(props)
-
-const { data: contractSharingList } = useQuery(
-  [getContractSharingList.name, unref(contractId)],
-  async () => await getContractSharingList(unref(contractId))
-)
-</script>
-
-<template>
-  <div class="tableBox tableLineBox">
-    <h4><i class="icon"></i>分包金额承担信息</h4>
-    <div class="table_filter_box">
-      <span>分包费用承担:</span>
-      <div>
-        <el-checkbox-group>
-          <el-checkbox label="自做" />
-          <el-checkbox label="全部由公司承担" />
-          <el-checkbox label="全部由技术部门承担" />
-          <el-checkbox label="由公司和技术部门按比例承担" />
-        </el-checkbox-group>
-      </div>
-    </div>
-    <table>
-      <thead>
-        <tr>
-          <th>承担部门</th>
-          <th>项目名称</th>
-          <th>产值(元)</th>
-          <th>承担金额(元)</th>
-        </tr>
-      </thead>
-      <tbody>
-        <tr>
-          <td></td>
-          <td></td>
-          <td></td>
-          <td></td>
-        </tr>
-      </tbody>
-    </table>
-  </div>
-</template>
-
-<style scoped lang="scss">
-@import './index.scss';
-</style>

+ 41 - 22
client/src/views/OaSystem/projectCenter/projectDetail/components/xmht/index.scss

@@ -9,27 +9,6 @@
       display: flex;
       justify-content: space-between;
       margin-bottom: 15px;
-      >ul {
-        display: flex;
-        align-items: center;
-        >li {
-          padding: 5px 15px;
-          cursor: pointer;
-          font-size: 16px;
-        }
-        &:first-child {
-          >li {
-            font-size: 18px;
-            padding: 5px 25px;
-            &.active,
-            &:hover {
-              font-weight: bold;
-              background-color: #E3EEFF;
-              color: #2E77E6;
-            }
-          }
-        }
-      }
     }
     &.content {
       flex-grow: 1;
@@ -100,7 +79,6 @@
           }
         }
         &.tableLineBox {
-
           table {
             width: 100%;
             border-collapse: collapse;
@@ -137,8 +115,49 @@
   .table_filter_box {
     display: flex;
     margin: 10px 0px;
+    align-items: center;
     >span {
       margin-right: 20px;
     }
   }
 }
+
+  
+ul.contractPopover {
+  >li {
+    cursor: pointer;
+    font-size: 15px;
+  }
+  &:first-child {
+    >li {
+      padding: 5px 25px;
+      &.active,
+      &:hover {
+        background-color: #E3EEFF;
+        color: #2E77E6;
+      }
+    }
+  }
+}
+  
+ul.contractTagList {
+  display: flex;
+  align-items: center;
+  >li {
+    padding: 5px 15px;
+    cursor: pointer;
+    font-size: 16px;
+  }
+  &:first-child {
+    >li {
+      font-size: 18px;
+      padding: 5px 25px;
+      &.active,
+      &:hover {
+        font-weight: bold;
+        background-color: #E3EEFF;
+        color: #2E77E6;
+      }
+    }
+  }
+}

+ 197 - 100
client/src/views/OaSystem/projectCenter/projectDetail/components/xmht/index.vue

@@ -1,29 +1,56 @@
 <template>
   <div class="_ContractDetail_xmxx form-disabled-style">
     <div class="header">
-      <ul v-if="(contractDetail?.['children']?.length ?? 0) !== 0">
+      <ul
+        class="contractTagList"
+        v-if="(contractDetails?.length ?? 0) > 1 || (childrenContracts?.length ?? 0) > 0"
+      >
+        <template v-if="(contractDetails?.length ?? 0) > 1">
+          <el-popover placement="bottom-start" trigger="hover">
+            <template #reference>
+              <li
+                :class="{ active: contractInfoIndex === 0 }"
+                @click="switchContractInfo(contractDetails[mainContractIndex], 0)"
+                >主合同-{{ mainContractIndex + 1 }}
+              </li>
+            </template>
+            <template #default>
+              <ul class="contractPopover">
+                <li
+                  v-for="(item, index) in contractDetails"
+                  :key="index"
+                  @click="switchContractInfo(item, 0, index)"
+                  >主合同-{{ index + 1 }}
+                </li>
+              </ul>
+            </template>
+          </el-popover>
+        </template>
+        <template v-else>
+          <li
+            :class="{ active: contractInfoIndex === 0 }"
+            @click="switchContractInfo(contractDetails[0], 0)"
+            >主合同
+          </li>
+        </template>
         <li
-          :class="{ active: contractInfoIndex === 0 }"
-          @click="switchContractInfo(contractDetail, 0)"
-          >主合同
-        </li>
-        <li
-          v-for="(item, index) in contractDetail['children']"
+          v-for="(item, index) in childrenContracts"
           :class="{ active: contractInfoIndex === index + 1 }"
           :key="index"
           @click="switchContractInfo(item, index + 1)"
-          >分包合同
+        >
+          {{ contractTypeFilter[item['contractType']] }}
         </li>
       </ul>
     </div>
     <div class="content">
       <template v-if="contractInfoIndex === 0">
         <div class="titleBox">
-          <h2>{{ contractDetail?.name ?? '' }} </h2>
-          <span v-if="contractDetail?.amountStatus === 1" class="tag">已签</span>
-          <span v-else-if="contractDetail?.amountStatus === 2" class="tag">未付清</span>
-          <span v-else-if="contractDetail?.amountStatus === 3" class="tag">已付清</span>
-          <span v-else-if="contractDetail?.amountStatus === 4" class="tag">手动设置已付清</span>
+          <h2>{{ mainContractDetail?.name ?? '' }} </h2>
+          <span v-if="mainContractDetail?.amountStatus === 1" class="tag">已签</span>
+          <span v-else-if="mainContractDetail?.amountStatus === 2" class="tag">未付清</span>
+          <span v-else-if="mainContractDetail?.amountStatus === 3" class="tag">已付清</span>
+          <span v-else-if="mainContractDetail?.amountStatus === 4" class="tag">手动设置已付清</span>
         </div>
         <div class="tableBox tableBox—first">
           <h4><i class="icon"></i>基本信息</h4>
@@ -31,19 +58,19 @@
             <li v-if="editor === false" @click="handleEdit">编辑合同</li>
             <li v-else @click="saveContractHandle">保存合同</li>
             <li>用款申请</li>
-            <li @click="() => startContractInvoiceMuate(contractDetail?.id)">开票申请</li>
+            <li @click="() => startContractInvoiceMuate(mainContractDetail?.id)">开票申请</li>
           </ul>
           <table>
             <tr>
               <td class="th">合同编号:</td>
               <td>
-                <el-input v-model="contractDetail['contractNumber']" :disabled="!editor" />
+                <el-input v-model="mainContractDetail.contractNumber" :disabled="!editor" />
               </td>
               <td class="th">合同主类型:</td>
               <td>
                 <el-select
                   style="width: 100%"
-                  v-model="contractDetail['mainType']"
+                  v-model="mainContractDetail.mainType"
                   :disabled="!editor"
                 >
                   <el-option
@@ -61,7 +88,7 @@
                 <TreeSelectV2
                   :data="contractTree"
                   :props="{ label: 'name', value: 'id' }"
-                  v-model="contractDetail['clientId']"
+                  v-model="mainContractDetail.clientId"
                   :filter-method="filterNodeMethod"
                   :disabled="!editor"
                 />
@@ -70,7 +97,7 @@
               <td>
                 <el-select
                   style="width: 100%"
-                  v-model="contractDetail['secondType']"
+                  v-model="mainContractDetail.secondType"
                   :disabled="!editor"
                 >
                   <el-option
@@ -85,14 +112,14 @@
             <tr>
               <td class="th">委托方编号:</td>
               <td>
-                <el-input v-model="contractDetail['clientNumber']" :disabled="!editor" />
+                <el-input v-model="mainContractDetail.clientNumber" :disabled="!editor" />
               </td>
               <td class="th">受托方:</td>
               <td>
                 <TreeSelectV2
                   :data="assigneeTree"
                   :props="{ label: 'name', value: 'id' }"
-                  v-model="contractDetail['assigneeId']"
+                  v-model="mainContractDetail.assigneeId"
                   :filter-method="filterNodeMethod"
                   :disabled="!editor"
                 />
@@ -104,9 +131,9 @@
                 <el-date-picker
                   style="width: 100%"
                   :disabled="true"
-                  v-model="contractDetail['contractOn']"
+                  v-model="mainContractDetail.contractOn"
                   type="date"
-                  @change="($evt) => (contractDetail['lxsj'] = $evt)"
+                  @change="($evt) => (mainContractDetail['contractOn'] = $evt)"
                   placeholder="请选择合同拿出时间"
                 />
               </td>
@@ -115,9 +142,9 @@
                 <el-date-picker
                   style="width: 100%"
                   :disabled="true"
-                  v-model="contractDetail['contractOff']"
+                  v-model="mainContractDetail.contractOff"
                   type="date"
-                  @change="($evt) => (contractDetail['lxsj'] = $evt)"
+                  @change="($evt) => (mainContractDetail['contractOff'] = $evt)"
                   placeholder="请选择合同拿回时间"
                 />
               </td>
@@ -125,7 +152,7 @@
             <tr>
               <td class="th">销售经理:</td>
               <td>
-                <UserOrgTree v-model="contractDetail['areaManager']" :disabled="!editor" />
+                <UserOrgTree v-model="mainContractDetail.areaManagerId" :disabled="!editor" />
               </td>
               <td class="th"></td>
               <td></td>
@@ -140,7 +167,8 @@
               <td>
                 <el-input
                   type="textarea"
-                  v-model="contractDetail['paymentTerms']"
+                  :rows="5"
+                  v-model="mainContractDetail.paymentTerms"
                   :disabled="!editor"
                 />
               </td>
@@ -152,12 +180,10 @@
           <table>
             <tr>
               <td class="th">质保金(元):</td>
-              <td>
-                <el-input v-model="contractDetail['qualityMoney']" :disabled="!editor" />
-              </td>
+              <td>{{ mainContractDetail.qualityMoney }} </td>
               <td class="th">质保金状态:</td>
               <td>
-                <el-input v-model="contractDetail['qualityMoneyStatus']" :disabled="!editor" />
+                {{ mainContractDetail.qualityMoneyStatus }}
               </td>
             </tr>
           </table>
@@ -182,13 +208,13 @@
                 </td>
                 <td>0</td>
                 <td rowspan="5">
-                  <el-input v-model="contractDetail['taxHsjeJskf']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxHsjeJskf" :disabled="!editor" />
                 </td>
                 <td rowspan="5">
-                  <el-input v-model="contractDetail['taxBhsze']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxBhsze" :disabled="!editor" />
                 </td>
                 <td rowspan="5">
-                  <el-input v-model="contractDetail['taxSoftpatent']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxSoftpatent" :disabled="!editor" />
                 </td>
               </tr>
               <tr>
@@ -197,7 +223,7 @@
                   服务
                 </td>
                 <td>
-                  <el-input v-model="contractDetail['taxHsjeFw']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxHsjeFw" :disabled="!editor" />
                 </td>
               </tr>
               <tr>
@@ -206,7 +232,7 @@
                   产品软件
                 </td>
                 <td>
-                  <el-input v-model="contractDetail['taxHsjeRjcp']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxHsjeRjcp" :disabled="!editor" />
                 </td>
               </tr>
               <tr>
@@ -215,26 +241,26 @@
                   硬件(平板等)
                 </td>
                 <td>
-                  <el-input v-model="contractDetail['taxHsjeYj']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxHsjeYj" :disabled="!editor" />
                 </td>
               </tr>
               <tr class="subtotal">
                 <td> 小计</td>
                 <td>
-                  <el-input v-model="contractDetail['taxHsjeTotal']" :disabled="!editor" />
+                  <el-input v-model="mainContractDetail.taxHsjeTotal" :disabled="!editor" />
                 </td>
               </tr>
             </tbody>
           </table>
         </div>
         <!-- 合同里程碑 -->
-        <ContractMilestone :contractId="contractDetail?.id" />
+        <ContractMilestone :contractId="mainContractDetail?.id" />
         <!-- 回款 -->
-        <ContractReturnedMoney :contractId="contractDetail?.id" />
+        <ContractReturnedMoney :contractId="mainContractDetail?.id" />
       </template>
       <template v-else>
         <div class="titleBox">
-          <h2>{{ contractDetail?.name ?? '' }} </h2>
+          <h2>{{ childContractDetail?.name ?? '' }} </h2>
           <span class="tag">已签</span>
           <span class="tag">未付清</span>
         </div>
@@ -245,43 +271,21 @@
             <li v-else @click="saveContractHandle">保存合同</li>
             <li>用款申请</li>
           </ul>
-          <table>
+          <table v-if="childContractDetail?.contractType === 2">
             <tr>
               <td class="th">分包理由:</td>
               <td colspan="3">
-                <el-input v-model="contractDetail['subReason']" :disabled="!editor" />
-              </td>
-            </tr>
-            <tr>
-              <td class="th">采购内容需求:</td>
-              <td colspan="3">
-                <el-input v-model="contractDetail['purchaseRequirements']" :disabled="!editor" />
-              </td>
-            </tr>
-            <tr>
-              <td class="th">分包合同额(元):</td>
-              <td>
-                <el-input v-model="contractDetail['subAmount']" :disabled="!editor" />
-              </td>
-              <td class="th">合同编号:</td>
-              <td>
-                <el-input v-model="contractDetail['contractNumber']" :disabled="!editor" />
+                <el-input v-model="childContractDetail.subReason" :disabled="!editor" />
               </td>
             </tr>
             <tr>
-              <td class="th">委托方:</td>
+              <td class="th">分包金额(元):</td>
               <td>
-                <TreeSelectV2
-                  :data="contractTree"
-                  :props="{ label: 'name', value: 'id' }"
-                  v-model="contractDetail['clientId']"
-                  :filter-method="filterNodeMethod"
-                  :disabled="!editor"
-                />
+                <el-input v-model="childContractDetail.subAmount" :disabled="!editor" />
               </td>
-              <td class="th">申请人:</td>
+              <td class="th">供应商:</td>
               <td>
-                <el-input v-model="contractDetail['applicantName']" :disabled="!editor" />
+                <el-input v-model="childContractDetail.applyWorkerDept" :disabled="!editor" />
               </td>
             </tr>
             <tr>
@@ -289,10 +293,10 @@
               <td>
                 <el-date-picker
                   style="width: 100%"
-                  :disabled="true"
-                  v-model="contractDetail['contractOn']"
+                  :disabled="!editor"
+                  v-model="childContractDetail.contractOn"
                   type="date"
-                  @change="($evt) => (contractDetail['lxsj'] = $evt)"
+                  @change="($evt) => (childContractDetail.contractOn = $evt)"
                   placeholder="请选择合同拿出时间"
                 />
               </td>
@@ -300,21 +304,87 @@
               <td>
                 <el-date-picker
                   style="width: 100%"
-                  :disabled="true"
-                  v-model="contractDetail['contractOff']"
+                  :disabled="!editor"
+                  v-model="childContractDetail.contractOff"
                   type="date"
-                  @change="($evt) => (contractDetail['lxsj'] = $evt)"
+                  @change="($evt) => (childContractDetail.contractOff = $evt)"
                   placeholder="请选择合同拿回时间"
                 />
               </td>
             </tr>
             <tr>
+              <td class="th">是否需要签订合同:</td>
+              <td>
+                <el-radio-group v-model="childContractDetail.isSign" :disabled="!editor">
+                  <el-radio label="1">是</el-radio>
+                  <el-radio label="0">否</el-radio>
+                </el-radio-group>
+              </td>
+              <td class="th">分包费用承担:</td>
+              <td>
+                <el-select
+                  style="width: 100%"
+                  v-model="childContractDetail.subShareWay"
+                  :disabled="!editor"
+                >
+                  <el-option label="全部由公司承担" :value="1" />
+                  <el-option label="全部由技术部门承担" :value="2" />
+                  <el-option label="由公司和技术部门按比例承担" :value="3" />
+                </el-select>
+              </td>
+            </tr>
+            <tr>
+              <td class="th">分包采购内容需求:</td>
+              <td colspan="3">
+                <el-input
+                  type="textarea"
+                  :rows="4"
+                  v-model="childContractDetail.purchaseRequirements"
+                  :disabled="!editor"
+                />
+              </td>
+            </tr>
+          </table>
+          <table v-else>
+            <tr>
+              <td class="th">外包包理由:</td>
+              <td colspan="3">
+                <el-input v-model="childContractDetail.outReason" :disabled="!editor" />
+              </td>
+            </tr>
+            <tr>
+              <td class="th">外包金额(元):</td>
+              <td>
+                <el-input v-model="childContractDetail.outAmount" :disabled="!editor" />
+              </td>
               <td class="th">供应商:</td>
               <td>
-                <el-input v-model="contractDetail['subReason']" :disabled="!editor" />
+                <el-input v-model="childContractDetail.applyWorkerDept" :disabled="!editor" />
+              </td>
+            </tr>
+            <tr>
+              <td class="th">是否需要签订合同:</td>
+              <td>
+                <el-radio-group v-model="childContractDetail.isSign" :disabled="!editor">
+                  <el-radio label="1">是</el-radio>
+                  <el-radio label="0">否</el-radio>
+                </el-radio-group>
+              </td>
+              <td class="th">分包质量把控人:</td>
+              <td>
+                <el-input v-model="childContractDetail.qualityControllerName" :disabled="!editor" />
+              </td>
+            </tr>
+            <tr>
+              <td class="th">备注:</td>
+              <td colspan="3">
+                <el-input
+                  type="textarea"
+                  :rows="4"
+                  v-model="childContractDetail.bz"
+                  :disabled="!editor"
+                />
               </td>
-              <td class="th"></td>
-              <td></td>
             </tr>
           </table>
         </div>
@@ -323,11 +393,10 @@
           <table>
             <tr>
               <td class="th">付款条件:</td>
-              <td colspan="3">{{ contractDetail?.['paymentTerms'] ?? '' }}</td>
+              <td colspan="3">{{ childContractDetail?.paymentTerms ?? '' }}</td>
             </tr>
           </table>
         </div>
-        <ContractSharing :contractId="contractDetail?.['id']" />
         <div class="tableBox">
           <h4><i class="icon"></i>财务信息</h4>
           <table>
@@ -350,7 +419,6 @@ import TreeSelectV2 from '@/components/TreeSelectV2/index.vue'
 import UserOrgTree from '@/views/OaSystem/components/UserOrgTree/index.vue'
 import ContractMilestone from '@/views/OaSystem/projectCenter/projectDetail/components/xmht/ContractMilestone.vue'
 import ContractReturnedMoney from '@/views/OaSystem/projectCenter/projectDetail/components/xmht/ContractReturnedMoney.vue'
-import ContractSharing from '@/views/OaSystem/projectCenter/projectDetail/components/xmht/ContractSharing.vue'
 import {
   getContractsByProject,
   putContract,
@@ -368,6 +436,13 @@ interface TypeSelectInterface {
   label: string
   value: string | number
 }
+const contractTypeFilter = {
+  1: '主合同',
+  2: '分包合同',
+  3: '外包合同'
+} as {
+  [key: number]: string
+}
 const mainTypeList = shallowReactive<TypeSelectInterface[]>([
   {
     label: '规划类',
@@ -417,10 +492,32 @@ const secondTypeList = shallowReactive<TypeSelectInterface[]>([
   }
 ])
 const editor = ref<Boolean>(false)
-const contractDetail = ref<Contract>({
-  id: ''
-})
-
+const mainContractDetail = ref<any>()
+const childContractDetail = ref<any>()
+const contractDetails = ref<any[]>([])
+const childrenContracts = ref<any[]>([])
+/***
+ * 查询主合同和子合同详情数据: 存在多个主合同(兼容之前项目合同),一般来说子合同只存在最新主合同
+ * **/
+const { refetch } = useQuery(
+  [getContractsByProject.name, unref(_mainProjectId)],
+  async () => await getContractsByProject(unref(_mainProjectId)),
+  {
+    onSuccess: (tData: Contract[]) => {
+      for (const contract of tData) {
+        if (contract.children && contract.children.length > 0) {
+          childrenContracts.value = contract.children.filter((child) => {
+            child['contractType'] = 2 //模拟子合同
+            return child?.contractType !== 4
+          })
+          break
+        }
+      }
+      contractDetails.value = tData
+      mainContractDetail.value = tData[0] //初始化主合同
+    }
+  }
+)
 const handleEdit = () => {
   console.log('handleEdit: ')
   editor.value = true
@@ -441,25 +538,27 @@ const { data: assigneeTree } = useQuery(['assigneeTree'], async () => await quer
 /**
  * 切换子项目信息
  * **/
+const mainContractIndex = ref<number>(0)
 const contractInfoIndex = ref<number>(0)
-const switchContractInfo = (item: any, key: number): void => {
+const switchContractInfo = (item: any, key: number, mKey?: number): void => {
   contractInfoIndex.value = key
-  contractDetail.value = item
-}
-
-/***
- * 查询主合同和子合同详情数据
- * **/
-const { refetch } = useQuery(
-  [getContractsByProject.name, unref(_mainProjectId)],
-  async () => await getContractsByProject(unref(_mainProjectId)),
-  {
-    onSuccess: (tData) => {
-      contractDetail.value = tData
+  if (key === 0) {
+    //主合同
+    mainContractDetail.value = item
+    if (mKey) {
+      mainContractIndex.value = mKey
     }
+  } else {
+    childContractDetail.value = item
   }
-)
+}
 
+const saveContractHandle = () => {
+  if (contractInfoIndex.value === 0) {
+    //主合同
+    saveContract(mainContractDetail.value)
+  }
+}
 /**
  * 编辑保存合同信息
  * **/
@@ -475,8 +574,6 @@ const { mutate: saveContract } = useMutation(putContract, {
     })
   }
 })
-const saveContractHandle = () => saveContract(contractDetail.value)
-
 /**
  * 发起开票申请流程
  */

+ 3 - 7
client/src/views/OaSystem/projectCenter/projectDetail/components/xmxx/index.vue

@@ -139,11 +139,7 @@
                     :disabled="!editor"
                   />
                 </td>
-                <template
-                  v-if="
-                    isMaster && projectDetail['isSign'] === 1 && (!contentType || contentType == 0)
-                  "
-                >
+                <template v-if="isMaster && projectDetail['isSign'] === 1 && isEstimateAmount">
                   <td class="th">预估金额(元):</td>
                   <td>
                     <el-input
@@ -221,8 +217,8 @@ import ProjectMember from '@/views/OaSystem/projectCenter/projectDetail/componen
 import ProjectMileStone from '@/views/OaSystem/projectCenter/projectDetail/components/xmxx/ProjectMileStone.vue'
 
 defineOptions({ name: 'XmxxComp' })
-const props = defineProps<{ editor: boolean; contractType: number | undefined }>()
-const { editor, contentType } = toRefs(props)
+const props = defineProps<{ editor: boolean; isEstimateAmount: boolean }>()
+const { editor, isEstimateAmount } = toRefs(props)
 const { query } = useRoute()
 const { id: _mainProjectId = '', subId = '' } = query as {
   id: string

+ 44 - 23
client/src/views/OaSystem/projectCenter/projectDetail/projectDetail.vue

@@ -19,14 +19,17 @@
           </li>
           <template v-if="projectDetail?.['isSign'] === 1">
             <li
-              v-if="!contractData || contractData?.flowStatus === 0"
+              v-if="
+                contractDatas?.length === 0 ||
+                (contractDatas.length === 1 && contractFlowStatuMap[0])
+              "
               @click="handleStartContractSign"
             >
               合同签订
             </li>
             <el-popconfirm
               title="当前存在进行中的合同,是否重复发起?"
-              v-else-if="contractData?.flowStatus === 1"
+              v-else-if="contractFlowStatuMap[1]"
               @confirm="handleStartContractSign"
             >
               <template #reference>
@@ -50,7 +53,7 @@
             <div><i class="icon"></i>项目信息</div>
           </li>
           <li
-            v-show="contractData?.flowStatus === 90"
+            v-show="contractFlowStatuMap[90]"
             @click="switchComponent(XmhtComp, 1)"
             :class="currentIndex === 1 ? 'active' : ''"
           >
@@ -67,7 +70,11 @@
           <template v-if="projectDetail?.['isSign'] === 0">
             <p style="margin-right: 0px">该项目不签合同</p>
           </template>
-          <template v-else-if="!contractData || contractData?.flowStatus === 0">
+          <template
+            v-else-if="
+              contractDatas.length === 0 || (contractDatas.length === 1 && contractFlowStatuMap[0])
+            "
+          >
             <p style="margin-right: 0px">该项目待签合同</p>
           </template>
           <template v-else>
@@ -92,7 +99,7 @@
         :is="currentComponent"
         ref="dynamicRef"
         :editor="isEditorProject"
-        :contractType="contractData?.flowStatus"
+        :isEstimateAmount="contractFlowStatuMap[1] || contractFlowStatuMap[90] ? false : true"
       />
     </div>
   </div>
@@ -110,26 +117,18 @@ import {
 import { openFlow } from '@/utils/flow'
 import { useMutation } from '@tanstack/vue-query'
 import { ProjectId } from '@/interface/project'
+import { Contract } from '@/interface/contract'
 import { getProjectWithChildrenById } from '@/service/project'
+import XmxxComp from './components/xmxx/index.vue'
+import XmhtComp from './components/xmht/index.vue'
+import XmcbComp from './components/xmcb/index.vue'
+import FjclComp from './components/fjcl/index.vue'
 
 const router = useRouter()
 
 defineOptions({ name: 'ProjectDetail' })
 const dynamicRef = shallowRef<Component>()
 
-const XmxxComp = defineAsyncComponent(() => {
-  return import('./components/xmxx/index.vue')
-})
-const XmhtComp = defineAsyncComponent(() => {
-  return import('./components/xmht/index.vue')
-})
-const XmcbComp = defineAsyncComponent(() => {
-  return import('./components/xmcb/index.vue')
-})
-const FjclComp = defineAsyncComponent(() => {
-  return import('./components/fjcl/index.vue')
-})
-
 const { query } = useRoute()
 const { id: projectId, contractId } = query
 const currentIndex = ref<number>(0)
@@ -172,13 +171,35 @@ const processLookHandle = () => {
   })
 }
 /***
- * 查询合同数据
+ * 查询合同数据:存在多主合同情况
  * **/
-const contractData = ref<any>()
+const contractDatas = ref<Contract[]>([])
+interface ContractStatuInterface {
+  [key: number]: boolean
+}
+const contractFlowStatuMap = ref<ContractStatuInterface>({
+  0: false,
+  1: false,
+  90: false
+})
+const contractFlowStatuMapFunc: (datas: Contract[]) => ContractStatuInterface = (
+  datas: Contract[]
+) => {
+  const result: ContractStatuInterface = {
+    0: false,
+    1: false,
+    90: false
+  }
+  for (const contract of datas) {
+    result[contract.flowStatus] = true
+  }
+  return result
+}
 const queryContractsByProject = async (projectId: string) => {
-  const tData = await getContractsByProject(projectId)
-  contractData.value = tData
-  if (tData?.flowStatus === 90 && contractId) {
+  const tData: Contract[] = await getContractsByProject(projectId)
+  contractFlowStatuMap.value = contractFlowStatuMapFunc(tData)
+  contractDatas.value = tData
+  if (contractDatas.value.length > 0 && contractId) {
     switchComponent(XmhtComp, 1)
   }
 }