add.vue 11 KB
<template>
  <view class="page">
    <scroll-view class="scroll" scroll-y>
      <uni-list>
        <uni-list-item title="框架合同编号">
          <template v-slot:footer>
            <uni-easyinput disabled v-model="form.code" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item class="select-item" :class="form.customerId ? 'is-filled' : 'is-empty'" clickable
          @click="openRelate('customerId')" :rightText="form.customerIdName || '请选择客户名称'" showArrow>
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>客户名称</text></view>
          </template>
        </uni-list-item>

        <uni-list-item class="select-item" :class="form.company ? 'is-filled' : 'is-empty'" clickable
          @click="openSheet('company')" :rightText="displayLabel('companyName')" showArrow>
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>所属单位</text></view>
          </template>
        </uni-list-item>

        <uni-list-item class="select-item" :class="form.materialTypeId ? 'is-filled' : 'is-empty'" clickable
          @click="openSheet('materialTypeId')" :rightText="displayLabel('materialTypeIdName')" showArrow>
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>品种</text></view>
          </template>
        </uni-list-item>

        <uni-list-item class="select-item" :class="form.hasFrameworkAgreementName ? 'is-filled' : 'is-empty'" clickable
          @click="openSheet('hasFrameworkAgreement')" :rightText="displayLabel('hasFrameworkAgreementName')" showArrow>
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>是否签订框架合同</text></view>
          </template>
        </uni-list-item>

        <uni-list-item title="授时截止日期">
          <template v-slot:footer>
            <uni-datetime-picker type="date" v-model="form.validityTime" />
          </template>
        </uni-list-item>
      </uni-list>
    </scroll-view>

    <view class="footer">
      <button class="btn submit" type="primary" @click="onSubmit">提交</button>
    </view>

    <SingleSelectSheet :visible.sync="sheet.visible" :title="sheet.title" :options="sheet.options" v-model="sheet.value"
      @confirm="onSheetConfirm" />

    <RelateSelectSheet :visible.sync="relate.visible" :title="relate.title" :source="relate.source"
      :display-fields="relate.display" :multiple="relate.multiple" :row-key="relate.rowKey"
      :selectedKeys.sync="relate.selectedKeys" @confirm="onRelateConfirm" />
  </view>
</template>
<script>
import SingleSelectSheet from '@/components/single-select/index.vue'
import RelateSelectSheet from '@/components/relate-select/index.vue'
import { productVarietyQuery, getCodeApi, createApi } from '@/api/contract'
import { getDicByCodes } from '@/utils/dic'

