Newer
Older
smart-metering-front / src / views / finance / businessSettlement / edit.vue
dutingting on 5 May 2023 20 KB 业务结算完成
<script lang="ts" setup name="CreateOrCheck">
import { onMounted, reactive, ref } from 'vue'
import type { Ref } from 'vue'
import dayjs from 'dayjs'
import type { FormInstance, FormRules } from 'element-plus'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import { el } from 'element-plus/es/locale'
import type { IForm, IsampleList } from './businessSettlement-interface'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import useUserStore from '@/store/modules/user'
import selectOrder from '@/views/business/schedule/interchangeReceipt/selectOrder.vue'
import type { IOrderList } from '@/views/business/schedule/order/orderList_interface'
import { getOrderDetail } from '@/api/business/schedule/order'
import { isNumber, validateMoney } from '@/utils/validate'
import { calc } from '@/utils/useCalc'
import { addBusinessSettlement, getBusinessSettlementDetail, updateBusinessSettlement } from '@/api/finance/businessSettlement/businessSettlement'
const user = useUserStore() // 用户信息
const $route = useRoute()
const pageType = ref('detail') // add/detail/edit
const infoId = ref('') // 列表id
const textMap: { [key: string]: string } = {
  edit: '编辑',
  add: '新建',
  detail: '详情',
}// 字典
// 表单数据
const form = ref<IForm>({
  orderCode: '', // 委托书编号
  orderId: '', // 委托书编号
  deliverer: '', // 送检人
  delivererTel: '', // 送样人联系方式
  createTime: '', // 委托单创建时间
  planDeliverTime: '', // 预计送达时间
  requireOverTime: '', // 要求检完时间
  customerNo: '', // 委托方代码
  customerId: '', // 委托方id
  customerName: '', // 委托方名称
  phone: '', // 委托方电话
  priceFront: 0, // 标价
  suggestedDiscount: 95, // 建议折扣
  suggestedPrice: 0, // 建议价格
  extraCharge: 0, // 附加费用-单位分
  extraChargeIllustration: '', // 附加费用说明
  totalSettlement: 0, // 总计结算费用
  samplePriceList: [], // 样品清单
})
const ruleFormRef = ref<FormInstance>() as any
const list = ref<IsampleList[]>([])// 表格数据
const orderVisible = ref(false) // 控制委托书对话框显隐

// 表头
const columns = ref([
  { text: '样品编号', value: 'sampleNo', align: 'center', width: '170', required: false },
  { text: '样品名称', value: 'sampleName', align: 'center', required: false },
  { text: '型号', value: 'sampleModel', align: 'center', required: false },
  { text: '出厂编号', value: 'manufacturingNo', align: 'center', required: false },
  { text: '检定项目', value: 'measureContent', align: 'center', required: false },
  { text: '标价(元)', value: 'price', align: 'center', required: true, reg: validateMoney },
])
// 表单校验规则
const rules = reactive<FormRules>({
  orderCode: [{ required: true, message: '要求委托书编号不能为空', trigger: 'blur' }],
  price: [{ required: true, message: '要求标价不能为空', trigger: ['blur', 'change'] },
    { pattern: /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/, message: '标价只能为数字', trigger: ['blur', 'change'] }],
  suggestedDiscount: [{ required: true, message: '要求建议折扣不能为空', trigger: ['blur', 'change'] },
    { pattern: /^([0]|[1-9][0-9]*)$/, message: '建议折扣只能为正整数或0', trigger: ['blur', 'change'] }],
  extraCharge: [{ required: true, message: '要求附加费用不能为空', trigger: ['blur', 'change'] },
    { pattern: /^(?!0+(?:\.0+)?$)(?:[1-9]\d*|0)(?:\.\d{1,2})?$/, message: '附加费用为正数,且最多保留两位小数', trigger: ['blur', 'change'] }],
  extraChargeIllustration: [{ required: true, message: '附加费用说明不能为空', trigger: 'blur' }],
})

