Browse Source

feat: 应用图片和安装包直接上传

lihao
nili 6 months ago
parent
commit
2762f0e947
  1. 90
      dist/247.3fe8fb10.async.js
  2. 21
      dist/417.ef345f0b.async.js
  3. 70
      dist/886.6c2624b2.async.js
  4. 4
      dist/index.html
  5. 1
      dist/p__App__AppManagement.3d27b19d.async.js
  6. 1
      dist/p__App__AppManagement.c0407dd6.async.js
  7. 1
      dist/p__SuperAdmin.2c0b0908.async.js
  8. 1
      dist/p__SuperAdmin.e98ce7d0.async.js
  9. 68
      dist/umi.1e97a9b1.js
  10. 29
      src/pages/App/AppBasicConfigForm.tsx
  11. 5
      src/pages/App/NormalAppManagement.tsx
  12. 50
      src/pages/OSSUpload.tsx
  13. 124
      src/pages/OSSUploadDragger.tsx
  14. 8
      src/pages/SuperAdmin.tsx

90
dist/247.3fe8fb10.async.js

File diff suppressed because one or more lines are too long

21
dist/417.ef345f0b.async.js

File diff suppressed because one or more lines are too long

70
dist/886.6c2624b2.async.js

File diff suppressed because one or more lines are too long

4
dist/index.html

