modify.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 v-model="form.code" :inputBorder="false" disabled />
          </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>
        <view class="footer">
          <button class="btn submit" type="primary" @click="onSubmit">保存</button>
        </view>
      </uni-list>
    </scroll-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, getDetailApi, updateApi } from '@/api/contract'
import { getDicByCodes } from '@/utils/dic'

export default {
  components: { SingleSelectSheet, RelateSelectSheet },
  data() {
    return {
      id: '',
      form: { id: '', code: '', customerId: '', customerIdName: '', company: '', companyName: '', materialTypeId: '', materialTypeIdName: '', hasFrameworkAgreement: '', hasFrameworkAgreementName: '', validityTime: '' },
      companyList: [],
      productVarietyList: [],
      sheet: { visible: false, title: '请选择', field: '', options: [], value: '' },
      relate: { visible: false, title: '选择', source: '', display: [], multiple: false, rowKey: 'id', selectedKeys: [], fieldKey: '' }
    }
  },
  onLoad(query) { this.id = (query && query.id) ? query.id : '' },
  created() { this.loadCompanyList(); this.loadProductVariety(); this.loadDetail() },
  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 = [] }
    },
    loadDetail() {
      if (!this.id) return
      getDetailApi(this.id).then(res => {
        const m = res.data || {}
        const yesNo = m.hasFrameworkAgreement === 'Y' || m.hasFrameworkAgreement === true
        this.form = {
          id: m.id || '',
          code: m.code || '',
          customerId: m.customerId || (m.customer && m.customer.id) || '',
          customerIdName: m.customerName || (m.customer && m.customer.name) || '',
          company: m.company || '',
          companyName: m.companyName || (m.company && m.company.name) || '',
          materialTypeId: m.materialTypeId || (m.materialType && m.materialType.id) || '',
          materialTypeIdName: m.materialTypeName || (m.materialType && m.materialType.name) || '',
          hasFrameworkAgreement: yesNo ? true : false,
          hasFrameworkAgreementName: yesNo ? '是' : '否',
          validityTime: m.validityTime || ''
        }
      })
    },
    openSheet(field) {
      const setSheet = (title, options) => {
        const current = this.form[field]
        const match = (options || []).find(o => 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 = { ...this.relate, title: config.title, source: config.source, display: config.display, multiple: config.multiple, rowKey: config.rowKey, selectedKeys, 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 : ''
    },
    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
    },
    onSubmit() {
      if (!this.validateRequired()) return
      const payload = { id: this.form.id, code: this.form.code, customerId: this.form.customerId, company: this.form.company, materialTypeId: this.form.materialTypeId, hasFrameworkAgreement: !!this.form.hasFrameworkAgreement, validityTime: this.form.validityTime }
      updateApi(payload).then(() => { uni.showToast({ title: '已保存', icon: 'none' }); setTimeout(() => { uni.redirectTo({ url: '/pages/contract_framework/index' }) }, 800) }).catch(() => { uni.showToast({ title: '保存失败', icon: 'none' }) })
    }
  }
}
</script>

<style lang="scss" scoped>
.page {
  display: flex;
  flex-direction: column;
  height: 100%;
}

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

.footer {
  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);
    }
  }

  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>