// ---------------------------------------路由参数--------------------------------------
if ($route.params && $route.params.type) {
  pageType.value = $route.params.type as string
  infoId.value = $route.params.id as string
}
// ------------------------------------委托书---------------------------------------------
// 点击选择委托书编号
const handleClickOrder = () => {
  orderVisible.value = true
}
// 修改委托书对话框显隐
const changeOrderVisible = (val: boolean) => {
  orderVisible.value = val
}
// 选好委托书
const confirmCheckoutOrder = (val: Array<IOrderList>) => {
  if (val && val.length) {
    getOrderDetail({ id: val[0].id }).then((res) => { // 样品清单
      form.value.orderCode = res.data.orderCode // 委托书编号
      form.value.orderId = res.data.id // 委托书id
      form.value.deliverer = res.data.deliverer // 送检人
      form.value.delivererTel = res.data.delivererTel // 送检人
      form.value.createTime = res.data.createTime // 委托单创建时间
      form.value.customerNo = res.data.customerNo // 委托方代码
      form.value.customerId = res.data.customerId // 委托方id
      form.value.customerName = res.data.customerName // 委托方名称
      form.value.planDeliverTime = res.data.planDeliverTime // 预计送达时间
      form.value.requireOverTime = res.data.requireOverTime // 要求检完时间
      form.value.phone = res.data.customerPhone // 委托方电话
      list.value = res.data.customerSampleInfoList.map((item: { isEdit: boolean }) => {
        return {
          ...item,
          isEdit: true,
        }
      })
    })
  }
}
// -----------------------------------------样品清单--------------------------------------------
// 检查列表
function checkSampleList() {
  for (let index = 0; index < list.value.length; index++) {
    const item = list.value[index]
    for (const prop of columns.value) {
      // 检查必填
      if (prop.required && !item[prop.value]) {
        ElMessage.warning(`请先完善第${index + 1}行中${prop.text}`)
        return false
      }
      // 验证正则
      if (prop.reg && typeof prop.reg === 'function') {
        if (!prop.reg(item[prop.value])) {
          // ElMessage.warning(`第${index + 1}行中${prop.text}输入不合法`)
          ElMessage.warning(`第${index + 1}行: 要求标价为正数,且最多保留两位小数`)
          return false
        }
      }
    }
  }
  return true
}

// --------------------------------------------自动计算----------------------------------------------
// 折扣改变-计算建议价格
const changeSuggestedDiscount = () => {
  console.log('折扣改变')
  if (form.value.priceFront) {
    form.value.suggestedPrice = calc(Number(form.value.priceFront), Number(form.value.suggestedDiscount / 100), '*') as number
    console.log('0000', form.value.suggestedPrice, typeof form.value.suggestedPrice, form.value.suggestedPrice.toFixed(2))
    form.value.suggestedPrice = Number(form.value.suggestedPrice.toFixed(2))
  }
}
// 标价改变
const changePrice = () => {
  console.log('标价改变')

  let sum = 0
  list.value.forEach((item) => {
    if (item.price) {
      sum = calc(Number(sum), Number(item.price), '+') as number
    }
  })
  form.value.priceFront = sum
  changeSuggestedDiscount() // 建议价格随之变化
}
// 附加费用改变
const changeExtraCharge = () => {
  console.log('附加费用改变')
  form.value.totalSettlement = calc(Number(form.value.suggestedPrice), Number(form.value.extraCharge), '+') as number
}
watch(() => form.value.suggestedPrice, (newValue) => {
  changeExtraCharge()
})

// ----------------------------------------------------------------------------------------
const $router = useRouter()
// 点击关闭
const close = () => {
  $router.back()
}

