|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |  | <template>  <view>    <uv-popup ref="popup" mode="bottom" bgColor="none" >      <view class="popup__view">        <view class="flex header">          <view class="title">{{ title }}</view>          <button class="btn" @click="close">关闭</button>        </view>        <view class="form">          <uv-form             ref="form"            :model="form"            :rules="rules"            errorType="toast"          >            <view class="form-item">              <uv-form-item prop="name" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  姓名                </view>                <view class="form-item-content">                  <formInput v-model="form.name"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="cerNo" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  身份证号                </view>                <view class="form-item-content">                  <formInput v-model="form.cerNo"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="type" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  类型                </view>                <view class="form-item-content">                  <uv-radio-group v-model="form.periodId"                    iconSize="36rpx"                    size="36rpx"                    labelColor="#181818"                    labelSize="26rpx"                    activeColor="#00A9FF"                  >                      <uv-radio                         v-for="item in configList.periodList"                         :key="item.id"                         :label="item.title"                         :name="item.id"                        :customStyle="{ flex: 1 }"                      ></uv-radio>                  </uv-radio-group>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="sex" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  性别                </view>                <view class="form-item-content">                  <uv-radio-group v-model="form.sex"                    iconSize="36rpx"                    size="36rpx"                    labelColor="#181818"                    labelSize="26rpx"                    activeColor="#00A9FF"                  >                    <uv-radio                       v-for="(item, index) in sexOptions"                       :key="index"                       :label="item.label"                       :name="item.value"                      :customStyle="{ flex: 1 }"                    ></uv-radio>                  </uv-radio-group>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="phone" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  手机号                </view>                <view class="form-item-content">                  <formInput v-model="form.phone"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="wechat" :customStyle="formItemStyle">                <view class="form-item-label">微信号</view>                <view class="form-item-content">                  <formInput v-model="form.wechat"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="school" :customStyle="formItemStyle">                <view class="form-item-label">学校</view>                <view class="form-item-content">                  <formInput v-model="form.school"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="grade" :customStyle="formItemStyle">                <view class="form-item-label">年级</view>                <view class="form-item-content">                  <formInput v-model="form.grade"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="age" :customStyle="formItemStyle">                <view class="form-item-label">年龄</view>                <view class="form-item-content">                  <formInput v-model="form.age"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="remark" :customStyle="formItemStyle">                <view class="form-item-label">特殊需求(饮食/健康等)备注</view>                <view class="form-item-content">                  <formInput v-model="form.remark"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="emergencyPhone" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  紧急联系人                </view>                <view class="form-item-content">                  <formInput v-model="form.emergencyPhone"></formInput>                </view>              </uv-form-item>            </view>            <view class="form-item">              <uv-form-item prop="chaperonPhone" :customStyle="formItemStyle">                <view class="form-item-label">                  <image class="icon" src="@/pages_order/static/icon-require.png" mode="widthFix"></image>                  监护人联系方式                </view>                <view class="form-item-content">                  <formInput v-model="form.chaperonPhone"></formInput>                </view>              </uv-form-item>            </view>          </uv-form>        </view>        <view class="footer">          <view class="agreement">            <view>              <uv-checkbox-group                v-model="checkboxValue"                shape="circle"              >                <uv-checkbox                  size="40rpx"                  icon-size="40rpx"                  activeColor="#00A9FF"                  :name="1"                ></uv-checkbox>              </uv-checkbox-group>            </view>            <view class="desc">              我已阅读并同意              <text class="highlight" @click="$refs.modal.open('service_agreement', '服务协议')">《服务协议》</text>              和              <text class="highlight" @click="$refs.modal.open('privacy_policy', '隐私政策')">《隐私政策》</text>            </view>          </view>          <view class="bar">            <button class="flex btn" @click="onSave">保存</button>          </view>        </view>      </view>		</uv-popup>
		<agreementModal ref="modal" @confirm="onConfirmAgreement"></agreementModal>
  </view></template>