@ -7,10 +7,10 @@
<title>Ant Design Pro</title>
<link rel="stylesheet" href="/umi.1ca9308c.css">
<script async src="/scripts/loading.js"></script>
<script>!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["51.e174e29e.async.js",51],["63.d3cf24e7.async.js",63],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["235.f7c67994.async.js",235],["258.355f303f.async.js",258],["287.b21721be.async.js",287],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.afe80231.async.js",301],["335.a2e08496.async.js",335],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.0a01face.async.js",371],["390.41467286.async.js",390],["393.b64a7324.async.js",393],["397.fb5f72c1.async.js",397],["417.ef345f0b.async.js",417],["p__SuperAdmin.e98ce7d0.async.js",455],["531.7b55d7f6.async.js",531],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.477947e4.async.js",635],["p__App__AppManagement.c0407dd6.async.js",731],["p__AdminManagement.292eeeb2.async.js",816],["p__AdvRecordList.58dfb141.async.js",857],["886.6c2624b2.async.js",886],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930]],"r":{"/*":[21,27],"/":[2,8,9,20,22,27],"/welcome":[2,3,4,14,20,28,8,9,22,27],"/super":[0,1,2,3,5,16,17,26,28,8,9,20,22,27],"/adminList":[0,3,5,7,24,2,8,9,20,22,27],"/bind":[2,3,14,15,19,20,28,8,9,22,27],"/appList":[0,1,2,3,5,7,10,15,16,18,23,27,28,8,9,20,22],"/advList/:code":[0,1,2,3,5,6,7,10,18,20,25,27,28,8,9,22],"/app/:code":[0,1,2,3,5,6,7,10,12,18,20,27,28,8,9,22],"/user/login":[1,2,3,5,7,11,18]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}();</script>
<script>!function(){"use strict";var t="/".replace(/([^/])$/,"$1/"),e=location.pathname,n=e.startsWith(t)&&decodeURI("/".concat(e.slice(t.length)));if(n){var a=document,c=a.head,r=a.createElement.bind(a),i=function(t,e,n){var a,c=e.r[t]||(null===(a=Object.entries(e.r).find((function(e){var n=e[0];return new RegExp("^".concat(n.replace(/\/:[^/]+/g,"/[^/]+").replace("/*","/.+"),"$")).test(t)})))||void 0===a?void 0:a[1]);return null==c?void 0:c.map((function(t){var a=e.f[t][1],c=e.f[t][0];return{type:c.split(".").pop(),url:"".concat(n.publicPath).concat(c),attrs:[["data-".concat(e.b),"".concat(e.p,":").concat(a)]]}}))}(n,{"p":"ant-design-pro","b":"webpack","f":[["51.e174e29e.async.js",51],["63.d3cf24e7.async.js",63],["134.6fc81d91.async.js",134],["169.57647c7d.async.js",169],["p__Welcome.61596037.async.js",185],["235.f7c67994.async.js",235],["247.3fe8fb10.async.js",247],["258.355f303f.async.js",258],["287.b21721be.async.js",287],["t__plugin-layout__Layout.6cae69f5.chunk.css",301],["t__plugin-layout__Layout.afe80231.async.js",301],["335.a2e08496.async.js",335],["p__User__Login__index.9d3ab92e.async.js",366],["p__DeviceOwnerApp.0a01face.async.js",371],["390.41467286.async.js",390],["393.b64a7324.async.js",393],["397.fb5f72c1.async.js",397],["p__SuperAdmin.2c0b0908.async.js",455],["531.7b55d7f6.async.js",531],["p__Bind.b6ee068f.async.js",557],["559.016bfdbb.async.js",559],["p__404.0c100574.async.js",571],["635.477947e4.async.js",635],["p__App__AppManagement.3d27b19d.async.js",731],["p__AdminManagement.292eeeb2.async.js",816],["p__AdvRecordList.58dfb141.async.js",857],["905.6e225d1b.async.js",905],["930.fca7adbf.async.js",930]],"r":{"/*":[21,26],"/":[2,9,10,20,22,26],"/welcome":[2,3,4,15,20,27,9,10,22,26],"/super":[0,1,2,3,5,6,17,27,9,10,20,22,26],"/adminList":[0,3,5,8,24,2,9,10,20,22,26],"/bind":[2,3,15,16,19,20,27,9,10,22,26],"/appList":[0,1,2,3,5,6,8,11,16,18,23,26,27,9,10,20,22],"/advList/:code":[0,1,2,3,5,7,8,11,18,20,25,26,27,9,10,22],"/app/:code":[0,1,2,3,5,7,8,11,13,18,20,26,27,9,10,22],"/user/login":[1,2,3,5,8,12,18]}},{publicPath:"/"});null==i||i.forEach((function(t){var e,n=t.type,a=t.url;if("js"===n)(e=r("script")).src=a,e.async=!0;else{if("css"!==n)return;(e=r("link")).href=a,e.rel="preload",e.as="style"}t.attrs.forEach((function(t){e.setAttribute(t[0],t[1]||"")})),c.appendChild(e)}))}}();</script>
</head>
<body>
<div id="root"></div>
<script src="/umi.17046495.js"></script>
<script src="/umi.1e97a9b1.js"></script>
</body>
</html>

1
dist/p__App__AppManagement.3d27b19d.async.js

File diff suppressed because one or more lines are too long

1
dist/p__App__AppManagement.c0407dd6.async.js

File diff suppressed because one or more lines are too long

1
dist/p__SuperAdmin.2c0b0908.async.js

File diff suppressed because one or more lines are too long

1
dist/p__SuperAdmin.e98ce7d0.async.js

File diff suppressed because one or more lines are too long

68
dist/umi.17046495.js → dist/umi.1e97a9b1.js

File diff suppressed because one or more lines are too long

29
src/pages/App/AppBasicConfigForm.tsx

@ -1,6 +1,7 @@
import { Form, Input, Modal, Select } from 'antd';
import React, { useEffect, useState } from 'react';
import { getBasicConfig, saveBasicConfig } from '../../services/matrix/matrixAppConfigController';
import OSSUpload from '../OSSUpload';
export type AppBasicConfigFormProps = {
onCancel: () => void;
@ -49,7 +50,7 @@ const AppBasicConfigForm: React.FC<AppBasicConfigFormProps> = (props) => {
return (
<Modal title="编辑" visible={props.updateModalOpen} onOk={handleOk} onCancel={handleCancel}>
<Form form={form} onFinish={handleSaveApp}>
<Form labelCol={{ span: 5 }} wrapperCol={{ span: 18 }} form={form} onFinish={handleSaveApp}>
<Form.Item name="id" style={{ display: 'none' }}>
<Input type="hidden" />
</Form.Item>
@ -60,11 +61,37 @@ const AppBasicConfigForm: React.FC<AppBasicConfigFormProps> = (props) => {
<Input />
</Form.Item>
<Form.Item label="应用图片" name="img">
<Input.Group compact>
<Form.Item
name="img"
noStyle
rules={[{ required: true, message: '请输入图片地址或选择图片上传!' }]}
>
<Input />
</Form.Item>
<OSSUpload
onUploadSuccess={(url: string) => {
form.setFieldsValue({ img: url });
}}
/>
</Input.Group>
</Form.Item>
<Form.Item label="下载地址" name="url">
<Input.Group compact>
<Form.Item
name="url"
noStyle
rules={[{ required: true, message: '请输入下载地址或选择安装包上传!' }]}
>
<Input />
</Form.Item>
<OSSUpload
onUploadSuccess={(url: string) => {
form.setFieldsValue({ url: url });
}}
/>
</Input.Group>
</Form.Item>
<Form.Item label="app版本" name="version">
<Input />
</Form.Item>

5
src/pages/App/NormalAppManagement.tsx

@ -13,6 +13,11 @@ const NormalAppManagement = () => {
const [appCode, setAppCode] = useState<string>();
const handleSearch = (value: string) => {
const filtered = appArr.filter((item) => item?.name?.includes(value));
setFilteredAppArr(filtered);
};
const columns: ProColumns<API.MatrixAppBo>[] = [
{
title: '应用名',

50
src/pages/OSSUpload.tsx

@ -1,6 +1,7 @@
import { toMD5 } from '@/utils/encryptUtil';
import { InboxOutlined } from '@ant-design/icons';
import OSS from 'ali-oss';
import { message, Upload, UploadFile, UploadProps } from 'antd';
import { Button, message, Upload, UploadProps } from 'antd';
import React, { useEffect, useState } from 'react';
import { getSts } from '../services/matrix/admin';
@ -11,9 +12,7 @@ interface OSSUploadProps {
const OSSUpload: React.FC<OSSUploadProps> = ({ onUploadSuccess, onUploadError }) => {
const [uploading, setUploading] = useState(false);
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [ossClient, setOssClient] = useState<OSS | null>(null);
const { Dragger } = Upload;
useEffect(() => {
async function initOssClient() {
@ -45,11 +44,6 @@ const OSSUpload: React.FC<OSSUploadProps> = ({ onUploadSuccess, onUploadError })
initOssClient();
}, [onUploadError]);
const onRemove = (file: UploadFile) => {
const files = (fileList || []).filter((v) => v.url !== file.url);
setFileList(files);
};
const handleUpload: UploadProps['customRequest'] = async (options) => {
const { file } = options;
if (file instanceof File) {
@ -69,29 +63,11 @@ const OSSUpload: React.FC<OSSUploadProps> = ({ onUploadSuccess, onUploadError })
onUploadSuccess(fileUrl);
}
setUploading(false);
// 将上传成功的文件信息添加到 fileList
setFileList((prevFileList) => [
...prevFileList,
{
uid: file.uid,
name: file.name + ':' + fileUrl,
status: 'done',
url: fileUrl,
},
]);
} catch (error) {
message.error('文件上传失败');
if (onUploadError) {
onUploadError(error);
}
setFileList((prevFileList) => [
...prevFileList,
{
uid: file.uid,
name: file.name,
status: 'error',
},
]);
} finally {
setUploading(false);
}
@ -101,23 +77,11 @@ const OSSUpload: React.FC<OSSUploadProps> = ({ onUploadSuccess, onUploadError })
};
return (
<Dragger
fileList={fileList}
multiple
customRequest={handleUpload}
onRemove={onRemove}
disabled={uploading || !ossClient}
onPreview={async (file) => {
await navigator.clipboard.writeText(file.url || '');
message.success('链接复制成功 ' + file.url);
}}
>
<p className="ant-upload-drag-icon">
<i className="anticon anticon-inbox" />
</p>
<p className="ant-upload-text"></p>
<p className="ant-upload-hint">使 MD5 </p>
</Dragger>
<Upload showUploadList={false} customRequest={handleUpload} disabled={uploading || !ossClient}>
<Button style={{ marginTop: 10 }} type="primary" icon={<InboxOutlined />}>
</Button>
</Upload>
);
};

124
src/pages/OSSUploadDragger.tsx

@ -0,0 +1,124 @@
import { toMD5 } from '@/utils/encryptUtil';
import OSS from 'ali-oss';
import { message, Upload, UploadFile, UploadProps } from 'antd';
import React, { useEffect, useState } from 'react';
import { getSts } from '../services/matrix/admin';
interface OSSUploadProps {
onUploadSuccess?: (fileUrl: string) => void;
onUploadError?: (error: any) => void;
}
const OSSUploadDragger: React.FC<OSSUploadProps> = ({ onUploadSuccess, onUploadError }) => {
const [uploading, setUploading] = useState(false);
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [ossClient, setOssClient] = useState<OSS | null>(null);
const { Dragger } = Upload;
useEffect(() => {
async function initOssClient() {
try {
const stsResponse = await getSts(); // 假设你有一个 getSTS 函数可以获取 STS 凭证
if (
!stsResponse.data ||
!stsResponse.data.accessKeySecret ||
!stsResponse.data.accessKeyId
) {
message.error('初始化失败,请稍后再试');
return;
}
const client = new OSS({
region: 'oss-cn-beijing',
accessKeyId: stsResponse.data.accessKeyId,
accessKeySecret: stsResponse.data.accessKeySecret,
stsToken: stsResponse.data.securityToken,
bucket: stsResponse.data.bucket,
});
setOssClient(client);
} catch (error) {
message.error('初始化 OSS 客户端失败');
if (onUploadError) {
onUploadError(error);
}
}
}
initOssClient();
}, [onUploadError]);
const onRemove = (file: UploadFile) => {
const files = (fileList || []).filter((v) => v.url !== file.url);
setFileList(files);
};
const handleUpload: UploadProps['customRequest'] = async (options) => {
const { file } = options;
if (file instanceof File) {
setUploading(true);
try {
const md5 = await toMD5(file);
const fileName = `matrix/${md5}.${file.name.split('.').pop()}`;
await ossClient?.put(fileName, file, {
headers: {
'Content-Type': file.type,
},
});
const fileUrl = `https://apks.bzgames.cn/${fileName}`;
if (onUploadSuccess) {
onUploadSuccess(fileUrl);
}
setUploading(false);
// 将上传成功的文件信息添加到 fileList
setFileList((prevFileList) => [
...prevFileList,
{
uid: file.uid,
name: file.name + ':' + fileUrl,
status: 'done',
url: fileUrl,
},
]);
} catch (error) {
message.error('文件上传失败');
if (onUploadError) {
onUploadError(error);
}
setFileList((prevFileList) => [
...prevFileList,
{
uid: file.uid,
name: file.name,
status: 'error',
},
]);
} finally {
setUploading(false);
}
} else {
message.error('上传文件类型错误');
}
};
return (
<Dragger
fileList={fileList}
multiple
customRequest={handleUpload}
onRemove={onRemove}
disabled={uploading || !ossClient}
onPreview={async (file) => {
await navigator.clipboard.writeText(file.url || '');
message.success('链接复制成功 ' + file.url);
}}
>
<p className="ant-upload-drag-icon">
<i className="anticon anticon-inbox" />
</p>
<p className="ant-upload-text"></p>
<p className="ant-upload-hint">使 MD5 </p>
</Dragger>
);
};
export default OSSUploadDragger;

8
src/pages/SuperAdmin.tsx

@ -26,7 +26,7 @@ import TabPane from 'antd/es/tabs/TabPane';
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import OSSUpload from './OSSUpload';
import OSSUploadDragger from './OSSUploadDragger';
// import { RequestOptionsType, ProFieldRequestData } from "@ant-design/pro-utils";
@ -329,8 +329,8 @@ const SuperAdmin: React.FC = () => {
</Form.Item>
<MinusCircleOutlined
onClick={() => remove(name)}
onPointerEnterCapture={undefined}
onPointerLeaveCapture={undefined}
onPointerOverCapture={undefined}
onPointerMoveCapture={undefined}
/>
</div>
))}
@ -347,7 +347,7 @@ const SuperAdmin: React.FC = () => {
</div>
</TabPane>
<TabPane tab="上传资源" key="3">
<OSSUpload />
<OSSUploadDragger />
</TabPane>
</Tabs>
</PageContainer>

Loading…
Cancel
Save