// 保存
const save = () => {
  if (!checkSampleList()) {
    return false
  }
  ruleFormRef.value.validate((valid: boolean) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        background: 'rgba(255, 255, 255, 0.8)',
      })
      const params = {
        extraCharge: calc(Number(form.value.extraCharge), 100, '*'), // 附加费用-单位分
        extraChargeIllustration: form.value.extraChargeIllustration, // 附加费用说明
        id: infoId.value,
        orderId: form.value.orderId, // 委托书id
        suggestedDiscount: form.value.suggestedDiscount, // 建议折扣-单位%
        samplePriceList: list.value.map((item) => {
          return {
            price: calc(Number(item.price), 100, '*'), // 标价-单位分
            relationId: item.relationId, // 样品id
          }
        }), // 样品清单
      }
      // 新建
      if (pageType.value === 'add') {
        addBusinessSettlement(params).then((res) => {
          ElMessage.success('保存成功')
          loading.close()
          close()
        }).catch(() => {
          loading.close()
        })
      }
      // 编辑
      else if (pageType.value === 'edit') {
        updateBusinessSettlement(params).then((res) => {
          ElMessage.success('保存成功')
          loading.close()
          close()
        }).catch(() => {
          loading.close()
        })
      }
    }
    else {
      console.log('表单校验不通过')
    }
  })
}

// 编辑、详情--获取详细信息
const fetchDetail = () => {
  getBusinessSettlementDetail({ id: infoId.value }).then((res) => {
    form.value = res.data
    form.value.phone = res.data.customerPhone
    list.value = res.data.sampleList.map((item: { postedPrice: number; id: string }) => {
      return {
        ...item,
        price: calc(Number(item.postedPrice), 100, '/') as number,
        isEdit: pageType.value === 'edit',
        relationId: item.id,
      }
    })
    form.value.priceFront = calc(Number(res.data.postedPrice), 100, '/') as number // 标价
    // form.value.suggestedDiscount =  // 建议折扣
    form.value.suggestedPrice = calc(Number(res.data.suggestedPrice), 100, '/') as number// 建议价格
    form.value.extraCharge = calc(Number(res.data.extraCharge), 100, '/') as number// 附加费用-单位分
    // form.value.extraChargeIllustration =  // 附加费用说明
    form.value.totalSettlement = calc(Number(res.data.totalSettlement), 100, '/') as number // 总计结算费用
  })
}

onMounted(() => {
  // 编辑、详情获取详情页信息
  if (pageType.value === 'edit' || pageType.value === 'detail') {
    fetchDetail() // 获取详细信息
  }
})
</script>

