form-list-item-content.vue 4.37 KB
<script setup lang="ts">
  import { Form, FormItem, Select, Input, Textarea } from '@arco-design/web-vue';
  import { IconAttachment } from '@arco-design/web-vue/es/icon';
  import { computed, createVNode, markRaw, ref, watch } from 'vue';
  import { AnyObject } from '@/types/global';
  import UserTable from '@/views/operation/banner/components/user-table.vue';
  import { BannerLink } from '@/utils/model';
  import { createModalVNode } from '@/utils/createVNode';
  import ProjectTable from '@/views/operation/banner/components/project-table.vue';
  import ActivityTable from '@/views/operation/banner/components/activity-table.vue';
  import { FormInstance } from '@arco-design/web-vue/es/form';

  const props = defineProps<{ init?: AnyObject }>();

  const typeOption = [
    { value: 1, label: '用户' },
    { value: 2, label: '歌曲' },
    { value: 3, label: '厂牌' },
  ];

  const formRef = ref<FormInstance>();

  const formRule = {
    link_type: [{ required: true, message: '请选择关联类型' }],
    link_id: [{ type: 'number', min: 1, required: true, message: '请选择关联对象' }],
    title: [{ required: true, message: '请输入名称' }],
    content: [{ required: true, message: '请输入推荐语' }],
  };

  const formValue = ref<BannerLink>({
    cover: '',
    link_type: 1,
    link_id: 0,
    link_name: '',
    title: '',
    content: '',
    desc1: '',
    desc2: '',
    desc3: '',
    ...props.init,
  });

  watch(
    () => formValue.value.link_type,
    () => {
      formValue.value.cover = '';
      formValue.value.link_id = 0;
      formValue.value.link_name = '';
      formValue.value.title = '';
      formValue.value.content = '';
      formValue.value.desc1 = '';
      formValue.value.desc2 = '';
      formValue.value.desc3 = '';
    }
  );

  const tableComponent = computed(() => {
    switch (formValue.value.link_type) {
      case 2:
        return markRaw(ActivityTable);
      case 3:
        return markRaw(ProjectTable);
      default:
        return markRaw(UserTable);
    }
  });

  const onChoose = () => {
    const modal = ref();

    modal.value = createModalVNode(
      () =>
        createVNode(tableComponent.value, {
          userKey: formValue.value.link_id,
          onCheck: (value: object) => {
            Object.assign(formValue.value, value);
            formRef.value?.clearValidate();
            modal.value?.close();
          },
        }),
      {
        title: '关联对象',
        titleAlign: 'center',
        footer: false,
        closable: true,
        width: '760px',
      }
    );
  };

  const getValue = () => formValue.value;

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

    return Promise.resolve(true);
  };

  defineExpose({ onSubmit, getValue });
</script>

<template>
  <Form ref="formRef" :model="formValue" :rules="formRule">
    <FormItem label="关联类型" field="link_type" show-colon>
      <Select v-model="formValue.link_type" :options="typeOption" placeholder="请选择" />
    </FormItem>
    <FormItem label="关联对象" field="link_id" show-colon>
      <Input :model-value="formValue.link_name" :readonly="true" placeholder="请选择" @focus="onChoose">
        <template #suffix>
          <IconAttachment />
        </template>
      </Input>
    </FormItem>
    <FormItem label="名称" field="title" show-colon>
      <Input v-model="formValue.title" :max-length="12" placeholder="请输入" show-word-limit />
    </FormItem>
    <FormItem label="描述1" field="desc1" show-colon>
      <Input v-model="formValue.desc1" :max-length="18" placeholder="请输入" show-word-limit />
    </FormItem>
    <FormItem label="描述2" field="desc2" show-colon>
      <Input v-model="formValue.desc2" :max-length="18" placeholder="请输入" show-word-limit />
    </FormItem>
    <FormItem label="描述3" field="desc3" show-colon>
      <Textarea v-model="formValue.desc3" :max-length="36" placeholder="请输入" :auto-size="{ minRows: 2, maxRows: 2 }" show-word-limit />
    </FormItem>
    <FormItem label="推荐语" field="content" show-colon row-class="mb-0">
      <Textarea v-model="formValue.content" :max-length="36" placeholder="请输入" :auto-size="{ minRows: 2, maxRows: 2 }" show-word-limit />
    </FormItem>
  </Form>
</template>

<style scoped lang="less"></style>