上传的页面主要还是延续上一章的登录和注册样式,使用form
表单提交数据。目前仅考虑APP的上传,不涉及组件的上传。组件主要通过maven仓库进行管理。最后,通过服务器同步抓取maven数据来更新组件(正常的管理平台不会有这种操作)。”
- 上传的数据包括名称,包名,版本号,简介,业务线条(可不用),logo,Apk包,升级提示,联系人(用于找到实际对接人)。
- 上传的包和logo是通过异步的方式,需要自行处理相关地址并上传至服务器
- 上传页面可以包揽更新的能力,通过appId或者包名获取数据得到对应APP信息,用于自动填入已有信息
整个Upload
代码
import React, { useState, useEffect } from 'react';import './upload.css';import cookie from 'js-cookie';import { useNavigate, useSearchParams } from 'react-router-dom';import { Button, Upload, message, Form, Input } from 'antd';import { InboxOutlined, LoadingOutlined, PlusOutlined } from '@ant-design/icons';import { array } from 'js-md5';const userId = cookie.get("userId")//获取当前登录用户信息const { Dragger } = Upload;//获取Upload组件里的Dragger组件,实现可拖拽文件上传export default function UplaodPage () {//获取当前query里的id,如有 let [params] = useSearchParams(); const detailId = params.get("id"); const navigate = useNavigate(); const [form] = Form.useForm();//获取表单对象 const [fileInfo, setFileInfo] = useState({})//上传的app包路径 const [logoUrl, setLogoUrl] = useState({//上传的logo路径,加一个loading状态 loading: false, imageUrl: null }) //上传apk包后,解析完成后返回包名和名字,其实也可以把版本号也扔回来的 const changeValue = (extra) => { console.log(extra); form.setFieldsValue({ packageName: `${extra.package}`, name: `${extra.name}` }); }; //用于apk上传的行为 const props = { name: 'file', multiple: true, action: '/api/file/upload', maxCount: 1, onChange (info) { const { status } = info.file;//获取file状态 if (status !== 'uploading') {//上传中 console.log(info.file, info.fileList); } if (status === 'done') {//上传结束 message.success(`${info.file.name} 文件上传成功~`); setFileInfo(info.file.response.detail);//获取服务器返回数据 const extra = JSON.parse(info.file.response.detail.extraInfo);//json解析 changeValue(extra);//处理数据 } else if (status === 'error') { message.error(`${info.file.name} 文件上传失败~`); } }, onDrop (e) {//拖入数据 console.log('Dropped files', e.dataTransfer.files); }, progress: {//进度条类型 type: 'line' }, };//表单提交动作 const onFinish = (values: any) => { console.log(values) values.logoUrl = logoUrl.imageUrl//写入logo地址 values.downloadUrl = fileInfo.fileUrl//写入apk地址 values.userId = userId;//用户id fetch("/app/uploadAppInfo", { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(values), }) .then(response => response.json()) .then(json => { console.log(json) if (json.result === 0) { message.success('发布成功'); navigate('/') } else { message.error(json.resultNote) } }) .catch(e => console.log(e)); }; //logo上传数据处理 const handleChange = (info) => { if (info.file.status === 'uploading') { setLogoUrl({ loading: true }) return; } if (info.file.status === 'done') { setLogoUrl({ imageUrl: info.file.response.detail.fileUrl, loading: false }) } }; const layout = { labelCol: { span: 8, }, wrapperCol: { span: 16, }, }; const tailLayout = { wrapperCol: { offset: 8, span: 16, }, }; const uploadButton = (<div>{logoUrl.loading ? <LoadingOutlined /> : <PlusOutlined />}<div style={{ marginTop: 8 }}>Upload</div> </div> ); //请求具体数据用于回写表单,useEffect保证之请求一次,react里会执行很多次,可能会造成循环,所以建议跟随生命周期 useEffect(() => { if (detailId) { getDetail(detailId); } }, []); //请求数据 const getDetail = (id) => { fetch("/api/app/detail/" + id) .then(response => response.json()) .then(json => { if (json.result === 0 && json.detail.userId === userId) { const info = json.detail if(info.name){ //通过form对象设置数据,具体api参考antd--form form.setFieldsValue({ packageName: `${info.packageName}`, name: `${info.name}`, describe: `${info.describe}`, appVersion: `${info.appVersion}`, business: `${info.business}`, updateNote: `${info.updateNote}`, contact: `${info.contact}`, }); setLogoUrl({ imageUrl: info.logoUrl, loading: false }); } } else { if (userId) { message.error("出现了一些未知问题~"); } else { message.error("登录超时,请重新登录"); navigate("/"); } } }) .catch(e => console.log(e)) } return ( <div className='upload-main'> <Form {...layout} form={form} className='upload-form' onFinish={onFinish} scrollToFirstError > <Form.Item {...tailLayout}> <Dragger {...props} className='drag-container'> <p className="ant-upload-drag-icon"> <InboxOutlined /> </p> <p className="ant-upload-text">点击或拖拽APK到此区域上传</p> </Dragger> </Form.Item> <Form.Item name="packageName" label="包名" rules={[{ required: true, message: '请输入包名~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="name" label="名字" rules={[{ required: true, message: '请输入名称~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="logoUrl" label="logo" valuePropName='file' > <Upload name="file" listType="picture-card" className="avatar-uploader" showUploadList={false} action="/api/file/upload" beforeUpload={beforeUpload} onChange={handleChange} > {logoUrl.imageUrl ? <img src={logoUrl.imageUrl} style={{ width: '100%' }} /> : uploadButton} </Upload> </Form.Item> <Form.Item name="describe" label="简介" rules={[{ required: true, message: '请输入简介内容~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="appVersion" label="版本" rules={[{ required: true, message: '请输入版本号~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="business" label="业务线条" rules={[{ required: true, message: '请输入业务线条~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="updateNote" label="升级提示" rules={[{ required: true, message: '请输入提示语~~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item name="contact" label="联系方式" rules={[{ required: true, message: '请输入联系方式~', whitespace: true }]} > <Input /> </Form.Item> <Form.Item {...tailLayout}> <Button htmlType='submit' className='form-submit' type='primary'>提交</Button> </Form.Item> </Form> </div > )}function beforeUpload (file) { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { message.error('You can only upload JPG/PNG file!'); } const isLt10M = file.size / 1024 / 1024 < 10; if (!isLt10M) { message.error('Image must smaller than 10MB!'); } return isJpgOrPng && isLt10M;}
css内容
``` 请注意,以下是对您提供的代码段进行编辑后的结果: .upload-main { width: 100%; padding: 10px; } .upload-form { /* 在此处添加样式 */ } ```
版权声明:搭建盘口维护联系TG:@KT_code
还木有评论哦,快来抢沙发吧~