<#assign base=request.contextPath />
<#import "../../common/defaultLayout.ftl" as defaultLayout>
<@defaultLayout.layout>
  <link rel="stylesheet" href="${base}/element-ui/element-ui.css">
  <style>

      #businessPurchaseDetailsModal {
          overflow: auto;
      }

      #businessPurchaseDetailsModal > table {

      }

      #procurementContractProcess {
          overflow: auto;
      }

      .el-upload__input {
          display: none !important;
      }

      .el-textarea .el-input__count {
          line-height: 15px;
      }

      .admin-content-body {
          margin-bottom: 100px;
      }

      .el-table__empty-block {
          height: 60px !important;
      }

      .el-upload-list__item-name [class^="el-icon"] {
          height: unset;
      }

      .el-checkbox {
          margin-right: 10px;
      }

      .supplierChoose {
          margin-bottom: 20px;
      }

      .el-input-number--mini .el-input-number__decrease, .el-input-number--mini .el-input-number__increase {
          height: 93%;
      }

      .el-input-number i {
          line-height: unset;
      }

      [v-cloak] {
          display: none;
      }

      .supplierChoose .el-alert {
          border-radius: unset;
      }

      .el-table .warning-row {
          background: oldlace;
      }

      .el-table .child-row {
          background: #f0f9eb;
      }

  </style>

  <div class="admin-content" id="app">
    <div class="admin-content-body">
      <div class="am-cf am-padding">
        <div class="am-fl am-cf" v-cloak><strong class="am-text-primary am-text-lg">{{title}}</strong> /
          <small v-cloak>{{subTitle}}</small></div>
      </div>

      <div class="am-g">
        <div class="am-u-sm-12 am-u-md-12" v-if="isButtonMode">
          <button type="button" class="am-btn" @click="goToSaleContractProcess">
            <img src="${base}/assets/process/销售合同流程@3x.png" width="36"/>
            销售合同流程
          </button>
          <button type="button" class="am-btn" @click="newProcurementContractClick">
            <img src="${base}/assets/process/业务采购流程@3x.png" width="39"/>
            业务采购流程
          </button>

        </div>

          <#-- 业务采购流程项目选择 -->
        <el-dialog title="请选择项目编号" :visible.sync="procurementProjectSelectorVisible"
                   destroy-on-close v-cloak width="40%">

          <el-autocomplete v-model="processForm.projectNo" :fetch-suggestions="queryProject" clearable
                           value-key="projectNo" placeholder="请输入项目编号或名称，支持模糊查询" @select="handleSelectProject"
                           @clear="clearProjectProcess" style="width: 100%;">
            <template slot="prepend">项目编号</template>
              <#--显示项目名称，但是值是 projectNo 定义显示的列表样式-->
            <template slot-scope="{ item }">
              <span>{{ item.name }}</span>
            </template>
          </el-autocomplete>

          <div slot="footer">
            <el-button type="primary" @click="selectProcurementDetail">下一步</el-button>
          </div>
        </el-dialog>

        <el-dialog title="预算采购明细表" :visible.sync="procurementDetailSelectorVisible" v-cloak width="90%"
                   :close-on-click-modal="false">

          <el-table border :data="procurementDetails" height="400">
            <el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
            <el-table-column prop="feeType" label="费用项目" fixed width="80"></el-table-column>
            <el-table-column prop="name" label="产品名称" fixed></el-table-column>
            <el-table-column prop="category" label="采购类别" fixed></el-table-column>

            <el-table-column prop="amount" label="数量"></el-table-column>
            <el-table-column prop="unit" label="单位"></el-table-column>
            <el-table-column prop="price" label="预算单价" width="130"></el-table-column>
            <el-table-column prop="taxRate" label="税率（%）" width="100"></el-table-column>
            <el-table-column prop="totalTaxInclude_" label="含税总金额（元）" width="140"></el-table-column>
            <el-table-column prop="totalTaxExclude" label="不含税金额（元）" width="140"></el-table-column>
            <el-table-column prop="totalTax" label="税金（元）" width="110"></el-table-column>
            <el-table-column prop="isUnderwrittenDesc" label="是否垫资"></el-table-column>
            <el-table-column prop="payTime" label="支出时间" width="180"></el-table-column>
            <el-table-column prop="payAmount" label="支出金额（元）" width="120"></el-table-column>
            <el-table-column prop="amountAlready" label="已采购数量" width="100"></el-table-column>
            <el-table-column prop="amountCurrent" label="本次采购数量" width="180">
              <template slot-scope="scope">
                <el-input-number :precision="2" :step="0.1" :min="0" v-model="scope.row.amountCurrent"
                                 :disabled="scope.row.amountLeft===0" size="mini"
                                 :max="scope.row.amountLeft" controls-position="right">
                </el-input-number>
              </template>
            </el-table-column>

            <el-table-column prop="amountLeft" label="未采购数量" width="100">
              <template slot-scope="scope">
                <span>{{scope.row.amountLeft}}</span>
              </template>
            </el-table-column>

          </el-table>

          <div slot="footer" class="dialog-footer">
            <el-button type="primary" @click="filterProcurementDetails">下一步</el-button>
          </div>

        </el-dialog>

          <#-- 新增销售合同流程 -->

        <div class="am-u-sm-12 am-u-md-12" v-cloak v-if="isSalesContractMode || isProcurementContractMode">
          <el-form :inline="true" ref="contractProcessForm" :model="processForm" label-position="right" label-width="110px">

            <div class="am-form-inline">
              <el-tooltip :disabled="projectSelected && hasText(processForm.projectNo)" effect="light" content="项目编号或名称，支持模糊查询"
                          placement="top-end">
                <el-form-item label="项目编号" required>
                  <el-autocomplete :disabled="projectSelected" clearable @clear="clearProjectProcess"
                                   v-model="processForm.projectNo" :fetch-suggestions="queryProject"
                                   value-key="projectNo" placeholder="请输入项目编号或名称" @select="handleSelectProject">
                      <#--显示项目名称，但是值是 projectNo 定义显示的列表样式-->
                    <template slot-scope="{ item }">
                      <el-tooltip effect="light" :content="item.name" placement="top-start">
                        <span>{{ item.name }}</span>
                      </el-tooltip>
                    </template>

                    <el-popconfirm slot="append" title="确定重新选择项目吗？填写的表单将丢弃"
                                   :disabled="!projectSelected" @confirm="clearProjectProcess">
                      <el-button type="danger" slot="reference" icon="el-icon-delete" size="mini"></el-button>
                    </el-popconfirm>

                  </el-autocomplete>
                </el-form-item>
              </el-tooltip>

              <el-tooltip :disabled="!projectSelected" effect="light" :content="processForm.projectTitle" placement="top-start">
                <el-form-item label="标题">
                  <span v-if="projectSelected">{{processForm.projectTitle}}</span>
                  <span v-else>未选择项目</span>
                </el-form-item>
              </el-tooltip>

              <el-form-item label="申请时间">
                <span v-if="projectSelected">{{processForm.applyDate}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

              <el-form-item :rules="[{ required: true, message: '采购模式不能为空'}]"
                            label="采购模式" prop="procurementMode" v-if="isProcurementContractMode">
                <el-select v-model="processForm.procurementMode" placeholder="请选择采购模式">
                    <#list procurementMode as item>
                      <el-option label="${item.description}" value="${item.name()}"></el-option>
                    </#list>
                </el-select>
              </el-form-item>

              <el-form-item label="项目类型" v-if="isSalesContractMode">
                <span v-if="projectSelected">{{processForm.projectType}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

              <el-form-item label="合作类型">
                <span v-if="projectSelected">{{processForm.cooperationType}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

            </div>

            <div>

              <el-form-item label="申请部门" prop="applyDeptId" :rules="[{ required: true, message: '申请部门不能为空'}]">
                <el-cascader :options="applyDeptSectorOptions" clearable v-model="processForm.applyDeptId"
                             :props="{ expandTrigger: 'hover', label:'name', value: 'id'}" @change="applyDeptSelected"></el-cascader>
              </el-form-item>

              <el-form-item label="申请人">
                <span v-if="projectSelected">{{processForm.applyPersonName}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

              <el-form-item label="申请部门领导">
                <span v-if="processForm.applyDeptLeaderName">{{processForm.applyDeptLeaderName}}</span>
                <span v-else>未选择部门</span>
              </el-form-item>

              <el-form-item v-if="isSalesContractMode" label="申请人电话" prop="applyPersonPhone"
                            :rules="[{ required: true, message: '申请人电话不能为空'},
                                     { pattern:/^((0\d{2,3}-\d{7,8})|(1[3584]\d{9}))$/, message: '请输入合法手机号', trigger: 'blur' }]">
                <el-input placeholder="请输入内容" v-model="processForm.applyPersonPhone" maxlength="13"></el-input>
              </el-form-item>

            </div>

            <div>

              <el-form-item label="合同编号" :rules="[{ required: true, message: '合同编号不能为空'}]" prop="contractNo">
                <el-input placeholder="请输入合同编号" v-model="processForm.contractNo"></el-input>
              </el-form-item>

              <el-form-item :rules="[{ required: true, message: '合同名称不能为空'}]"
                            label="合同名称" prop="contractName" v-if="isSalesContractMode">
                <el-input placeholder="请输入合同名称" v-model="processForm.contractName"></el-input>
              </el-form-item>

              <el-form-item v-if="isProcurementContractMode" label="采购合同名称"
                            :rules="[{ required: true, message: '采购合同名称不能为空'}]" prop="contractName">
                <el-input placeholder="请输入采购合同名称" v-model="processForm.contractName"></el-input>
              </el-form-item>

              <el-form-item label="合同金额">
                <span v-if="projectSelected">{{processForm.contractAmount|numberFormat}}元</span>
                <span v-else>未选择项目</span>
              </el-form-item>

            </div>

            <div>
              <el-form-item v-if="isSalesContractMode" label="客户名称" prop="clientName"
                            :rules="[{ required: true, message: '客户名称不能为空'}]">
                <el-input placeholder="请输入客户名称" v-model="processForm.clientName"></el-input>
              </el-form-item>

              <el-form-item v-if="isProcurementContractMode" label="供应商名称" prop="supplierName"
                            :rules="[{ required: true, message: '供应商名称不能为空'}]">
                <el-input placeholder="请输入供应商" v-model="processForm.supplierName"></el-input>
              </el-form-item>

              <el-form-item label="最终用户名称">
                  <#--TODO 最终用户名称-->
                <span v-if="projectSelected">{{processForm.terminalCustomer}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>
            </div>

            <div>
              <el-form-item label="用印类型" :rules="[{ required: true, message: '用印类型不能为空'}]" prop="sealTypes">
                <el-checkbox-group v-model="processForm.sealTypes">
                    <#list sealTypes as sealType>
                      <el-checkbox label="${sealType.name()}" key="key-${sealType.name()}">${sealType.description}</el-checkbox>
                    </#list>
                </el-checkbox-group>
              </el-form-item>
            </div>

            <div>

              <el-form-item label="税率" :rules="[{ required: true, message: '税率不能为空'}]" prop="taxRate">
                <el-select v-model="processForm.taxRate" placeholder="请选择税率" clearable>
                    <#list taxRate as rate>
                      <el-option label="${rate}%" value="${rate}"></el-option>
                    </#list>
                </el-select>
              </el-form-item>

              <el-form-item label="是否垫资">
                <span v-if="projectSelected">{{processForm.isPrepaid}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

              <el-form-item label="垫资金额" v-if="processForm.isPrepaid!=='否'">
                <span v-if="projectSelected">{{processForm.repaidAmount}}</span>
                <span v-else>未选择项目</span>
              </el-form-item>

              <el-form-item label="预算毛利率">
                <span v-if="projectSelected">{{processForm.budgetGrossMargin}}%</span>
                <span v-else>未选择项目</span>
              </el-form-item>

            </div>

            <div>
              <el-form-item v-if="isSalesContractMode" label="收款条件" :rules="[{ required: true, message: '收款条件不能为空'}]"
                            prop="paymentTerms">
                <el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
                          v-model="processForm.paymentTerms" placeholder="请输入收款条件（限制5000字）"></el-input>
              </el-form-item>

              <el-form-item v-if="isProcurementContractMode" label="付款条件" :rules="[{ required: true, message: '付款条件不能为空'}]"
                            prop="paymentTerms">
                <el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" cols="90" maxlength="5000" show-word-limit
                          v-model="processForm.paymentTerms" placeholder="请输入付款条件（限制5000字）"></el-input>
              </el-form-item>
            </div>

            <div>
              <el-form-item label="备注">
                <el-input type="textarea" :autosize="{ minRows: 5, maxRows: 10}" maxlength="5000" show-word-limit
                          v-model="processForm.remark" placeholder="请输入备注（限制5000字）" cols="90"></el-input>
              </el-form-item>
            </div>

            <div>
              <el-form-item label="上传附件" :rules="[{ required: true, message: '未上传附件'}]">
                <el-upload :show-file-list="false"
                           class="upload-demo" action="${base}/file/upload" name="files[]"
                           accept=".rar,.zip,.7z,.doc,.docx,.pdf,.xls,.xlsx,.png,.jpg,.jpeg,.gif,.bmp,.webp"
                           :before-upload="file => beforeUpload(attachments, file)" :on-success="handleFileUploaded">
                  <el-button size="small" type="primary">点击上传</el-button>
                  <div slot="tip" class="el-upload__tip">只能上传PDF、excel、word、图片、压缩包，且不超过50MB</div>
                </el-upload>
                  <#--已经上传的文件列表-->
                <div v-if="isNotEmpty(attachments)" style="margin-top: 10px">
                  <ul class="el-upload-list el-upload-list--text">
                    <li class="el-upload-list__item is-success" title="点击查看或下载"
                        v-for="attachment in attachments" :key="attachment.name">
                      <a class="el-upload-list__item-name" :href="attachment.uri" target="_blank">
                        <i class="el-icon-document"></i>{{attachment.name|ellipsis}}
                      </a>
                      <i class="el-icon-close" @click="removeAttachment(attachment)"></i>
                    </li>
                  </ul>
                </div>
              </el-form-item>

            </div>

            <div>
              <el-form-item label="合同清单明细" required>
                <el-button type="text" @click="goToContractDetail">详细清单</el-button>
              </el-form-item>
            </div>

          </el-form>

            <#-- 供应商比选材料 -->
          <div class="am-u-sm-12 am-u-md-12 supplierChoose" v-if="isProcurementContractMode">
            <el-alert title="供应商比选材料" type="success" center :closable="false"></el-alert>

            <el-table style="width: 100%" border :data="supplierMaterialsForm" empty-text="暂无">
              <el-table-column type="index" :index="1" label="序号" fixed></el-table-column>

              <el-table-column prop="companyName" label="公司名称" width="180" align="center">
                <template slot-scope="scope">
                  <el-input size="mini" placeholder="请输入公司名称" v-model="scope.row.companyName"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="totalAmount" label="合计金额" width="160" align="center">
                <template slot-scope="scope">
                  <el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
                                   v-model="scope.row.totalAmount"></el-input-number>
                </template>
              </el-table-column>
              <el-table-column prop="serviceTerms" label="服务条款" width="180" align="center">
                <template slot-scope="scope">
                  <el-input size="mini" placeholder="请输入服务条款" v-model="scope.row.serviceTerms"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="paymentTerms" label="付款条件" align="center">
                <template slot-scope="scope">
                  <el-input size="mini" placeholder="请输入付款条件" v-model="scope.row.paymentTerms"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="taxRate" label="税率（%）" width="160" align="center">
                <template slot-scope="scope">
                  <el-input-number size="mini" :precision="2" :step="0.1" :max="100" :min="0"
                                   v-model="scope.row.taxRate"></el-input-number>
                </template>
              </el-table-column>
              <el-table-column prop="remark" label="备注" align="center">
                <template slot-scope="scope">
                  <el-input size="mini" placeholder="请输入备注"
                            v-model="scope.row.remark"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="attachment" label="附件" align="center" width="150">
                <template slot-scope="scope">
                  <el-upload size="mini" name="files[]" action="${base}/file/upload"
                             accept=".rar,.zip,.7z,.doc,.docx,.pdf,.xls,.xlsx,.png,.jpg,.jpeg,.gif,.bmp,.webp"
                             :before-upload="file => beforeUpload(scope.row.attachment, file)"
                             :show-file-list="false"
                             :on-success="(response, file, fileList) => handleSupplierMaterialFileUploaded(scope, response, file, fileList)">
                    <el-popover placement="top-end" title="已经上传的附件" width="380" trigger="hover">
                      <el-button size="small" type="text" slot="reference">上传附件</el-button>
                        <#--展示已经上传的文件-->
                      <div>只能上传PDF、excel、word、图片、压缩包，且不超过50MB</div>
                      <div v-if="isNotEmpty(scope.row.attachment)" style="margin-top: 10px">
                        <ul class="el-upload-list el-upload-list--text">
                          <li class="el-upload-list__item is-success" title="点击查看或下载"
                              v-for="attachment in scope.row.attachment" :key="attachment.name">
                            <a class="el-upload-list__item-name" :href="attachment.uri" target="_blank">
                              <i class="el-icon-document"></i>{{attachment.name|ellipsis}}
                            </a>
                            <i class="el-icon-close" @click="removeSupplierMaterialAttachment(scope, attachment)"></i>
                          </li>
                        </ul>
                      </div>
                      <span v-else style="margin-top: 10px;text-align: center"><strong>暂未上传</strong></span>
                    </el-popover>

                  </el-upload>

                </template>
              </el-table-column>

              <el-table-column width="49" fixed="right">
                <template slot-scope="scope">
                  <el-popconfirm title="确定删除吗？填写的表单将丢弃" @confirm="removeSupplierMaterialRow(scope)">
                    <el-button slot="reference" type="danger" icon="el-icon-delete" circle size="mini"></el-button>
                  </el-popconfirm>
                </template>
              </el-table-column>

            </el-table>

            <el-button type="primary" icon="el-icon-plus" circle size="mini" @click="addSupplierRow"
                       style="float: right;margin: 10px 10px 0 0"></el-button>
          </div>

          <el-row class="am-u-sm-12 am-u-md-12" v-cloak>
            <el-button type="info" @click="goToHome">返回上一级</el-button>
            <el-button type="primary" @click="saveDraft">保存草稿</el-button>
            <el-button type="success" @click="submitForm">提交</el-button>
          </el-row>

        </div>

          <#-- 销售合同清单明细 -->

        <div v-cloak class="am-u-sm-12 am-u-md-12" v-if="isSaleContractDetailMode">
          <el-table border :data="incomeDetails">
            <el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
            <el-table-column prop="name" label="名称" fixed width="120"></el-table-column>
            <el-table-column prop="type" label="类别"></el-table-column>
            <el-table-column prop="spec" label="规格型号"></el-table-column>
            <el-table-column prop="param" label="参数"></el-table-column>
            <el-table-column prop="amount" label="数量"></el-table-column>
            <el-table-column prop="unit" label="单位"></el-table-column>
            <el-table-column prop="price" label="单价（元）" width="120"></el-table-column>
            <el-table-column prop="taxRate" label="税率（%）"></el-table-column>
            <el-table-column prop="totalTaxInclude" label="含税金额（元）" width="120"></el-table-column>
            <el-table-column prop="totalTaxExclude" label="不含税金额（元）" width="120"></el-table-column>
            <el-table-column prop="totalTax" label="税金（元）" width="120"></el-table-column>

            <el-table-column prop="expirationDate" label="质保期" fixed="right" width="150">
              <template slot-scope="scope">
                <el-input maxlength="5" size="mini" placeholder="请输入质保期" v-model="scope.row.expirationDate"
                          @change="updateExpirationDate(scope.row)" show-word-limit>
                </el-input>
              </template>
            </el-table-column>

          </el-table>

          <el-row style="margin: 20px 0">
            <el-button type="primary" @click="saveAndGoToSaleContractProcess">保存并返回上一级</el-button>
          </el-row>

        </div>

          <#-- 新增业务采购合同流程 -->

          <#-- 选择 业务采购清单明细 -->

        <div v-cloak class="am-u-sm-12 am-u-md-12" v-if="isProcurementContractDetailMode">
          <el-table border :data="procurementDetails" row-key="rowKey" default-expand-all :row-class-name="procurementDetailRowClassName">
            <el-table-column type="index" :index="1" label="序号" fixed></el-table-column>
            <el-table-column prop="feeType" label="费用项目" width="100" fixed></el-table-column>
            <el-table-column prop="name" label="产品名称" fixed></el-table-column>
            <el-table-column prop="category" label="采购类别" fixed></el-table-column>

            <el-table-column prop="amount" label="数量"></el-table-column>
            <el-table-column prop="unit" label="单位"></el-table-column>
            <el-table-column prop="price" label="预算单价" width="130"></el-table-column>
            <el-table-column prop="taxRate" label="税率（%）"></el-table-column>
            <el-table-column prop="totalTaxInclude_" label="含税总金额（元）" width="120"></el-table-column>
            <el-table-column prop="totalTaxExclude" label="不含税金额（元）" width="120"></el-table-column>
            <el-table-column prop="totalTax" label="税金（元）" width="110"></el-table-column>
            <el-table-column prop="isUnderwrittenDesc" label="是否垫资"></el-table-column>
            <el-table-column prop="payTime" label="支出时间" width="160"></el-table-column>
            <el-table-column prop="payAmount" label="支出金额（元）" width="120"></el-table-column>
            <el-table-column prop="amountAlready" label="已采购数量" width="100"></el-table-column>
            <el-table-column prop="amountCurrent" label="本次采购数量" width="180">
              <template slot-scope="scope">
                <span v-if="scope.row.newRow"></span>
                <el-input-number v-else :precision="2" :step="0.1" :min="0" v-model="scope.row.amountCurrent"
                                 :disabled="scope.row.amountLeft===0" size="mini"
                                 :max="scope.row.amountLeft" controls-position="right">
                </el-input-number>
              </template>
            </el-table-column>

            <el-table-column prop="amountLeft" label="未采购数量" width="100">
              <template slot-scope="scope">
                <span v-if="!scope.row.newRow">{{scope.row.amountLeft}}</span>
              </template>
            </el-table-column>

            <el-table-column prop="supplierName" label="供应商名称" width="200">
              <template slot-scope="scope">
                <el-input size="mini" placeholder="请输入供应商名称" v-model="scope.row.supplierName"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="manufacturerName" label="设备厂商名称" width="200">
              <template slot-scope="scope">
                <el-input size="mini" placeholder="请输入设备厂商名称" v-model="scope.row.manufacturerName"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="purchaseList" label="对应采购清单" width="200">
              <template slot-scope="scope">
                <el-input size="mini" placeholder="请输入对应采购清单" v-model="scope.row.purchaseList"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="spec" label="规格型号" width="200">
              <template slot-scope="scope">
                <el-input size="mini" placeholder="请输入规格型号" v-model="scope.row.spec"></el-input>
              </template>
            </el-table-column>
            <el-table-column prop="procurementAmount" label="对应采购数目" width="200">
              <template slot-scope="scope">
                <el-input-number size="mini" :precision="2" :step="0.1" :min="0" :max="100000000000000"
                                 v-model="scope.row.procurementAmount" controls-position="right"></el-input-number>
              </template>
            </el-table-column>
            <el-table-column prop="procurementPrice" label="采购单价" width="200">
              <template slot-scope="scope">
                <el-input-number size="mini" :precision="2" :step="1" :min="0" :max="100000000000000"
                                 v-model="scope.row.procurementPrice" controls-position="right"></el-input-number>
              </template>
            </el-table-column>
            <el-table-column prop="totalTaxInclude" label="含税总金额（元）" width="200">
              <template slot-scope="scope">
                <el-input-number size="mini" :precision="2" :step="0.1" :min="0" :max="100000000000000"
                                 v-model="scope.row.totalTaxInclude" controls-position="right"></el-input-number>
              </template>
            </el-table-column>

            <el-table-column width="49" fixed="right">
              <template slot-scope="scope">

                <el-popconfirm v-if="scope.row.newRow" title="确定删除吗？填写的表单将丢弃" @confirm="removeProcurementDetailRow(scope)">
                  <el-button slot="reference" type="danger" icon="el-icon-delete" circle size="mini"></el-button>
                </el-popconfirm>

                <el-button v-else type="primary" icon="el-icon-plus" circle size="mini"
                           @click="addProcurementDetailRow(scope)"></el-button>

              </template>
            </el-table-column>
          </el-table>

          <el-row style="margin: 20px 0">
            <el-button type="primary" @click="saveProcurementContractDetail">保存并返回上一级</el-button>
          </el-row>

        </div>

      </div>

    </div>

  </div>

  <script src="${base}/vue/vue.js"></script>
  <script src="${base}/element-ui/element-ui.js"></script>

  <script>

    const procurementContractProcess = "procurementContractProcess"
    const procurementContractDetail = "procurementContractDetail"
    const saleContractProcess = "saleContractProcess"
    const saleContractDetail = "saleContractDetail"
    const BUTTON = "btn"
    const saleContract = "sale_contract"
    const procurementContract = "procurement_contract"

    const procurementDetailProperties = [
      "spec",
      "purchaseList",
      "amountCurrent",
      "supplierName",
      "totalTaxInclude",
      "manufacturerName",
      "procurementPrice",
      "procurementAmount"
    ]

    const supplierMaterialProperties = [
      "companyName",
      "totalAmount",
      "serviceTerms",
      "paymentTerms",
      "taxRate",
      "attachment",
    ]

    const fileUploadSuffix = [
      ".pdf",
      ".doc", ".docx",
      ".xls", ".xlsx",
      ".rar", ".zip", ".7z",
      ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp"
    ]

    const isEmpty = (obj) => {
      if (!obj) {
        return true
      }

      if (obj.hasOwnProperty('length')) {
        return obj.length === 0
      }
      return false
    }

    const isNotEmpty = (obj) => {
      return !isEmpty(obj)
    }

    const isBlank = (obj) => {
      return isEmpty(obj) || (obj.trim && isEmpty(obj.trim()))
    }

    const hasText = (obj) => {
      return !isBlank(obj)
    }

    const hasProperties = obj => {
      return isNotEmpty(Object.keys(obj));
    }

    const isEmptyObject = obj => {
      return isEmpty(Object.keys(obj));
    }

    function checkStatus(response) {
      if (response.status >= 200 && response.status < 300) {
        return response
      }
      else {
        const error = new Error(response.statusText);
        error.response = response
        throw error
      }
    }

    function parseJSON(response) {
      return response.json()
    }

    /**
     * 给定一个数字，保留两位小数输出，格式化为包含分隔符
     * @param f
     * @returns {string}
     */
    function numberFixed(f) {
      if (!f) {
        return "0.00";
      }
      //return Number(f).toFixed(2);
      //格式化413,423,423.24
      f = Number(f).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2, useGrouping: true });
      return f;
    }

    const data = () => {
      return {
        mode: "btn", // btn , procurementContractProcess
        processForm: {
          sealTypes: [],
        },
        attachments: [],
        supplierMaterialsForm: [],
        projectSelected: false,
        applyDeptSectorOptions: [],
        // 销售合同收入明细
        incomeDetails: [],
        procurementDetails: [],
        filteredProcurementDetails: [],
        processType: "",
        procurementProjectSelectorVisible: false,
        procurementDetailSelectorVisible: false,
        rowKeyCounter: 0,
      }
    }

    const methods = {
      isEmpty,
      isBlank,
      hasText,
      isNotEmpty,
      changeMode(mode) {
        this.mode = mode
      },

      newProcurementContractClick() {
        // 先选择 项目 (打开对话框)
        this.resetForm()
        this.processType = procurementContract
        this.procurementProjectSelectorVisible = true
      },
      selectProcurementDetail() {
        if (this.processForm.projectId) {
          // 预算采购明细表 (打开对话框)
          this.procurementProjectSelectorVisible = false
          this.procurementDetailSelectorVisible = true
        }
        else {
          this.$message.warning("项目还未选择")
        }
      },

      /**
       * 过滤本次流程要填写的采购清单
       */
      filterProcurementDetails() {
        const filteredProcurementDetails = this.procurementDetails.filter(detail => {
          return detail.amountCurrent && detail.amountCurrent !== 0;
        })

        if (isEmpty(filteredProcurementDetails)) {
          this.$message.warning("预算采购明细至少选择一项")
          return
        }
        this.processType = procurementContract
        this.changeMode(procurementContractProcess)
        this.procurementDetailSelectorVisible = false

        this.procurementDetails = [...filteredProcurementDetails]
        // 保留副本，提交订单的时候构建表单的时候用
        this.filteredProcurementDetails = filteredProcurementDetails
      },

      goToHome() {
        // 判断是否已填写了
        if (Object.keys(this.processForm).length > 2) { // 2代表 -> sealTypes,projectTitle
          this.$confirm('您确认要返回上一级吗 返回后填写的表单将重置', '返回上一级', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.resetForm()
            this.changeMode(BUTTON)
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消'
            });
          });
        }
        else {
          this.changeMode(BUTTON)
        }
      },

      goToSaleContractProcess() {
        this.changeMode(saleContractProcess)
        this.processType = saleContract
      },

      /**
       * 校验不通过提示
       * @returns {boolean} 校验通过否
       */
      checkProcurementDetails() {
        let row = 1;
        const emptyRowIndex = []

        const containsEmpty = detail => {
          return isNotEmpty(procurementDetailProperties.filter(property => isBlank(detail[property])))
        }

        this.procurementDetails.forEach(detail => {
          if (containsEmpty(detail)) {
            emptyRowIndex.push(row)
          }
          row++;
          const { children } = detail
          if (children) {
            children.forEach(childDetail => {
              if (containsEmpty(childDetail)) {
                emptyRowIndex.push(row)
              }
              // 每个children都加1
              row++;
            })
          }
        })
        if (isNotEmpty(emptyRowIndex)) {
          const indexString = emptyRowIndex.join(",")
          this.$message.error("在合同清单明细中第 '" + indexString + "' 行中的数据未填写完整")
          return false
        }
        return true
      },
      /**
       * 保存 业务采购合同清单明细
       */
      saveProcurementContractDetail() {
        let contractAmount = 0
        for (let element of this.procurementDetails) {
          const children = element['children'] || []
          contractAmount += element['totalTaxInclude'] || 0
          for (let child of children) {
            contractAmount += child['totalTaxInclude'] || 0
          }
        }
        this.processForm['contractAmount'] = contractAmount
        this.changeMode(procurementContractProcess)
        this.processType = procurementContract
      },


      goToContractDetail() {
        const { projectId } = this.processForm
        if (projectId) {
          // 选择了才能编辑详情
          if (this.isSalesContractMode) {
            this.changeMode(saleContractDetail)
          }
          else if (this.isProcurementContractMode) {
            this.changeMode(procurementContractDetail)
          }
        }
        else {
          this.$message.warning("项目还未选择")
        }
      },

      render(obj) {
        console.log(obj)
      },
      computeProjectTitle(processForm) {
        const { projectNo, projectName, applyPersonName, applyDate } = processForm
        if (projectNo && projectName) {
          return projectNo.trim() + "-" + projectName.trim() + "-" + applyPersonName + "-" + applyDate.split('-').join('')
        }
        return ""
      },
      initForm(form) {
        this.processForm = { ...form, sealTypes: [], projectTitle: this.computeProjectTitle(form) }
      },

      resetForm() {
        this.initForm({})
        this.attachments = []
        this.rowKeyCounter = 0
        this.incomeDetails = []
        this.projectSelected = false
        this.procurementDetails = []
        this.supplierMaterialsForm = []
        this.filteredProcurementDetails = []
      },

      resetProjectNo() {
        this.processForm.projectNo = ""
      },
      /**
       * 搜索项目
       * @param q 用户输入的字符串
       * @param callback 查询成功的回调
       */
      queryProject(q, callback) {
        if (isBlank(q)) {
          callback([])
          return
        }
        fetch("${base}/process/projects?q=" + q + "&processType=" + this.processType)
            .then(checkStatus)
            .then(parseJSON)
            .then(data => {
              if (data.length === 0) {
                callback([])
                this.$message.info('未搜索到结果');
              }
              else {
                callback(data)
              }
            })
            .catch(({ response }) => {
              this.resetProjectNo()
              if (response) {
                parseJSON(response)
                    .then(json => {
                      this.$message.error(json.message || "项目搜索失败")
                    })
              }
              else {
                this.$message.error("项目搜索失败")
              }
            })
      },
      /**
       * 加载选择的项目数据，填写表单需要一些初始数据
       * @param selected 选择的项目信息，包含ID，name 字段
       */
      handleSelectProject({ id, name }) {
        if (!id) {
          this.initForm(this.processForm)
          return
        }
        const loading = this.$loading({
          lock: true,
          text: '正在加载项目',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        })

        fetch("${base}/process/projects/" + id + "?processType=" + this.processType)
            .then(checkStatus)
            .then(parseJSON)
            .then(data => {
              const { incomeDetails, procurementDetails, ...form } = data
              if (!form.projectNo || !form.projectName) {
                this.$message.warning("当前选择的项目没有编号或者名称")
                return
              }

              // 转换数据
              // @formatter:off
              const computeType = (type) => {
                switch (type) {
                  case 1: return '设备'
                  case 2: return '工程'
                  case 3: return '服务'
                  default: return '未知'
                }
              }

              const computeFeeType = (type) => {
                switch (type) {
                  case 1: return '设备'
                  case 2: return '施工'
                  case 3: return '服务'
                  case 4: return '其他'
                  default: return '未知'
                }
              }
              // @formatter:on
              if (this.projectType === procurementContract) {
                // 只有 采购合同重置 合同金额 （因为要根据合同清单明细计算）
                this.initForm({ ...form, contractAmount: 0 })
              }
              else {
                this.initForm(form)
              }
              this.projectSelected = true
              let indexCounter = 1;
              this.incomeDetails = incomeDetails && incomeDetails.map(detail => ({
                ...detail, type: computeType(detail.type),
                price: numberFixed(detail.price),
                totalTax: numberFixed(detail.totalTax),
                payAmount: numberFixed(detail.payAmount),
                totalTaxExclude: numberFixed(detail.totalTaxExclude),
                totalTaxInclude: numberFixed(detail.totalTaxInclude),
                expirationDate: null, // 质保期需要全部重新填写
                index: indexCounter++ // 用于记录序号，展示或者定位
              }))

              let rowKey = 0
              this.procurementDetails = procurementDetails && procurementDetails.map(detail => ({
                ...detail, feeType: computeFeeType(detail.type),
                price: numberFixed(detail.price),
                payAmount: numberFixed(detail.payAmount),
                totalTaxExclude: numberFixed(detail.totalTaxExclude),
                totalTaxInclude_: numberFixed(detail.totalTaxInclude),
                totalTaxInclude: undefined, // 存在相同字段转换一下
                rowKey: rowKey++, children: []
              }))

              this.rowKeyCounter = rowKey

            })
            .catch(({ response }) => {
              // 加载失败重置
              this.resetProjectNo()
              if (response) {
                parseJSON(response)
                    .then(json => {
                      this.$message.error(json.message || "项目'" + name + "'加载失败")
                    })
              }
              else {
                this.$message.error("项目'" + name + "'加载失败")
              }
            })

            .finally(() => loading.close())
      },
      clearProjectProcess() {
        this.resetForm()
        if (this.isProcurementContractMode) {
          this.goToHome()
          // 重新打开对话框选择项目
          this.newProcurementContractClick()
        }
      },

      async saveDraft() {
        this.processForm.status = 'draft'
        this.$refs["contractProcessForm"].clearValidate();
        await this.submit(false)
      },

      async submitForm() {
        this.processForm.status = 'to_be_audit'
        await this.submit(true)
      },

      async submit(needValid) {
        const attachments = this.attachments
        const processForm = this.processForm
        const processType = this.processType
        const supplierMaterialsForm = this.supplierMaterialsForm

        if (!processForm.projectId) {
          this.$message.error("未选择项目");
          return false
        }
        let validStatus = !needValid
        if (needValid) {
          // 校验表单
          this.$refs["contractProcessForm"].validate((valid) => {
            if (valid) {

              if (attachments && attachments.length === 0) {
                this.$message.error("未上传附件");
                return false
              }

              if (processType === saleContract) {
                if (!this.checkExpirationDate()) {
                  return false
                }
              }

              // 采购合同需要验证 供应商比选材料
              if (processType === procurementContract) {
                if (!this.checkProcurementDetails()) {
                  return false
                }
                const { procurementMode } = processForm

                // specify_purchase("指定采购"),
                // simple_price_comparison("简单比价"),
                // price_comparison("比价"),
                // competitive_evaluation("竞争性评估");
                // 当“采购模式”为“指定采购”“简单比价”时，本模块为非必填模块，当为“比价”“竞争性评估”时，本模块为必填项（“备注”除外）
                if (procurementMode === 'price_comparison'
                    || procurementMode === 'competitive_evaluation') {

                  if (isEmpty(supplierMaterialsForm)) {
                    this.$message.error("供应商比选材料未填写,请检查表单")
                    return false
                  }

                  const isPropertyEmpty = value => {
                    if (typeof value === 'string') {
                      return isBlank(value)
                    }
                    else if (value instanceof Array) {
                      return value.length === 0
                    }
                    return value == null || value === undefined
                  }

                  const containsEmpty = detail => {
                    return isNotEmpty(supplierMaterialProperties.filter(property => isPropertyEmpty(detail[property])))
                  }

                  let idx = 0
                  for (const item of supplierMaterialsForm) {
                    idx++
                    if (isEmptyObject(item)) {
                      this.$message.error("供应商比选材料第'" + idx + "'行未填写,请检查表单")
                      return false
                    }

                    if (containsEmpty(item)) {
                      // 单独检查附件
                      if (isEmpty(item.attachment)) {
                        this.$message.error("供应商比选材料第'" + idx + "'行未上传附件")
                      }
                      else {
                        this.$message.error("供应商比选材料第'" + idx + "'行有数据未填写,请检查表单")
                      }
                      return false
                    }
                  }
                }
              }

              if (!processForm.applyDeptId) {
                this.$message.error("申请部门还未选择");
                return false
              }

              // 验证通过
              validStatus = true
              return true;
            }
            else {
              return false
            }
          })

        }

        if (!validStatus) {
          if (isEmpty(document.getElementsByClassName('el-message'))) {
            this.$message.error("表单填写不完整，不能提交");
          }
          return false
        }

        // 提交
        const budgetCostIdMap = new Map()
        this.procurementDetails.forEach(detail => {
          budgetCostIdMap.set(detail.budgetCostId, detail)
        })

        const computePurchaseAmountDetail = budgetCostId => {
          const detail = budgetCostIdMap.get(budgetCostId)
          const ret = []
          const map = detail => {
            const ret = {
              amount: detail.amount // 需要 amount
            }
            procurementDetailProperties.forEach(property => {
              ret[property] = detail[property]
            })
            return ret
          }

          ret.push(map(detail))
          detail.children.forEach(detail => {
            ret.push(map(detail))
          })
          return ret
        }

        const form = {
          ...processForm,
          processType,
          applyDeptId: processForm.applyDeptId?.join(','),// (逗号分割),
          attachments: attachments,
          incomeDetails: this.incomeDetails.map(detail => ({
            id: detail.id, expirationDate: detail.expirationDate
          })),
          purchaseAmount: this.filteredProcurementDetails.map(detail => ({
            amount: detail.amount,
            budgetCostId: detail.budgetCostId,
            amountAlready: detail.amountAlready,
            amountCurrent: detail.amountCurrent,
            details: computePurchaseAmountDetail(detail.budgetCostId)
          })),
          // 剔除空行
          supplierMaterials: supplierMaterialsForm.filter(hasProperties).map(item => ({
            ...item, attachment: JSON.stringify(item.attachment) // 转化为 字符串
          })),
        }
        const loading = this.$loading({
          lock: true,
          text: processForm.status === 'draft' ? '正在保存草稿' : "正在提交",
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        })

        fetch("${base}/process", {
          method: 'POST', // or 'PUT'
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(form),
        }).then(checkStatus).then(data => {
          this.$message({
            showClose: true,
            message: processForm.status === 'draft' ? '草稿保存成功' : "提交成功",
            type: 'success',
            duration: 1000,
            onClose: () => {
              this.resetForm()
              this.goToHome()
            }
          })
        }).catch(({ response }) => {
          const defaultMessage = () => {
            return processForm.status === 'draft' ? '草稿保存失败' : "项目提交失败"
          }
          if (response) {
            parseJSON(response)
                .then(json => {
                  this.$message.error(json.message || defaultMessage())
                })
          }
          else {
            this.$message.error(defaultMessage())
          }
        }).finally(() => loading.close())
      },

      checkExpirationDate() {
        const emptyRows = this.incomeDetails.filter(detail => isBlank(detail.expirationDate))
        if (isNotEmpty(emptyRows)) {
          const indexString = emptyRows.map(detail => detail.index).join(",")
          this.$message.error("在合同清单明细中第 '" + indexString + "' 行的质保期未填写")
          return false
        }
        return true
      },

      /**
       * 处理 质保期
       * @param row 数据行
       */
      updateExpirationDate(row) {
        if (row.expirationDate) {
          row.expirationDate = row.expirationDate.replace(/[^\d\u4E00-\u9FA5]/g, '')
        }
      },

      /**
       * 保存销售合同详情数据，并返回表单界面
       */
      saveAndGoToSaleContractProcess() {
        this.goToSaleContractProcess()
      },

      isUploadFileSizeExceed(file) {
        return file.size > 50 * 1024 * 1024
      },

      isExtensionFailed(file) {
        const { name } = file
        return isEmpty(fileUploadSuffix.filter(suffix => name.endsWith(suffix)))
      },

      beforeUpload(attachments, file) {
        if (attachments.length === 10) {
          this.$message.warning("当前限制选择只能选择10个文件");
          return false
        }

        if (this.isExtensionFailed(file)) {
          this.$message.warning("只能上传PDF、Excel、Word、图片、压缩包");
          return false;
        }
        if (this.isUploadFileSizeExceed(file)) {
          this.$message.warning("上传文件大小不能超过 50MB");
          return false;
        }
      },

      /**
       * 将名字相同的过滤掉
       * @param fileList 要过滤的文件列表 必须含有 name 字段
       * @returns {any[]}
       */
      filterFiles(fileList) {
        const map = new Map()
        fileList.forEach(item => {
          map.set(item.name, item)
        })
        return Array.from(map.values())
      },

      handleFileUploaded(response, file, fileList) {
        if (response.success) {
          this.attachments.push({
            uri: response.data.url,
            name: file.name
          })
          this.attachments = this.filterFiles(this.attachments)
          this.$message.success("上传成功");
        }
        else {
          this.$message.warning("上传失败");
        }
      },

      removeAttachment(file) {
        this.$confirm("确定移除 " + file.name + "？")
            .then(re => {
              this.attachments = this.attachments.filter(item => item !== file)
            })
      },

      removeSupplierMaterialAttachment(scope, attachmentToRemove) {
        this.$confirm("确定移除 " + attachmentToRemove.name + "？")
            .then(r => {
              scope.row['attachment'] = scope.row['attachment'].filter(item => item !== attachmentToRemove)
            })
      },

      handleSupplierMaterialFileUploaded(scope, response, file, fileList) {
        if (response.success) {
          let attachments = scope.row.attachment
          if (isEmpty(attachments)) {
            attachments = []
          }
          attachments.push({
            uri: response.data.url,
            name: file.name
          })

          scope.row.attachment = this.filterFiles(attachments)
          this.$message.success("上传成功");
        }
        else {
          this.$message.warning("上传失败");
        }
      },

      indexMethod(index) {
        return index * 1;
      },

      addSupplierRow() {
        this.supplierMaterialsForm.push({
          rowKey: this.rowKeyCounter++,
          attachment: []
        })
      },

      addProcurementDetailRow(scope) {
        const { row } = scope
        const { children } = row
        const newRow = {
          // ...row, // 不显示数据相同的部分
          rowKey: this.rowKeyCounter++,
          newRow: true,
          parent: row, // 记录上一级元素，在删除的时候使用
          amountCurrent: row.amountCurrent
        }

        delete newRow['children']
        if (children) {
          row['children'].push(newRow)
        }
        else {
          row['children'] = [newRow]
        }

        scope.store.table.toggleRowExpansion(row, true)
      },

      removeProcurementDetailRow(scope) {
        const { rowKey, parent } = scope.row
        parent.children = parent.children.filter(child => child.rowKey !== rowKey)
      },

      // 区别子项
      procurementDetailRowClassName({ row, rowIndex }) {
        if (row.parent) {
          // 有父项说明就是子项
          return 'child-row';
        }
        return '';
      },

      removeSupplierMaterialRow(scope) {
        const { rowKey } = scope.row
        this.supplierMaterialsForm = this.supplierMaterialsForm.filter(child => child.rowKey !== rowKey)
      },

      applyDeptSelected(value) {
        if (value.length === 0) {
          this.processForm['applyDept'] = null
          this.processForm['applyDeptId'] = null
          this.processForm['applyDeptLeaderId'] = null
          this.processForm['applyDeptLeaderName'] = null
          return;
        }

        const level1Value = value[0]
        const level2Value = value.length >= 2 && value[1]
        const level3Value = value.length === 3 && value[2]

        const find = (options, value) => {
          return options.find(option => option.id === value)
        }

        const leveled = []
        let selected = find(this.applyDeptSectorOptions, level1Value)
        leveled.push(selected)
        if (selected && level2Value) {
          selected = find(selected.children, level2Value)
          leveled.push(selected)
          if (selected && level3Value) {
            selected = find(selected.children, level3Value)
            if (selected) {
              leveled.push(selected)
            }
          }
        }

        // applyDeptId 提交时处理
        this.processForm['applyDept'] = leveled.map(level => level.name).join(',') // (逗号分割)
        this.processForm['applyDeptLeaderId'] = selected.leaderId
        this.processForm['applyDeptLeaderName'] = selected.leaderName
      },

    }

    new Vue({
      el: '#app',
      data,
      computed: {
        isButtonMode() {
          return this.mode === BUTTON
        },
        isProcurementContractMode() {
          return this.mode === procurementContractProcess
        },
        isProcurementContractDetailMode() {
          return this.mode === procurementContractDetail
        },
        isSalesContractMode() {
          return this.mode === saleContractProcess
        },
        isSaleContractDetailMode() {
          return this.mode === saleContractDetail
        },
        title() {
          switch (this.mode) {
            case saleContractDetail:
            case procurementContractDetail:
              return "新增流程"
            default:
              return "业务应用"
          }
        },
        subTitle() {
          switch (this.mode) {
            case BUTTON:
              return "新增流程"
            case saleContractProcess:
              return "新增销售合同流程"
            case saleContractDetail:
              return "销售合同清单明细"
            case procurementContractDetail:
              return "业务采购合同清单明细"
            case procurementContractProcess:
              return "新增业务采购合同流程"
          }
        }
      },

      methods,

      mounted() {
        // this.processType = procurementContract
        // this.handleSelectProject({ id: 135 })
        this.applyDeptSectorOptions = JSON.parse('${applyDeptSectorOptions}')
      },

      filters: {
        ellipsis(value, limit = 40) {
          if (!value) return ''
          if (value.length > limit) {
            return value.slice(0, limit) + '...'
          }
          return value
        },
        numberFormat(value) {
          return numberFixed(value)
        }
      }
    })

  </script>

</@defaultLayout.layout>















