form-basic-content.vue 4.04 KB
<script setup lang="ts">
  import { Layout, LayoutContent, LayoutSider, Form, FormItem, Input, InputNumber, Select } from '@arco-design/web-vue';
  import ImageUpload from '@/components/image-upload/index.vue';
  import RoleSelect from '@/views/operation/banner/components/role-select.vue';
  import { Banner } from '@/utils/model';
  import useBannerApi from '@/http/bannner';
  import { computed, ref, watch } from 'vue';
  import { FormInstance } from '@arco-design/web-vue/es/form';
  import { pick } from 'lodash';
  import { AttributeData } from '@/types/global';
  import { promiseToBoolean } from '@/utils';

  type FormType = Pick<Banner, 'name' | 'scope' | 'weight' | 'permission' | 'type' | 'cover' | 'content_picture'>;

  const props = defineProps<{ init?: AttributeData; http: (params?: object) => Promise<any> }>();

  const { scopeOption, typeOption } = useBannerApi;

  const formVal = ref<FormType>({
    name: '',
    scope: 1,
    weight: 0,
    permission: [],
    type: 1,
    cover: '',
    content_picture: '',
    ...pick(props.init, ['name', 'scope', 'weight', 'permission', 'type', 'cover', 'content_picture']),
  });

  const formRule = computed(() => {
    return {
      name: [{ required: true, message: '请输入名称' }],
      scope: [{ required: true, message: '请选择展示位置' }],
      weight: [{ required: true, message: '请输入权重' }],
      permission: [{ required: true, message: '请选择浏览用户' }],
      type: [{ required: true, message: '请选择类型' }],
      cover: [{ required: true, message: '请选择封面' }],
      content_picture: formVal.value.type === 1 ? [] : [{ required: true, message: '请输入链接地址' }],
    };
  });

  const formRef = ref<FormInstance>();

  watch(
    () => formVal.value.type,
    () => (formVal.value.content_picture = '')
  );

  const onSubmit = async (): Promise<boolean> => {
    if (await formRef.value?.validate()) {
      // eslint-disable-next-line prefer-promise-reject-errors
      return Promise.reject(false);
    }
    return promiseToBoolean(props.http(formVal.value));
  };

  defineExpose({ onSubmit });
</script>

<template>
  <Layout>
    <LayoutContent class="content">
      <Form ref="formRef" :model="formVal" :rules="formRule" auto-label-width>
        <FormItem label="封面" field="cover" show-colon>
          <ImageUpload v-model="formVal.cover" :width="500" :height="154" fit="contain" />
        </FormItem>
        <FormItem label="名称" field="name" show-colon>
          <Input v-model="formVal.name" :max-length="30" show-word-limit placeholder="请输入" />
        </FormItem>
        <FormItem label="展示位置" field="scope" show-colon>
          <Select v-model="formVal.scope" :options="scopeOption" placeholder="请选择" />
        </FormItem>
        <FormItem label="权重" field="weight" show-colon>
          <InputNumber v-model="formVal.weight" :min="0" :max="200" placeholder="请输入" />
        </FormItem>
        <FormItem label="浏览用户" field="permission" show-colon>
          <RoleSelect v-model="formVal.permission" :max-tag-count="3" style="height: 32px; width: 500px" />
        </FormItem>
        <FormItem label="类型" field="type" show-colon>
          <Select v-model="formVal.type" :options="typeOption.filter((item) => [1, 2].includes(item.value))" placeholder="请选择" />
        </FormItem>
        <FormItem v-show="formVal.type === 2" label="详情" field="content_picture" show-colon row-class="mb-0">
          <Input v-model="formVal.content_picture" placeholder="请输入" />
        </FormItem>
      </Form>
    </LayoutContent>
    <LayoutSider v-show="formVal.type === 1" class="side" :width="260">
      <ImageUpload v-model="formVal.content_picture" :width="260" height="100%" min-height="414px" fit="fill" />
    </LayoutSider>
  </Layout>
</template>

<style scoped lang="less">
  .side {
    box-shadow: unset;
    margin-left: 10px;
    height: 414px;

    :deep(.arco-upload-list-item) {
      margin-top: 0 !important;

      .arco-upload-picture-card {
        height: 414px !important;
      }
    }
  }
</style>