add.vue 9.07 KB
<template>
  <view class="page">
    <scroll-view class="scroll" scroll-y>
      <uni-list>
        <uni-list-item class="select-item" :class="form.code ? 'is-filled' : 'is-empty'">
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>编号</text></view>
          </template>
          <template v-slot:footer>
            <view class="serial-number-row">
              <uni-easyinput v-model="form.code" placeholder="自动生成编号" :inputBorder="false" disabled />
              <button class="generate-btn" @click="loadCode">点此生成</button>
            </view>
          </template>
        </uni-list-item>

        <uni-list-item title="名称">
          <template v-slot:body>
            <view class="item-title"><text class="required">*</text><text>名称</text></view>
          </template>
          <template v-slot:footer>
            <uni-easyinput v-model="form.name" placeholder="请输入名称" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="联系人">
          <template v-slot:footer>
            <uni-easyinput v-model="form.contact" placeholder="请输入联系人" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="联系电话">
          <template v-slot:footer>
            <uni-easyinput v-model="form.telephone" placeholder="请输入联系电话" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="电子邮箱">
          <template v-slot:footer>
            <uni-easyinput v-model="form.email" placeholder="请输入电子邮箱" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="邮编">
          <template v-slot:footer>
            <uni-easyinput v-model="form.zipCode" placeholder="请输入邮编" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="传真">
          <template v-slot:footer>
            <uni-easyinput v-model="form.fax" placeholder="请输入传真" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item class="select-item"
          :class="(Array.isArray(form.cityIds) && form.cityIds.length) ? 'is-filled' : 'is-empty'" clickable
          @click="openCitySelector" :rightText="form.cityLabel || '请选择'" showArrow>
          <template v-slot:body>
            <view class="item-title"><text>地区</text></view>
            <CitySelector ref="citySelectorRef" v-model="form.cityIds" @change="onCityChange" />
          </template>
        </uni-list-item>

        <uni-list-item title="地址">
          <template v-slot:footer>
            <uni-easyinput v-model="form.address" placeholder="请输入地址" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="统一社会信用代码">
          <template v-slot:footer>
            <uni-easyinput v-model="form.creditCode" placeholder="请输入统一社会信用代码" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="纳税人识别号">
          <template v-slot:footer>
            <uni-easyinput v-model="form.taxIdentifyNo" placeholder="请输入纳税人识别号" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="开户银行">
          <template v-slot:footer>
            <uni-easyinput v-model="form.bankName" placeholder="请输入开户银行" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="户名">
          <template v-slot:footer>
            <uni-easyinput v-model="form.accountName" placeholder="请输入户名" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="银行账号">
          <template v-slot:footer>
            <uni-easyinput v-model="form.accountNo" placeholder="请输入银行账号" :inputBorder="false" />
          </template>
        </uni-list-item>

        <uni-list-item title="备注">
          <template v-slot:footer>
            <uni-easyinput type="textarea" v-model="form.description" placeholder="请输入备注" :inputBorder="false" />
          </template>
        </uni-list-item>
        <view class="footer">
          <button class="btn submit" type="primary" @click="onSubmit">提交</button>
        </view>
      </uni-list>
    </scroll-view>
  </view>
</template>

<script>
import { createApi } from '@/api/customer.js'
import { generateCodeApi } from '@/api/base.js'
import CitySelector from '@/components/city-selector/index.vue'
import { isEmail } from '@/utils/common.js'

export default {
  name: 'CustomerAdd',
  components: { CitySelector },
  data() {
    return {
      form: {
        code: '',
        name: '',
        contact: '',
        telephone: '',
        email: '',
        zipCode: '',
        fax: '',
        cityIds: [],
        cityLabel: '',
        address: '',
        creditCode: '',
        taxIdentifyNo: '',
        bankName: '',
        accountName: '',
        accountNo: '',
        description: ''
      }
    }
  },
  created() {
    this.loadCode()
  },
  methods: {
    async loadCode() {
      try {
        const res = await generateCodeApi(5)
        this.form.code = (res && res.data) || ''
      } catch (e) {
        this.form.code = ''
      }
    },
    openCitySelector() {
      this.$refs.citySelectorRef && this.$refs.citySelectorRef.open()
    },
    onCityChange(payload) {
      const label = payload && payload.label != null ? payload.label : ''
      this.form.cityLabel = label
    },
    validateRequired() {
      if (!this.form.code) {
        uni.showToast({ title: '请先生成编号', icon: 'none' })
        return false
      }
      if (!this.form.name || !this.form.name.trim()) {
        uni.showToast({ title: '请输入名称', icon: 'none' })
        return false
      }
      if (this.form.email && !isEmail(this.form.email)) {
        uni.showToast({ title: '邮箱地址格式不正确', icon: 'none' })
        return false
      }
      return true
    },
    async onSubmit() {
      if (!this.validateRequired()) return

      const { cityIds, cityLabel, ...other } = this.form
      // 取最后一个 ID 作为 city
      const cityId = cityIds && cityIds.length > 0 ? cityIds[cityIds.length - 1] : ''

      const payload = {
        ...other,
        cityId
      }

      console.log('onSubmit payload', payload)
      try {
        await createApi(payload)
        uni.showToast({ title: '提交成功', icon: 'success' })
        setTimeout(() => { uni.redirectTo({ url: '/pages/customer/index' }) }, 300)
      } catch (e) {
        uni.showToast({ title: (e && e.msg) || '提交失败', icon: 'none' })
      }
    }
  }
}
</script>

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

.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);
  z-index: 10;

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

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

::v-deep .uni-list {
  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 {
        .is-disabled {
          background-color: transparent !important;
        }

        &__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;
          }
        }
      }

      .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);
        padding-right: 0;

        .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;
        }
      }

      .serial-number-row {
        display: flex;
        align-items: center;

        .generate-btn {
          margin-left: 24rpx;
          height: 64rpx;
          line-height: 64rpx;
          padding: 0 24rpx;
          font-size: 28rpx;
          border-radius: 8rpx;
          background: $theme-primary;
          color: #fff;
        }
      }
    }
  }
}
</style>