<script>  import formInput from '@/pages_order/components/formInput.vue'	import agreementModal from '@/pages_order/components/agreementModal.vue'
  export default {    components: {      formInput,      agreementModal,    },    data() {      return {        id: null,        title: null,        form: {          name: null,          cerNo: null,          periodId: null,          sex: null,          phone: null,          wechat: null,          school: null,          grade: null,          age: null,          remark: null,          emergencyPhone: null,          chaperonPhone: null,        },        rules: {          'name': {            type: 'string',            required: true,            message: '请输入姓名',          },          'cerNo': {            type: 'string',            required: true,            message: '请输入身份证号',          },          'periodId': {            type: 'string',            required: true,            message: '请选择类型',          },          'sex': {            type: 'string',            required: true,            message: '请选择性别',          },          'phone': {            type: 'string',            required: true,            message: '请输入手机号',          },          'emergencyPhone': {            type: 'string',            required: true,            message: '请输入紧急联系人联系方式',          },          'chaperonPhone': {            type: 'string',            required: true,            message: '请输入监护人联系方式',          },        },        formItemStyle: { padding: 0 },        sexOptions: [          {            id: '001',            label: '男',            value: '0',          },          {            id: '002',            label: '女',            value: '1',          },        ],        checkboxValue: [],      }    },    methods: {      async fetchTravelerDetail(personId) {        try {
          const result = await this.$fetch('queryTouristById', { personId })
          const {            name,            cerNo,            periodId,            sex,            phone,            wechat,            school,            grade,            age,            remark,            emergencyPhone,            chaperonPhone,          } = result
          this.form = {            name: name || '',            cerNo: cerNo || '',            periodId,            sex,            phone: phone || '',            wechat: wechat || '',            school: school || '',            grade: grade || '',            age: age || '',            remark: remark || '',            emergencyPhone: emergencyPhone || '',            chaperonPhone: chaperonPhone || '',          }
        } catch (err) {
        }      },      open(id) {
        if (id) {          this.id = id          this.title = '编辑出行人'          this.fetchTravelerDetail(id)        } else {          this.id = null          this.title = '添加出行人'          this.form = {            name: '',            cerNo: '',            periodId: this.configList?.periodList?.[0]?.id || null,            sex: this.sexOptions?.[0]?.value,            phone: '',            wechat: '',            school: '',            grade: '',            age: '',            remark: '',            emergencyPhone: '',            chaperonPhone: '',          }        }
        this.$refs.popup.open()      },      close() {        this.$refs.popup.close()      },      onConfirmAgreement(confirm) {        if (confirm) {          this.checkboxValue = [1]        } else {          this.checkboxValue = []        }      },      async onSave() {        if(!this.checkboxValue.length){          return uni.showToast({            title: '请先同意《服务协议》和《隐私政策》',            icon:'none'          })        }
        try {          await this.$refs.form.validate()
          const {            name,            cerNo,            periodId,            sex,            phone,            wechat,            school,            grade,            age,            remark,            emergencyPhone,            chaperonPhone,          } = this.form
          const params = {            name,            cerNo,            periodId,            sex,            phone,            wechat,            school,            grade,            age,            remark,            emergencyPhone,            chaperonPhone,          }
          if (this.id) {            params.id = this.id
            await this.$fetch('updateTourist', params)                        uni.showToast({              icon: 'success',              title: '修改出行人成功',            });
          } else {
            await this.$fetch('addTourist', params)                        uni.showToast({              icon: 'success',              title: '添加出行人成功',            });
          }
          this.$emit('submitted')
          this.close()
        } catch (err) {          console.log('onSave err', err)        }
      },    },  }</script>
<style lang="scss" scoped>
  .popup__view {    width: 100vw;    display: flex;    flex-direction: column;    box-sizing: border-box;    background: #FFFFFF;    border-top-left-radius: 32rpx;    border-top-right-radius: 32rpx;  }
  .header {    position: relative;    width: 100%;    padding: 24rpx 0;    box-sizing: border-box;    border-bottom: 2rpx solid #EEEEEE;
    .title {      font-family: PingFang SC;      font-weight: 500;      font-size: 34rpx;      line-height: 1.4;      color: #181818;    }
    .btn {      font-family: PingFang SC;      font-weight: 500;      font-size: 32rpx;      line-height: 1.4;      color: #8B8B8B;      position: absolute;      top: 26rpx;      left: 40rpx;    }
  }    .form {    max-height: 75vh;    padding: 32rpx 40rpx;    box-sizing: border-box;    overflow-y: auto;
    &-item {      padding: 8rpx 0 6rpx 0;            & + & {        padding-top: 24rpx;        border-top: 2rpx solid #EEEEEE;      }
      &-label {        margin-bottom: 14rpx;        display: flex;        align-items: center;        font-family: PingFang SC;        font-weight: 400;        font-size: 26rpx;        line-height: 1.4;        color: #181818;
        .icon {          margin-right: 8rpx;          width: 16rpx;          height: auto;        }      }
      &-content {        .placeholder {          color: #C6C6C6;           font-size: 32rpx;           font-weight: 400;        }
        .region {          min-height: 44rpx;          justify-content: flex-start;        }
      }    }  }
  .footer {    width: 100%;
    .agreement {      display: flex;      padding: 16rpx 40rpx;      background: #E9F8FF;      box-sizing: border-box;
      /deep/ .uv-checkbox-group {        flex: none;      }
      .desc {        flex: 1;        font-family: PingFang SC;        font-size: 24rpx;        font-weight: 400;        line-height: 40rpx;        color: #8B8B8B;      }
      .highlight {        color: $uni-color;      }    }        .bar {      width: 100%;      padding: 32rpx 40rpx;      box-sizing: border-box;      border-top: 2rpx solid #F1F1F1;    }
    .btn {      width: 100%;      padding: 14rpx 0;      box-sizing: border-box;      font-family: PingFang SC;      font-weight: 500;      font-size: 36rpx;      line-height: 1.4;      color: #FFFFFF;      background-image: linear-gradient(to right, #21FEEC, #019AF9);      border: 2rpx solid #00A9FF;      border-radius: 41rpx;    }  }
</style>
 |