AppDraw.vue 11.7 KB
<template>
  <div class="card">
    <Card :bordered="false" class="card">
      <BasicForm @register="registerForm">
        <template #logoUpload>
          <Upload
            name="avatar"
            list-type="picture-card"
            class="avatar-uploader"
            :show-upload-list="false"
            @preview="handlePreview"
            :customRequest="customUploadLogoPic"
            :before-upload="beforeUploadLogoPic"
          >
            <img v-if="logoPic" :src="logoPic" />
            <div v-else>
              <div style="margin-top: 1.875rem">
                <LoadingOutlined v-if="loading" />
                <PlusOutlined v-else style="font-size: 2.5rem" />
              </div>
              <div
                class="ant-upload-text flex"
                style="width: 180px; height: 100px; align-items: center; font-size: 0.5625rem"
              >
                支持.PNG、.JPG格式,建议尺寸为32*32px,大小不超过500KB</div
              >
            </div>
          </Upload>
        </template>
        <template #bgUpload>
          <Upload
            name="avatar"
            list-type="picture-card"
            class="avatar-uploader"
            :show-upload-list="false"
            :customRequest="customUploadBgPic"
            :before-upload="beforeUploadBgPic"
          >
            <img v-if="bgPic" :src="bgPic" alt="avatar" />
            <div v-else>
              <div style="margin-top: 1.875rem">
                <LoadingOutlined v-if="loading1" />
                <PlusOutlined v-else style="font-size: 2.5rem" />
              </div>
              <div
                class="ant-upload-text flex"
                style="width: 280px; height: 100px; align-items: center; font-size: 0.5625rem"
              >
                支持.PNG、.JPG格式,建议尺寸为1920*1080px,大小不超过2M</div
              >
            </div>
          </Upload>
        </template>
        <template #colorInput="{ model, field }"
          ><Input disabled v-model:value="model[field]">
            <template #prefix> <input type="color" v-model="model[field]" /> </template
          ></Input>
        </template>

        <template #homeSwiper>
          <Upload
            v-model:file-list="fileList"
            list-type="picture-card"
            @preview="handlePreview"
            :customRequest="customUploadHomeSwiper"
            :before-upload="beforeUploadHomeSwiper"
            @change="handleChange"
          >
            <div v-if="fileList.length < 5">
              <div style="margin-top: 1.875rem">
                <PlusOutlined style="font-size: 2.5rem" />
              </div>
              <div
                class="ant-upload-text flex"
                style="width: 150px; height: 70px; align-items: center; font-size: 0.5625rem"
                >支持.PNG、.JPG格式,建议尺寸为800*600px,大小不超过3M</div
              >
            </div>
          </Upload>
          <Modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
            <img alt="example" style="width: 100%" :src="previewImage" />
          </Modal>
        </template>
      </BasicForm>
    </Card>
    <Loading v-bind="compState" />
    <Authority value="api:yt:appDesign:update:update">
      <a-button @click="handleUpdateInfo" type="primary" class="mt-4">保存信息</a-button>
    </Authority>
    <Authority value="api:yt:appDesign:data_reset:reset">
      <a-button @click="handleResetInfo" type="primary" class="ml-4">恢复默认设置</a-button>
    </Authority>
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, unref, onMounted } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { Loading } from '/@/components/Loading/index';
  import { Card, Upload, Input, Modal } from 'ant-design-vue';
  import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
  import { schemas } from '../config/AppDraw.config';
  import { FileItem, FileInfo } from '../types/index';
  import { logoUpload, bgUpload, resetAppInfo } from '/@/api/oem/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { getAppDesign, updateAppDesign } from '/@/api/oem/index';
  import { Authority } from '/@/components/Authority';

  export default defineComponent({
    components: {
      Card,
      BasicForm,
      Upload,
      Loading,
      PlusOutlined,
      Input,
      Modal,
      Authority,
      LoadingOutlined,
    },
    setup() {
      const loading = ref(false);
      const loading1 = ref(false);
      const compState = ref({
        absolute: false,
        loading: false,
        tip: '拼命加载中...',
      });
      const { createMessage } = useMessage();
      const [registerForm, { getFieldsValue, setFieldsValue, resetFields }] = useForm({
        schemas,
        showSubmitButton: false,
        showResetButton: false,
        labelWidth: 150,
        wrapperCol: {
          span: 10,
        },
      });
      const previewVisible = ref<boolean>(false);
      const previewImage = ref<string | undefined>('');
      function getBase64(file: File) {
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = () => resolve(reader.result);
          reader.onerror = (error) => reject(error);
        });
      }
      const handleCancel = () => {
        previewVisible.value = false;
      };
      const handlePreview = async (file: FileItem) => {
        if (!file.url && !file.preview) {
          file.preview = (await getBase64(file.originFileObj)) as string;
        }
        previewImage.value = file.url || file.preview;
        previewVisible.value = true;
      };

      // logo图片上传
      const logoPic = ref();
      async function customUploadLogoPic({ file }) {
        if (beforeUploadLogoPic(file)) {
          logoPic.value = '';
          loading.value = true;
          const formData = new FormData();
          formData.append('file', file);
          const response = await logoUpload(formData);
          if (response.fileStaticUri) {
            logoPic.value = response.fileStaticUri;
            loading.value = false;
          }
        }
      }
      const beforeUploadLogoPic = (file) => {
        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
        if (!isJpgOrPng) {
          createMessage.error('只能上传图片文件!');
        }
        const isLt2M = (file.size as number) / 1024 < 500;
        if (!isLt2M) {
          createMessage.error('图片大小不能超过500KB!');
        }
        return isJpgOrPng && isLt2M;
      };

      // 登录页背景上传
      const bgPic = ref();
      async function customUploadBgPic({ file }) {
        if (beforeUploadBgPic(file)) {
          bgPic.value = '';
          loading1.value = true;
          const formData = new FormData();
          formData.append('file', file);
          const response = await bgUpload(formData);
          if (response.fileStaticUri) {
            bgPic.value = response.fileStaticUri;
            loading1.value = false;
          }
        }
      }
      const beforeUploadBgPic = (file) => {
        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
        if (!isJpgOrPng) {
          createMessage.error('只能上传图片文件!');
        }
        const isLt2M = (file.size as number) / 1024 / 1024 < 2;
        if (!isLt2M) {
          createMessage.error('图片大小不能超过2MB!');
        }
        return isJpgOrPng && isLt2M;
      };
      // 首页轮播图
      const fileList = ref<FileItem[]>([]);
      async function customUploadHomeSwiper({ file }) {
        if (beforeUploadHomeSwiper(file)) {
          const formData = new FormData();
          formData.append('file', file);
          const response = await bgUpload(formData);
          if (response.fileStaticUri) {
            fileList.value.push({
              uid: -Math.random() + '',
              name: response.fileName,
              status: 'done',
              url: response.fileStaticUri,
            });
            const fileArr = fileList.value.filter((item) => {
              return item.percent !== 0;
            });
            fileList.value = fileArr;
          }
        }
      }

      const beforeUploadHomeSwiper = (file) => {
        const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
        if (!isJpgOrPng) {
          createMessage.error('只能上传图片文件!');
        }
        const isLt2M = (file.size as number) / 1024 / 1024 < 3;
        if (!isLt2M) {
          createMessage.error('图片大小不能超过3MB!');
        }
        return isJpgOrPng && isLt2M;
      };
      const handleChange = (info: FileInfo) => {
        if (info.file.status !== 'uploading') {
          fileList.value = info.fileList.filter((f: any) => !f.size);
        }
      };

      const handleUpdateInfo = async () => {
        try {
          const fieldValue = getFieldsValue();
          // 做换字段
          const homeSwiper = fileList.value.map((item) => item.url);
          const rotation = homeSwiper.join(',');

          compState.value.loading = true;
          await updateAppDesign({
            ...fieldValue,
            background: unref(bgPic),
            icon: unref(bgPic),
            logo: unref(logoPic),
            rotation,
          });
          compState.value.loading = false;
          createMessage.success('保存信息成功');
        } catch (e) {
          createMessage.error('保存信息失败');
        }
      };

      onMounted(async () => {
        const res = await getAppDesign();
        const rotation = res.rotation ? res.rotation.split(',') : [];
        const arr: any[] = [];
        for (let item of rotation) {
          arr.push({
            uid: -Math.random() + '',
            name: '111',
            url: item,
            status: 'done',
          });
        }
        setFieldsValue(res);
        logoPic.value = res.logo;
        bgPic.value = res.background;
        if (arr[0]?.url === '') return;
        fileList.value = arr;
      });
      const handleResetInfo = async () => {
        try {
          compState.value.loading = true;
          await resetAppInfo();
          compState.value.loading = false;
          createMessage.success('恢复出厂设置成功');
          resetFields();
          const res = await getAppDesign();
          const rotation = res.rotation ? res.rotation.split(',') : [];
          const arr: any[] = [];
          for (let item of rotation) {
            arr.push({
              uid: -Math.random() + '',
              name: '111',
              url: item,
              status: 'done',
            });
          }
          setFieldsValue(res);
          logoPic.value = res.logo;
          bgPic.value = res.background;
          if (arr[0]?.url === '') return;
          fileList.value = arr;
        } catch (e) {
          compState.value.loading = false;
          createMessage.error('恢复出厂设置失败');
        }
      };
      return {
        compState,
        fileList,
        registerForm,
        handleUpdateInfo,
        handleCancel,
        handlePreview,
        customUploadLogoPic,
        beforeUploadLogoPic,
        customUploadBgPic,
        beforeUploadBgPic,
        customUploadHomeSwiper,
        beforeUploadHomeSwiper,
        handleChange,
        logoPic,
        bgPic,
        previewVisible,
        previewImage,
        loading,
        loading1,
        handleResetInfo,
      };
    },
  });
</script>

<style lang="less" scoped>
  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
  }
</style>