export default {
  components: { SingleSelectSheet, RelateSelectSheet },
  data() {
    return {
      form: {
        code: '',
        customerId: '',
        customerIdName: '',
        company: '',
        companyName: '',
        materialTypeId: '',
        materialTypeIdName: '',
        hasFrameworkAgreement: '',
        hasFrameworkAgreementName: '',
        validityTime: ''
      },
      productVarietyList: [],
      companyList: [],
      sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
      relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' }
    }
  },
  created() {
    this.loadCompanyList()
    this.loadProductVariety()
  },
  watch: {
    'form.company'(val) {
      if (!val) return
      getCodeApi({ company: val }).then(res => {
        console.log(res, '获取框架合同编号')
        const code = (res && res.data) ? res.data : ''
        this.form.code = code
      })
    }
  },
  methods: {
    displayLabel(field) {
      const m = this.form
      const map = {
        companyName: '请选择所属单位',
        materialTypeIdName: '请选择品种',
        hasFrameworkAgreementName: '请选择是否签订'
      }
      const val = m[field]
      return val ? String(val) : map[field]
    },
    async loadCompanyList() {
      try {
        const results = await getDicByCodes(['SUPPLIER'])
        const items = results && results.SUPPLIER && results.SUPPLIER.data ? results.SUPPLIER.data : []
        this.companyList = items.map(it => ({ label: it.name, value: it.code }))
      } catch (e) {
        this.companyList = []
      }
    },
    async loadProductVariety() {
      try {
        const res = await productVarietyQuery({ pageIndex: 1, pageSize: 9999 })
        const list = (res.data && res.data.datas) ? res.data.datas : []
        this.productVarietyList = list.map(it => ({ label: it.name, value: it.id }))
      } catch (e) {
        this.productVarietyList = []
      }
    },
    openSheet(field) {
      const setSheet = (title, options) => {
        const current = this.form[field]
        const match = (options || []).find(o => String(o.label) === String(current) || String(o.value) === String(current))
        this.sheet = { ...this.sheet, visible: true, title, options, field, value: match ? match.value : '' }
      }
      if (field === 'company') {
        setSheet('所属单位', this.companyList)
      } else if (field === 'materialTypeId') {
        setSheet('品种', this.productVarietyList)
      } else if (field === 'hasFrameworkAgreement') {
        setSheet('是否签订框架合同', [{ label: '是', value: true }, { label: '否', value: false }])
      }
    },
    onSheetConfirm({ value, label }) {
      const field = this.sheet.field
      if (!field) return
      const v = (value === undefined || value === null) ? '' : value
      this.form[field] = v
      this.form[field + 'Name'] = label || ''
      if (field === 'company' && value !== undefined && value !== null) {
        getCodeApi({ company: value }).then(res => { const code = (res && res.data) ? res.data : ''; this.form.code = code })
      }
    },
    openRelate(fieldKey) {
      let config = {}
      if (fieldKey === 'customerId') {
        config = {
          title: '客户名称',
          source: 'customer',
          rowKey: 'id',
          multiple: false,
          display: [
            { label: '姓名', field: 'name' },
            { label: '编号', field: 'code' },
            { label: '状态', field: 'available', format: v => (v ? '启用' : '停用') }
          ]
        }
      }
      const selectedKeys = this.form[fieldKey] ? [this.form[fieldKey]] : []
      this.sheet.visible = false
      this.relate.title = config.title
      this.relate.source = config.source
      this.relate.display = config.display
      this.relate.multiple = config.multiple
      this.relate.rowKey = config.rowKey
      this.relate.selectedKeys = selectedKeys
      this.relate.fieldKey = fieldKey
      this.$nextTick(() => { this.relate.visible = true })
    },
    onRelateConfirm({ items }) {
      const _fieldKey = this.relate.fieldKey
      const first = (items && items.length > 0) ? items[0] : null
      this.form[_fieldKey] = (first && first.id) ? first.id : ''
      this.form[_fieldKey + 'Name'] = (first && first.name) ? first.name : ''
    },
    onSubmit() {
      if (!this.validateRequired()) return
      const hv = this.form.hasFrameworkAgreement
      const hasBool = typeof hv === 'string' ? (hv === 'Y') : !!hv
      const payload = {
        code: this.form.code,
        customerId: this.form.customerId,
        company: this.form.company,
        materialTypeId: this.form.materialTypeId,
        hasFrameworkAgreement: hasBool,
        validityTime: this.form.validityTime
      }
      createApi(payload)
        .then(() => {
          uni.showToast({ title: '已提交', icon: 'none' })
          setTimeout(() => { uni.redirectTo({ url: '/pages/contract_framework/index' }) }, 800)
        })
        .catch((err) => {
          uni.showToast({ title: err.msg ||'提交失败', icon: 'none' })
        })
    },
    validateRequired() {
      const checks = [
        { key: 'code', label: '框架合同编号' },
        { key: 'customerId', label: '客户名称' },
        { key: 'company', label: '所属单位' },
        { key: 'materialTypeId', label: '品种' },
        { key: 'hasFrameworkAgreement', label: '是否签订框架合同' },
        { key: 'validityTime', label: '授时截止日期' }
      ]
      for (const it of checks) {
        const val = this.form[it.key]
        const empty = (val === undefined || val === null || (typeof val === 'string' && val.trim() === '') || (typeof val === 'number' && isNaN(val)))
        if (empty) {
          uni.showToast({ title: `请先选择${it.label}`, icon: 'none' })
          return false
        }
      }
      return true
    }
  }
}
</script>
<style lang="scss" scoped>
.page {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.scroll {
  flex: 1;
  padding: 12rpx 0 160rpx;
}

.footer {
  z-index: 2;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 32rpx;
  padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
  background: #fff;
  box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);

  .btn {
    height: 80rpx;
    line-height: 80rpx;
    border-radius: 12rpx;
    font-size: 32rpx;
  }

  .submit {
    background: $theme-primary;
    color: #fff;
  }
}

::v-deep .uni-list {
  .uni-easyinput {
    display: flex;

    .uni-input-input {
      color: rgba(0, 0, 0, 0.9);
    }
  }
  .is-disabled {
    background: transparent !important;
  }

  background: transparent;

  &-item {
    &__extra-text {
      font-size: 32rpx;
    }

    &__content-title {
      font-size: 32rpx;
      color: rgba(0, 0, 0, 0.9);
    }

    &__container {
      padding: 32rpx;

      .uni-easyinput {
        &__placeholder-class {
          font-size: 32rpx;
          color: rgba(0, 0, 0, 0.4);
        }

        &__content {
          border: none;

          &-input {
            padding-left: 0 !important;
            height: 48rpx;
            line-height: 48rpx;
            font-size: 32rpx;
          }

          .content-clear-icon {
            font-size: 44rpx !important;
          }
        }
      }

      .item-title,
      .uni-list-item__content {
        flex: none;
        min-height: 48rpx;
        line-height: 48rpx;
        font-size: 32rpx;
        position: relative;
        width: 210rpx;
        margin-right: 32rpx;
        color: rgba(0, 0, 0, 0.9);

        .required {
          color: red;
          position: absolute;
          top: 50%;
          transform: translateY(-50%);
          left: -16rpx;
        }
      }
    }

    &.select-item {
      &.is-empty {
        .uni-list-item__extra-text {
          color: rgba(0, 0, 0, 0.4) !important;
        }
      }

      &.is-filled {
        .uni-list-item__extra-text {
          color: rgba(0, 0, 0, 0.9) !important;
        }
      }
    }

    &.mgb10 {
      margin-bottom: 20rpx;
    }
  }
}
</style>