通过上传图片组件向OSS服务器上传图片之后没有回写图片路径, 提交保存资料的时候gql response显示图片路径是null

来源:9-19 编写门店列表和新增编辑页面(下)

阜東原

2024-02-26

老师好, 这一节修改了上传组件之后, 在个人信息页面上传照片, 不会回写照片保存地址.
通过上传图片组件向OSS服务器上传图片之后没有回写图片路径, 提交保存资料的时候gql response显示图片路径是null.

// 上传图片组件
import { useRef } from 'react';
import { useQuery } from '@apollo/client';
import type { UploadProps } from 'antd';
import { Upload } from 'antd';
import ImgCrop from 'antd-img-crop';
import type { UploadFile } from 'antd/es/upload/interface';
import { GET_OSS_INFO } from '@graphql/oss';

interface OSSDataType {
  dir: string;
  expire: string;
  host: string;
  accessId: string;
  policy: string;
  signature: string;
}

interface AliyunOSSUploadProps {
  value?: UploadFile[];
  label?: string,
  maxCount?: number,
  imgCropAspect?: number,
  onChange?: (file?: UploadFile[]) => void;
}

const AliyunOSSUpload = ({
  value, onChange, label, maxCount, imgCropAspect,
}: AliyunOSSUploadProps) => {
  const key = useRef('');
  const { data, refetch } = useQuery<{ getOSSInfo: OSSDataType }>(GET_OSS_INFO);

  const OSSData = data?.getOSSInfo;

  const handleChange: UploadProps['onChange'] = ({ fileList }) => {
    const files = fileList.map((file) => (
      {
        ...file,
        url: `${OSSData?.host}/${key.current}`,
      }
    ));
    onChange?.(files);
  };

  const getExtraData: UploadProps['data'] = (file) => {
    const suffix = file.name.slice(file.name.lastIndexOf('.'));
    const filename = Date.now() + suffix;
    key.current = `${OSSData?.dir}${filename}`;
    return {
      key: key.current,
      OSSAccessKeyId: OSSData?.accessId,
      policy: OSSData?.policy,
      Signature: OSSData?.signature,
    };
  };

  const beforeUpload: UploadProps['beforeUpload'] = async (file) => {
    if (!OSSData) return false;
    const expire = Number(OSSData.expire) * 1000;
    if (expire < Date.now()) {
      await refetch();
    }
    return file;
  };

  return (
    <ImgCrop rotationSlider aspect={imgCropAspect}>
      <Upload
        name="file"
        listType="picture-card"
        // fileList={value ? [value] : []}
        fileList={value}
        action={OSSData?.host}
        onChange={handleChange}
        data={getExtraData}
        beforeUpload={beforeUpload}
        maxCount={maxCount}
      >
        {label}
      </Upload>
    </ImgCrop>
  );
};

AliyunOSSUpload.defaultProps = {
  value: null,
  onChange: () => {},
  label: '上传图片',
  maxCount: 1,
  imgCropAspect: 1,
};

export default AliyunOSSUpload;
// 个人信息编辑
import { useEffect, useRef } from 'react';
import { useMutation } from '@apollo/client';
import {
  PageContainer, ProForm, ProFormInstance, ProFormText, ProFormTextArea,
} from '@ant-design/pro-components';
import {
  Col, Form, Row,
} from 'antd';
import { Toaster, toast } from 'sonner';
import { AliyunOSSUpload } from '@components/OSSImageUpload';
import { useUserInfoContext } from '@hooks/useUserInfo';
import { UPDATE_USER_INFO } from '@graphql/user';

const My = () => {
  const { store: user } = useUserInfoContext();
  const formRef = useRef<ProFormInstance>();

  const [updateUserInfo] = useMutation(UPDATE_USER_INFO);

  useEffect(() => {
    if (!user.phoneNumber) return;
    formRef.current?.setFieldsValue({
      phoneNumber: user.phoneNumber,
      username: user.username,
      desc: user.desc,
      avatar: [{ url: user.avatar }],
    });
  }, [user]);

  return (
    <PageContainer>
      <Toaster richColors position="top-center" />
      <ProForm
        formRef={formRef}
        layout="horizontal"
        submitter={{
          resetButtonProps: {
            style: { display: 'none' },
          },
        }}
        onFinish={async (values) => {
          const {
            username, phoneNumber, desc, avatar,
          } = values;

          const { data: { updateUserInfo: { statusCode, message: msg } } } = await updateUserInfo({
            variables: {
              id: user.id,
              params: {
                username,
                phoneNumber,
                desc,
                avatar: avatar?.url,
              },
            },
          });
          if (statusCode === 200) {
            toast.success(msg);
            user.refetch?.();
            return;
          }
          toast.error(msg);
        }}
      >
        <Row gutter={20}>
          <Col>
            <ProFormText
              required
              name="username"
              label="用户名"
              placeholder="请输入用户名"
            />
            <ProFormText
              name="phoneNumber"
              label="手机号码"
              tooltip="暂不允许修改"
              disabled
            />
            <ProFormTextArea
              name="desc"
              label="简介"
              placeholder="请输入您的简介"
            />
          </Col>
          <Col>
            <Form.Item name="avatar">
              <AliyunOSSUpload label="上传头像" maxCount={1} />
            </Form.Item>
          </Col>
        </Row>
      </ProForm>
    </PageContainer>
  );
};

export default My;
写回答

1回答

阜東原

提问者

2024-02-26

找到问题了, 是My.tsx的Proform组件中更新用户信息的头像字段的值没有更新.

avatar: avatar?.url => avatar: avatar[0].url || '' 

1
0

React18+TS+NestJS+GraphQL 全栈开发在线教育平台

平台级应用+流行全栈技术+实用职场技巧&面试策略 助你升职加薪

439 学习 · 242 问题

查看课程