<template>
  <app-container>
    <detail-page :title="`业务结算-${textMap[pageType]}`">
      <template #btns>
        <el-button v-if="pageType !== 'detail'" type="primary" @click="save">
          保存
        </el-button>
        <el-button type="info" @click="close">
          关闭
        </el-button>
      </template>
      <div id="form">
        <el-form
          ref="ruleFormRef"
          :model="form"
          :label-width="120"
          label-position="right"
          :rules="rules"
        >
          <el-row :gutter="24">
            <el-col :span="6">
              <el-form-item label="委托书编号:" prop="orderCode">
                <el-input
                  v-model="form.orderCode"
                  :placeholder="pageType === 'detail' ? '' : '请选择委托书编号'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                >
                  <template v-if="pageType !== 'detail'" #append>
                    <el-button size="small" @click="handleClickOrder">
                      选择
                    </el-button>
                  </template>
                </el-input>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="送检人" prop="deliverer">
                <el-input
                  v-model="form.deliverer"
                  :placeholder="pageType === 'detail' ? '' : '送检人'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="联系方式" prop="delivererTel">
                <el-input
                  v-model="form.delivererTel"
                  :placeholder="pageType === 'detail' ? '' : '送检人联系方式'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="委托单创建时间:" prop="createTime">
                <el-date-picker
                  v-model="form.createTime"
                  type="datetime"
                  class="full-width-input"
                  :placeholder="pageType === 'detail' ? '' : '委托单创建时间'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                />
              </el-form-item>
            </el-col>

            <el-col :span="6">
              <el-form-item label="委托方代码:" prop="customerNo">
                <el-input
                  v-model="form.customerNo"
                  :placeholder="pageType === 'detail' ? '' : '委托方代码'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="委托方名称:" prop="customerName">
                <el-input
                  v-model="form.customerName"
                  :placeholder="pageType === 'detail' ? '' : '委托方名称'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <!-- <el-col :span="12">
              <el-form-item label="委托方地址:" prop="customerAddress">
                <el-input
                  v-model="form.customerAddress"
                  type="textarea"
                  autosize
                  :placeholder="pageType === 'detail' ? '' : '请输入委托方地址'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col> -->

            <el-col :span="6">
              <el-form-item label="预计送达时间:" prop="planDeliverTime">
                <el-date-picker
                  v-model="form.planDeliverTime"
                  type="datetime"
                  class="full-width-input"
                  :placeholder="pageType === 'detail' ? '' : '预计送达时间'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="要求检完时间:" prop="requireOverTime">
                <el-date-picker
                  v-model="form.requireOverTime"
                  type="datetime"
                  class="full-width-input"
                  :placeholder="pageType === 'detail' ? '' : '要求检完时间'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="委托方电话">
                <el-input
                  v-model="form.phone"
                  :placeholder="pageType === 'detail' ? '' : '委托方电话'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="标价(元)">
                <el-input
                  v-model="form.priceFront"
                  :placeholder="pageType === 'detail' ? '' : '标价'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="建议折扣(%)" prop="suggestedDiscount">
                <el-input-number
                  v-model="form.suggestedDiscount"
                  :placeholder="pageType === 'detail' ? '' : '请输入建议折扣'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                  :max="100"
                  :min="0"
                  @change="changeSuggestedDiscount"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="建议价格(元)">
                <el-input
                  v-model="form.suggestedPrice"
                  :placeholder="pageType === 'detail' ? '' : '建议价格'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="附加费用" prop="extraCharge">
                <el-input
                  v-model="form.extraCharge"
                  :placeholder="pageType === 'detail' ? '' : '附加费用'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                  @change="changeExtraCharge"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="附加费用说明" prop="extraChargeIllustration">
                <el-input
                  v-model="form.extraChargeIllustration"
                  :placeholder="pageType === 'detail' ? '' : '附加费用说明'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="总计结算费用(元)">
                <el-input
                  v-model="form.totalSettlement"
                  :placeholder="pageType === 'detail' ? '' : '总计结算费用'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </detail-page>
    <!-- 表格 -->
    <detail-block title="样品清单">
      <el-table
        :data="list"
        border
        style="width: 100%;"
        max-height="600"
      >
        <el-table-column align="center" label="序号" width="80" type="index" />
        <el-table-column
          v-for="item in columns"
          :key="item.value"
          :prop="item.value"
          :label="item.text"
          :width="item.width"
          show-overflow-tooltip
          align="center"
        >
          <template #header>
            <span v-show="item.required" style="color: red;">*</span><span>{{ item.text }}</span>
          </template>
          <template #default="scope">
            <!-- 标价可编辑 -->
            <el-input
              v-if="item.value === 'price'"
              v-model="scope.row[item.value]"
              placeholder="请输入标价"
              :disabled="!scope.row.isEdit"
              class="input"
              @change="changePrice"
            />
            <!-- 除标价另外的行 -->
            <span v-else>{{ scope.row[item.value] }}</span>
          </template>
        </el-table-column>
      </el-table>
    </detail-block>
    <!-- 选择委托书组件 -->
    <select-order v-model:visible="orderVisible" @confirmCheckout="confirmCheckoutOrder" @changeVisible="changeOrderVisible" />
  </app-container>
</template>

<style lang="scss" scoped>
// 样式
.create-check {
  margin-top: 10px;

  .top-info {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding-right: 10px;
    border-radius: 10px;
    background-color: #fff;
    // padding: 10px;

    .title-button {
      display: flex;
      align-items: center;

      &::before {
        content: "";
        flex: 1;
      }

      .button-group {
        flex: 1;
        display: flex;
        justify-content: flex-end;
      }
    }

    .form-area {
      margin-top: 40px;
    }
  }
}
</style>