友情链接管理;封装上传接口
This commit is contained in:
@ -1,45 +0,0 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['UAT'],
|
||||
define:{
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL:'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY : 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET :'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE:'1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY:'0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
|
||||
//当前环境
|
||||
START_ENV:'UAT',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8280/provider_uat',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.158:18022/api/api/biz-customer-service',
|
||||
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:18022/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.gz-tst.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
},
|
||||
});
|
@ -3,43 +3,7 @@ import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['dev'],
|
||||
define: {
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL: 'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY: 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET: 'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE: '1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY: '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
|
||||
//当前环境
|
||||
START_ENV: 'DEV',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8080/provider_dev',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:8100/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632',
|
||||
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.37.148:18022/api/api/biz-customer-service',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.gz-tst.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
UPLOAD_URL: '/upload',
|
||||
REQUEST_BASE: '/api',
|
||||
},
|
||||
});
|
||||
|
@ -3,41 +3,7 @@ import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['prod'],
|
||||
define:{
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL:'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY : 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET :'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE:'1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY:'04819CF427F9150FEEBD91E8D2346F203FC47312D212022A967D8372EA30B9581CCEEFCE2670BDDAF2E8DA1620EA73948126078ED9FF9773AA3A94EE6C80035A18',
|
||||
|
||||
//当前环境
|
||||
START_ENV:'PROD',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'https://60.10.26.178/provider',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'https://uscm.chinaunicom.cn:18023/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'https://uscm.chinaunicom.cn:18011',
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://uscm.unicom.local:18022/api/api/biz-customer-service',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.xx-pbc.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
UPLOAD_URL: '/upload',
|
||||
REQUEST_BASE: '/api',
|
||||
},
|
||||
});
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import proxy from './proxy';
|
||||
export default defineConfig({
|
||||
proxy: proxy['sim'],
|
||||
define: {
|
||||
//商城2.0跳转地址
|
||||
REACT_APP_MALL_V2_URL: 'http://111.198.162.67/zglt/index_hzf.jsp?id=dev',
|
||||
|
||||
//各系统跳转参数
|
||||
REACT_APP_CLIENT_KEY: 'KgPEkttG',
|
||||
// REACT_APP_CLIENT_SECRET: 'ae5bdb183c502355d2055b3de73300aa73cbfdf3',
|
||||
|
||||
//密码加密参数
|
||||
REACT_APP_PASSWORD_CIPHERMODE: '1',
|
||||
REACT_APP_PASSWORD_PUBLICKEY: '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
|
||||
//当前环境
|
||||
START_ENV: 'sim',
|
||||
|
||||
//询价查看报价跳转地址
|
||||
// REACT_APP_XUNJIA_REDIRECT: 'http://10.0.204.215:8080/provider',
|
||||
//询价-查看报价详情-虚拟用户uid
|
||||
REACT_APP_XUNJIA_UID: 'admin_entrance',
|
||||
//智慧客服用户中心地址
|
||||
REACT_APP_CUSTOMERSERVICE_USERCENTER: 'http://10.242.31.158:8100/auth/oauth/authorize?response_type=code',
|
||||
|
||||
//智慧客服client_id
|
||||
REACT_APP_CUSTOMERSERVICE_CLIENT_ID: 'COsHJydx',
|
||||
|
||||
//智慧客服地址
|
||||
REACT_APP_CUSTOMERSERVICE_REDIRECT: 'http://10.242.31.158:8632',
|
||||
// //智慧客服ws地址
|
||||
// REACT_APP_CUSTOMERSERVICE_WS_REDIRECT: 'ws://10.242.31.54:18022/api/api/biz-customer-service',
|
||||
|
||||
// //智慧客服文档中心查看图片地址
|
||||
// REACT_APP_CUSTOMERSERVICE_DOC_REDIRECT: 'http://cos.xx-pbc.cos.tg.unicom.local/349553515466:mall/',
|
||||
|
||||
// //智慧客服加密公钥私钥ciphercode
|
||||
// REACT_APP_CUSTOMERSERVICE_PUBLICKEY : '0428D625CEEB71CE823BD7D78DFEE7B122F2DA5C4D21E32253AD684D0FE21810394A799639C0CDFBFEB535A1DFD6A366A637E582CE0B1466A5FE7858841135DE6B',
|
||||
// REACT_APP_CUSTOMERSERVICE_PRIVATEKEY : '4F7144028D4DCF88FA50F0E2B3FFDDCF63BBE17D1700537DCE037687D3AA3DA7',
|
||||
// REACT_APP_CUSTOMERSERVICE_CIPHERCODE : 1,
|
||||
},
|
||||
});
|
@ -1,8 +1,6 @@
|
||||
import { defineConfig } from 'umi';
|
||||
import defaultSettings,{antdTheme} from './defaultSettings';
|
||||
// import proxy from './proxy';
|
||||
import PageRoutes from './router.config'
|
||||
const { REACT_APP_ENV } = process.env;
|
||||
export default defineConfig({
|
||||
hash: true,
|
||||
antd: {
|
||||
|
@ -1,96 +1,20 @@
|
||||
export default {
|
||||
dev: {
|
||||
// '/api/wfap/v1/audit/bill/find/by/procid': {
|
||||
// target: 'http://10.242.37.148:8891/',//审批单 dev环境自动审批,暂时用不到
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
'/api': {
|
||||
// target: 'http://10.242.37.148:18022',//连接天宫的ng
|
||||
target: 'http://10.0.0.10:18013',//连接天宫的ng
|
||||
// target: 'http://10.242.37.148:18022',//
|
||||
target: 'http://10.0.0.10:18013',//
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^/api': '' },
|
||||
},
|
||||
},
|
||||
UAT: {
|
||||
'/api/core-service-ebtp-userinfo': {
|
||||
target: 'http://localhost:18023',
|
||||
'/upload': {
|
||||
target: 'http://10.0.0.10:18013',//
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/core-service-ebtp-userinfo': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-bid': {
|
||||
target: 'http://localhost:18003',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { 'biz-service-ebtp-bid': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-extend': {
|
||||
target: 'http://localhost:18018',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-extend': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-project': {
|
||||
target: 'http://localhost:18012',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-project': '' },
|
||||
},
|
||||
'/api/sys-manager-ebtp-project': {
|
||||
target: 'http://localhost:18030',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/sys-manager-ebtp-project': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-rsms': {
|
||||
target: 'http://localhost:18014',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-rsms': '' },
|
||||
},
|
||||
'/api/biz-service-ebtp-agency': {
|
||||
target: 'http://localhost:18099',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-service-ebtp-agency': '' },
|
||||
},
|
||||
'/api/biz-supplier-manage': {
|
||||
target: 'http://localhost:18096',
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '/api/biz-supplier-manage': '' },
|
||||
}
|
||||
|
||||
// '/api/wfap/v1/audit/bill/find/by/procid': {
|
||||
// target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
// '/living/api/*': {
|
||||
// // target: 'https://ai.cubigdata.cn:5001',//连接天宫的ng
|
||||
// target: 'http://localhost:3000',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '/living/api': '' },
|
||||
// },
|
||||
// '/api/*': {
|
||||
// target: 'http://10.242.31.158:18022',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
// '/doc/v1.0/*': {
|
||||
// target: 'http://10.242.31.158:8806',//连接天宫的ng
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
},
|
||||
sim: {
|
||||
// '/api/wfap/v1/audit/bill/find/by/procid': {
|
||||
// target: 'http://10.242.31.158:8891/',//审批单 uat环境自动审批,暂时用不到
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: { '^': '' },
|
||||
// },
|
||||
'/api/*': {
|
||||
target: 'http://10.242.31.54:18022',//连接天宫的ng
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^': '' },
|
||||
pathRewrite: { '^/upload': '' },
|
||||
},
|
||||
},
|
||||
prod: {
|
||||
'/api/*': {
|
||||
target: 'http://uscm.unicom.local:18022',//连接天宫的ng
|
||||
target: 'http://uscm.unicom.local:18022',//
|
||||
changeOrigin: true,
|
||||
pathRewrite: { '^': '' },
|
||||
},
|
||||
|
51
src/components/FileUpload/FileUpload.less
Normal file
51
src/components/FileUpload/FileUpload.less
Normal file
@ -0,0 +1,51 @@
|
||||
.file-upload-wrapper {
|
||||
.ant-upload-list {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.ant-upload-list-item-name {
|
||||
max-width: 300px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.ant-upload-select {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.file-upload-tip {
|
||||
margin-top: 8px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
|
||||
span {
|
||||
cursor: help;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-upload-drag {
|
||||
padding: 16px;
|
||||
|
||||
.ant-upload-drag-icon {
|
||||
margin-bottom: 8px;
|
||||
|
||||
.anticon {
|
||||
color: #40a9ff;
|
||||
font-size: 48px;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-upload-text {
|
||||
margin: 0 0 4px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ant-upload-hint {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
226
src/components/FileUpload/FileUpload.tsx
Normal file
226
src/components/FileUpload/FileUpload.tsx
Normal file
@ -0,0 +1,226 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Upload, Button, message, Tooltip } from 'antd';
|
||||
import { UploadOutlined, InboxOutlined } from '@ant-design/icons';
|
||||
import type { UploadFile, UploadProps } from 'antd/es/upload/interface';
|
||||
import { validateFileSize } from '@/utils/utils';
|
||||
import { useIntl } from 'umi';
|
||||
import './FileUpload.less';
|
||||
|
||||
export interface FileUploadProps {
|
||||
value?: UploadFile[];
|
||||
onChange?: (fileList: UploadFile[]) => void;
|
||||
maxCount?: number;
|
||||
maxSize?: number;
|
||||
allowedTypes?: string[];
|
||||
listType?: 'text' | 'picture' | 'picture-card';
|
||||
buttonText?: string;
|
||||
disabled?: boolean;
|
||||
accept?: string;
|
||||
showUploadList?:
|
||||
| boolean
|
||||
| { showPreviewIcon?: boolean; showRemoveIcon?: boolean; showDownloadIcon?: boolean };
|
||||
isDragger?: boolean;
|
||||
tip?: string;
|
||||
action?: string;
|
||||
}
|
||||
|
||||
// 上传接口返回数据格式
|
||||
interface UploadResponseData {
|
||||
fileName: string;
|
||||
fileSize: string;
|
||||
filePath: string;
|
||||
fileType: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
// API响应格式
|
||||
interface ApiResponse<T> {
|
||||
code: number;
|
||||
success: boolean;
|
||||
message: string;
|
||||
data: T;
|
||||
}
|
||||
|
||||
const FileUpload: React.FC<FileUploadProps> = ({
|
||||
value,
|
||||
onChange,
|
||||
maxCount = 1,
|
||||
maxSize = 5,
|
||||
allowedTypes = ['*'],
|
||||
listType = 'text',
|
||||
buttonText,
|
||||
disabled = false,
|
||||
accept,
|
||||
showUploadList = true,
|
||||
isDragger = false,
|
||||
tip,
|
||||
action,
|
||||
}) => {
|
||||
const actionUrl = action ? `${UPLOAD_URL}${action}` : `${UPLOAD_URL}/api/files/upload`;
|
||||
const intl = useIntl();
|
||||
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
||||
|
||||
// 监听value变化
|
||||
useEffect(() => {
|
||||
|
||||
// 处理字符串URL值(这是关键修复)
|
||||
if (typeof value === 'string' && value) {
|
||||
const file: Partial<UploadFile> = {
|
||||
uid: '-1',
|
||||
name: 'image.jpg',
|
||||
status: 'done',
|
||||
url: value,
|
||||
size: 0,
|
||||
type: 'image/jpeg',
|
||||
};
|
||||
setFileList([file as UploadFile]);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理空值
|
||||
if (!value || (Array.isArray(value) && value.length === 0)) {
|
||||
setFileList([]);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理正常的文件数组
|
||||
if (Array.isArray(value)) {
|
||||
setFileList(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理对象格式
|
||||
if (typeof value === 'object') {
|
||||
// 处理fileList属性
|
||||
if ('fileList' in value && Array.isArray((value as any).fileList)) {
|
||||
const files = (value as { fileList: UploadFile[] }).fileList;
|
||||
setFileList(files);
|
||||
return;
|
||||
}
|
||||
|
||||
// 尝试作为单个文件对象处理
|
||||
if ('uid' in value && 'status' in value) {
|
||||
setFileList([value as unknown as UploadFile]);
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn('FileUpload: Unrecognized object format', value);
|
||||
setFileList([]);
|
||||
return;
|
||||
}
|
||||
|
||||
// 无法识别的格式
|
||||
console.warn('FileUpload component: unrecognized value format:', value);
|
||||
setFileList([]);
|
||||
}, [value]);
|
||||
|
||||
const defaultButtonText = intl.formatMessage({
|
||||
id: 'component.fileUpload.buttonText',
|
||||
defaultMessage: '上传文件',
|
||||
});
|
||||
|
||||
// 处理上传接口返回的数据格式
|
||||
const getFileUrl = (file: UploadFile) => {
|
||||
// 如果response是API的标准响应格式
|
||||
if (file.response && typeof file.response === 'object') {
|
||||
// 首先检查是否是标准API响应格式
|
||||
if ('success' in file.response && 'data' in file.response) {
|
||||
const response = file.response as ApiResponse<UploadResponseData>;
|
||||
if (response.success && response.data) {
|
||||
return response.data.url;
|
||||
}
|
||||
}
|
||||
// 如果response直接包含url属性
|
||||
else if ('url' in file.response) {
|
||||
return (file.response as UploadResponseData).url;
|
||||
}
|
||||
}
|
||||
|
||||
// 回退到文件的url或thumbUrl
|
||||
return file.url || file.thumbUrl;
|
||||
};
|
||||
|
||||
const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
|
||||
const filteredList = newFileList.filter((file) => file.status !== 'error');
|
||||
|
||||
// 为每个文件添加正确的url
|
||||
const processedList = filteredList.map(file => {
|
||||
if (file.status === 'done' && file.response && !file.url) {
|
||||
return {
|
||||
...file,
|
||||
url: getFileUrl(file)
|
||||
};
|
||||
}
|
||||
return file;
|
||||
});
|
||||
|
||||
setFileList(processedList);
|
||||
|
||||
if (onChange) {
|
||||
onChange(processedList);
|
||||
}
|
||||
};
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
return validateFileSize(file, maxSize, allowedTypes);
|
||||
};
|
||||
|
||||
const UploadComponent = isDragger ? Upload.Dragger : Upload;
|
||||
|
||||
const uploadProps = {
|
||||
fileList,
|
||||
onChange: handleChange,
|
||||
beforeUpload,
|
||||
listType,
|
||||
maxCount,
|
||||
disabled,
|
||||
accept,
|
||||
showUploadList,
|
||||
action: actionUrl,
|
||||
};
|
||||
|
||||
const renderUploadButton = () => {
|
||||
if (fileList.length >= maxCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isDragger) {
|
||||
return (
|
||||
<>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<InboxOutlined />
|
||||
</p>
|
||||
<p className="ant-upload-text">
|
||||
{buttonText ||
|
||||
intl.formatMessage({
|
||||
id: 'component.fileUpload.dragText',
|
||||
defaultMessage: '点击或拖拽文件到此区域上传',
|
||||
})}
|
||||
</p>
|
||||
{tip && <p className="ant-upload-hint">{tip}</p>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button icon={<UploadOutlined />} disabled={disabled}>
|
||||
{buttonText || defaultButtonText}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="file-upload-wrapper">
|
||||
<UploadComponent {...uploadProps}>{renderUploadButton()}</UploadComponent>
|
||||
{!isDragger && tip && (
|
||||
<div className="file-upload-tip">
|
||||
<Tooltip title={tip}>
|
||||
<span>{tip}</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileUpload;
|
127
src/components/FileUpload/README.md
Normal file
127
src/components/FileUpload/README.md
Normal file
@ -0,0 +1,127 @@
|
||||
# FileUpload 文件上传组件
|
||||
|
||||
基于Ant Design Upload组件封装的文件上传组件,支持文件类型和大小校验。
|
||||
|
||||
## 组件特性
|
||||
|
||||
- 支持文件类型校验
|
||||
- 支持文件大小限制
|
||||
- 支持拖拽上传
|
||||
- 支持上传多个文件
|
||||
- 支持国际化
|
||||
- 支持自定义提示信息
|
||||
- 支持表单受控模式
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基本使用
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { Form } from 'antd';
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.Item
|
||||
name="files"
|
||||
label="上传文件"
|
||||
rules={[{ required: true, message: '请上传文件' }]}
|
||||
>
|
||||
<FileUpload maxSize={5} allowedTypes={['pdf', 'doc', 'docx']} />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
### 拖拽上传
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { Form } from 'antd';
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
import { useIntl } from 'umi';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
const intl = useIntl();
|
||||
|
||||
const fileTip = intl.formatMessage(
|
||||
{ id: 'component.fileUpload.fileTypeTip' },
|
||||
{ types: 'PDF, Word' }
|
||||
);
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.Item
|
||||
name="files"
|
||||
label="上传文件"
|
||||
rules={[{ required: true, message: '请上传文件' }]}
|
||||
>
|
||||
<FileUpload
|
||||
maxSize={10}
|
||||
allowedTypes={['pdf', 'doc', 'docx']}
|
||||
isDragger={true}
|
||||
tip={fileTip}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
### 图片上传
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { Form } from 'antd';
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
return (
|
||||
<Form form={form}>
|
||||
<Form.Item
|
||||
name="images"
|
||||
label="上传图片"
|
||||
rules={[{ required: true, message: '请上传图片' }]}
|
||||
>
|
||||
<FileUpload
|
||||
maxSize={2}
|
||||
allowedTypes={['jpg', 'png']}
|
||||
listType="picture-card"
|
||||
tip="支持jpg, png格式,大小不超过2MB"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| value | 文件列表 | UploadFile[] | [] |
|
||||
| onChange | 文件列表改变时的回调 | (fileList: UploadFile[]) => void | - |
|
||||
| maxCount | 最大上传数量 | number | 1 |
|
||||
| maxSize | 文件大小限制(MB) | number | 5 |
|
||||
| allowedTypes | 允许的文件类型 | string[] | ['*'] |
|
||||
| listType | 上传列表的样式 | 'text' \| 'picture' \| 'picture-card' | 'text' |
|
||||
| buttonText | 上传按钮文字 | string | '上传文件' |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
| accept | 接受的文件类型 | string | - |
|
||||
| showUploadList | 是否展示文件列表 | boolean \| { showPreviewIcon?: boolean; showRemoveIcon?: boolean; showDownloadIcon?: boolean } | true |
|
||||
| isDragger | 是否启用拖拽上传 | boolean | false |
|
||||
| tip | 提示文字 | string | - |
|
4
src/components/FileUpload/index.ts
Normal file
4
src/components/FileUpload/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import FileUpload from './FileUpload';
|
||||
|
||||
export default FileUpload;
|
||||
export type { FileUploadProps } from './FileUpload';
|
@ -1,5 +1,9 @@
|
||||
import { useIntl } from 'umi';
|
||||
|
||||
export enum LinkStatusMap {
|
||||
ENABLED = '0',
|
||||
DISABLED = '1',
|
||||
}
|
||||
export const useFriendLinkDict = () => {
|
||||
const intl = useIntl();
|
||||
|
||||
@ -7,11 +11,11 @@ export const useFriendLinkDict = () => {
|
||||
const linkStatusOptions = [
|
||||
{
|
||||
label: intl.formatMessage({ id: 'friendLink.enabled' }),
|
||||
value: '1',
|
||||
value: LinkStatusMap.ENABLED,
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage({ id: 'friendLink.disabled' }),
|
||||
value: '0',
|
||||
value: LinkStatusMap.DISABLED,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -31,4 +31,13 @@ export default {
|
||||
// Buttons
|
||||
"common.confirm": "Confirm",
|
||||
"common.cancel": "Cancel",
|
||||
|
||||
// FileUpload component
|
||||
'component.fileUpload.buttonText': 'Upload File',
|
||||
'component.fileUpload.dragText': 'Click or drag file to this area to upload',
|
||||
'component.fileUpload.fileTypeTip': 'Supported file types: {types}',
|
||||
'component.fileUpload.fileSizeTip': 'File size should not exceed {size}MB',
|
||||
'component.fileUpload.uploadFailed': 'Upload failed',
|
||||
'component.fileUpload.parseError': 'Failed to parse response',
|
||||
'component.fileUpload.networkError': 'Network error',
|
||||
};
|
||||
|
@ -51,6 +51,7 @@ export default {
|
||||
'friendLink.enable.confirm.content': 'Are you sure you want to enable this link?',
|
||||
'friendLink.disable.confirm.title': 'Disable Confirmation',
|
||||
'friendLink.disable.confirm.content': 'Are you sure you want to disable this link?',
|
||||
'friendLink.detail.failed': 'Failed to get link details',
|
||||
|
||||
// Friendly Link Category Management
|
||||
'friendLink.category.title': 'Friendly Link Category Management',
|
||||
|
@ -22,6 +22,7 @@ export default {
|
||||
'helpManage.cancel': 'Cancel',
|
||||
'helpManage.confirmDelete': 'Are you sure you want to delete this help item?',
|
||||
'helpManage.batchDelete': 'Are you sure you want to delete the selected help items?',
|
||||
'helpManage.batchDeleteButton': 'Batch Delete',
|
||||
'helpManage.confirmPublish': 'Are you sure you want to publish this help item?',
|
||||
'helpManage.confirmUnpublish': 'Are you sure you want to unpublish this help item?',
|
||||
'helpManage.confirmTop': 'Are you sure you want to top this help item?',
|
||||
|
@ -23,9 +23,10 @@ export default {
|
||||
'policyManage.confirmDeleteBatch': 'Are you sure you want to delete the selected policies?',
|
||||
'policyManage.confirmPublish': 'Are you sure you want to publish this policy?',
|
||||
'policyManage.confirmUnpublish': 'Are you sure you want to unpublish this policy?',
|
||||
'policyManage.batchDelete': 'Batch Delete',
|
||||
'policyManage.deleteSuccess': 'Delete successful',
|
||||
'policyManage.deleteFailed': 'Delete failed',
|
||||
'policyManage.batchDeleteSuccess': 'Delete successful',
|
||||
'policyManage.batchDeleteSuccess': 'Batch delete successful',
|
||||
'policyManage.batchDeletePartialFailed': 'Some deletions failed, please refresh and try again',
|
||||
'policyManage.batchDeleteFailed': 'Batch delete failed',
|
||||
'policyManage.publishSuccess': 'Publish successful',
|
||||
|
@ -62,7 +62,7 @@ export default {
|
||||
'readQuestion.search': 'Search',
|
||||
'readQuestion.reset': 'Reset',
|
||||
'readQuestion.confirmDelete': 'Are you sure you want to delete this question?',
|
||||
'readQuestion.batchDelete': 'Delete Selected',
|
||||
'readQuestion.batchDelete': 'Batch Delete',
|
||||
'readQuestion.viewDetails': 'View Question Details',
|
||||
'readQuestion.questionDetails': 'Question Details',
|
||||
'readQuestion.answerDetails': 'Reply Details',
|
||||
@ -103,7 +103,7 @@ export default {
|
||||
'unreadQuestion.search': 'Search',
|
||||
'unreadQuestion.reset': 'Reset',
|
||||
'unreadQuestion.confirmDelete': 'Are you sure you want to delete this question?',
|
||||
'unreadQuestion.batchDelete': 'Delete Selected',
|
||||
'unreadQuestion.batchDelete': 'Batch Delete',
|
||||
'unreadQuestion.replyModal': 'Reply to Question',
|
||||
'unreadQuestion.questionContent': 'Question Content',
|
||||
'unreadQuestion.answerContent': 'Reply Content',
|
||||
|
@ -31,4 +31,13 @@ export default {
|
||||
// 按钮
|
||||
"common.confirm": "确定",
|
||||
"common.cancel": "取消",
|
||||
|
||||
// FileUpload组件
|
||||
'component.fileUpload.buttonText': '上传文件',
|
||||
'component.fileUpload.dragText': '点击或拖拽文件到此区域上传',
|
||||
'component.fileUpload.fileTypeTip': '支持的文件类型:{types}',
|
||||
'component.fileUpload.fileSizeTip': '文件大小不超过{size}MB',
|
||||
'component.fileUpload.uploadFailed': '上传失败',
|
||||
'component.fileUpload.parseError': '解析响应失败',
|
||||
'component.fileUpload.networkError': '网络错误',
|
||||
};
|
||||
|
@ -51,6 +51,7 @@ export default {
|
||||
'friendLink.enable.confirm.content': '确定要启用该友情链接吗?',
|
||||
'friendLink.disable.confirm.title': '禁用确认',
|
||||
'friendLink.disable.confirm.content': '确定要禁用该友情链接吗?',
|
||||
'friendLink.detail.failed': '获取友情链接详情失败',
|
||||
|
||||
// 友情链接分类管理
|
||||
'friendLink.category.title': '友情链接分类管理',
|
||||
|
@ -1,12 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useIntl } from 'umi';
|
||||
import { Table, Button, Modal, Form, Input, Space, message, Upload, Tag, TreeSelect } from 'antd';
|
||||
import {
|
||||
PlusOutlined,
|
||||
DeleteOutlined,
|
||||
ExclamationCircleOutlined,
|
||||
UploadOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Table, Button, Modal, Form, Input, Space, message, Tag, TreeSelect } from 'antd';
|
||||
import { PlusOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
import type { UploadFile } from 'antd/es/upload/interface';
|
||||
import {
|
||||
getLinkList,
|
||||
@ -16,8 +11,10 @@ import {
|
||||
enableLink,
|
||||
disableLink,
|
||||
getAllCategories,
|
||||
getLinkDetail,
|
||||
} from '@/servers/api/friendLink';
|
||||
import { useFriendLinkDict } from '@/dicts/friendLinkDict';
|
||||
import { LinkStatusMap } from '@/dicts/friendLinkDict';
|
||||
import FileUpload from '@/components/FileUpload';
|
||||
import './friendLinkManage.less';
|
||||
|
||||
const FriendLinkManage: React.FC = () => {
|
||||
@ -35,7 +32,6 @@ const FriendLinkManage: React.FC = () => {
|
||||
total: 0,
|
||||
});
|
||||
const [form] = Form.useForm();
|
||||
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
||||
const [categoryMap, setCategoryMap] = useState<Record<string, string>>({});
|
||||
|
||||
// 获取友情链接列表
|
||||
@ -50,12 +46,7 @@ const FriendLinkManage: React.FC = () => {
|
||||
});
|
||||
|
||||
if (res.data && res.success) {
|
||||
// 处理分类名称
|
||||
const links = res.data.records.map((item: API.LinkItem) => ({
|
||||
...item,
|
||||
categoryName: categoryMap[item.classificationId] || '',
|
||||
}));
|
||||
setLinkData(links);
|
||||
setLinkData(res.data.records);
|
||||
setPagination({
|
||||
current: res.data.current,
|
||||
pageSize: res.data.size,
|
||||
@ -74,28 +65,7 @@ const FriendLinkManage: React.FC = () => {
|
||||
try {
|
||||
const res = await getAllCategories();
|
||||
if (res.data && res.success) {
|
||||
const flattenCategories = (
|
||||
categories: API.CategoryType[],
|
||||
result: API.CategoryType[] = [],
|
||||
): API.CategoryType[] => {
|
||||
categories.forEach((category) => {
|
||||
result.push(category);
|
||||
if (category.children && category.children.length > 0) {
|
||||
flattenCategories(category.children, result);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const flatCategories = flattenCategories(res.data);
|
||||
setCategoryData(res.data);
|
||||
|
||||
// 创建分类ID到名称的映射
|
||||
const categoryNameMap: Record<string, string> = {};
|
||||
flatCategories.forEach((category) => {
|
||||
categoryNameMap[category.id] = category.name;
|
||||
});
|
||||
setCategoryMap(categoryNameMap);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch category list', error);
|
||||
@ -119,7 +89,6 @@ const FriendLinkManage: React.FC = () => {
|
||||
setIsEdit(false);
|
||||
setCurrentId('');
|
||||
form.resetFields();
|
||||
setFileList([]);
|
||||
form.setFieldsValue({
|
||||
orderBy: 1,
|
||||
});
|
||||
@ -132,30 +101,34 @@ const FriendLinkManage: React.FC = () => {
|
||||
setCurrentId(record.id);
|
||||
setModalVisible(true);
|
||||
|
||||
// 设置表单初始值
|
||||
form.setFieldsValue({
|
||||
name: record.name,
|
||||
nameEn: record.nameEn,
|
||||
url: record.url,
|
||||
orderBy: parseInt(record.orderBy),
|
||||
classificationId: record.classificationId,
|
||||
});
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
|
||||
// 设置上传文件列表
|
||||
if (record.thumbnail) {
|
||||
setFileList([
|
||||
{
|
||||
uid: '-1',
|
||||
name: 'thumbnail.png',
|
||||
status: 'done',
|
||||
url: record.thumbnail,
|
||||
type: 'image/png',
|
||||
size: 0,
|
||||
} as UploadFile,
|
||||
]);
|
||||
} else {
|
||||
setFileList([]);
|
||||
}
|
||||
// 调用详情接口获取完整数据
|
||||
getLinkDetail(record.id)
|
||||
.then((res: API.Response<API.LinkType>) => {
|
||||
if (res.success && res.data) {
|
||||
const detail = res.data;
|
||||
console.log('Detail data:', detail);
|
||||
|
||||
// 设置表单初始值,包括缩略图URL
|
||||
form.setFieldsValue({
|
||||
name: detail.name,
|
||||
nameEn: detail.nameEn,
|
||||
url: detail.url,
|
||||
orderBy: parseInt(detail.orderBy),
|
||||
classificationId: detail.classificationId,
|
||||
// 设置为URL字符串,组件会自动处理
|
||||
thumbnail: detail.thumbnail,
|
||||
});
|
||||
} else {
|
||||
message.error(intl.formatMessage({ id: 'friendLink.detail.failed' }));
|
||||
}
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.error('Failed to get link detail', error);
|
||||
message.error(intl.formatMessage({ id: 'friendLink.detail.failed' }));
|
||||
});
|
||||
};
|
||||
|
||||
// 处理删除
|
||||
@ -220,22 +193,24 @@ const FriendLinkManage: React.FC = () => {
|
||||
// 添加确认对话框
|
||||
Modal.confirm({
|
||||
title: intl.formatMessage({
|
||||
id: record.status === '1'
|
||||
? 'friendLink.disable.confirm.title'
|
||||
: 'friendLink.enable.confirm.title'
|
||||
id:
|
||||
record.status === LinkStatusMap.ENABLED
|
||||
? 'friendLink.disable.confirm.title'
|
||||
: 'friendLink.enable.confirm.title',
|
||||
}),
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
content: intl.formatMessage({
|
||||
id: record.status === '1'
|
||||
? 'friendLink.disable.confirm.content'
|
||||
: 'friendLink.enable.confirm.content'
|
||||
id:
|
||||
record.status === LinkStatusMap.ENABLED
|
||||
? 'friendLink.disable.confirm.content'
|
||||
: 'friendLink.enable.confirm.content',
|
||||
}),
|
||||
okText: intl.formatMessage({ id: 'common.confirm' }),
|
||||
cancelText: intl.formatMessage({ id: 'common.cancel' }),
|
||||
onOk: async () => {
|
||||
try {
|
||||
let res;
|
||||
if (record.status === '1') {
|
||||
if (record.status === LinkStatusMap.ENABLED) {
|
||||
// 当前启用,需要禁用
|
||||
res = await disableLink(record.id);
|
||||
} else {
|
||||
@ -245,7 +220,7 @@ const FriendLinkManage: React.FC = () => {
|
||||
|
||||
if (res.success) {
|
||||
message.success(
|
||||
record.status === '1'
|
||||
record.status === LinkStatusMap.ENABLED
|
||||
? intl.formatMessage({ id: 'friendLink.disable.success' })
|
||||
: intl.formatMessage({ id: 'friendLink.enable.success' }),
|
||||
);
|
||||
@ -261,19 +236,15 @@ const FriendLinkManage: React.FC = () => {
|
||||
// 处理表单提交
|
||||
const handleModalSubmit = () => {
|
||||
form.validateFields().then(async (values) => {
|
||||
console.log('Form values:', values);
|
||||
try {
|
||||
// 确保thumbnail有值
|
||||
if (fileList.length === 0) {
|
||||
message.error(intl.formatMessage({ id: 'friendLink.form.thumbnail.required' }));
|
||||
return;
|
||||
}
|
||||
|
||||
// 准备提交数据
|
||||
// 现在thumbnail字段已经直接是URL字符串,不需要额外处理
|
||||
const formData = {
|
||||
...values,
|
||||
thumbnail: fileList[0].url || fileList[0].thumbUrl || '',
|
||||
};
|
||||
|
||||
console.log('Submitting form data:', formData);
|
||||
|
||||
let res;
|
||||
if (isEdit) {
|
||||
// 编辑模式
|
||||
@ -301,11 +272,6 @@ const FriendLinkManage: React.FC = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 处理文件上传变化
|
||||
const handleFileChange = (info: { fileList: UploadFile[] }) => {
|
||||
setFileList(info.fileList);
|
||||
};
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
@ -345,7 +311,7 @@ const FriendLinkManage: React.FC = () => {
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (text: string) =>
|
||||
text === '1' ? (
|
||||
text === LinkStatusMap.ENABLED ? (
|
||||
<Tag color="green">{intl.formatMessage({ id: 'friendLink.enabled' })}</Tag>
|
||||
) : (
|
||||
<Tag color="red">{intl.formatMessage({ id: 'friendLink.disabled' })}</Tag>
|
||||
@ -361,7 +327,7 @@ const FriendLinkManage: React.FC = () => {
|
||||
{intl.formatMessage({ id: 'friendLink.edit' })}
|
||||
</Button>
|
||||
<Button type="link" onClick={() => handleToggleStatus(record)}>
|
||||
{record.status === '1'
|
||||
{record.status === LinkStatusMap.ENABLED
|
||||
? intl.formatMessage({ id: 'friendLink.disable' })
|
||||
: intl.formatMessage({ id: 'friendLink.enable' })}
|
||||
</Button>
|
||||
@ -381,26 +347,28 @@ const FriendLinkManage: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div className="friend-link-manage-container common-container">
|
||||
<div className="action-bar">
|
||||
<div className="filter-action-row">
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||
{intl.formatMessage({ id: 'friendLink.add' })}
|
||||
</Button>
|
||||
<Button
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={handleBatchDelete}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
>
|
||||
{intl.formatMessage({ id: 'friendLink.batchDelete' })}
|
||||
</Button>
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<span className="selected-count">
|
||||
{intl.formatMessage(
|
||||
{ id: 'friendLink.selectedCount' },
|
||||
{ count: selectedRowKeys.length },
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
<div className="right-buttons">
|
||||
<Button
|
||||
danger
|
||||
icon={<DeleteOutlined />}
|
||||
onClick={handleBatchDelete}
|
||||
disabled={selectedRowKeys.length === 0}
|
||||
>
|
||||
{intl.formatMessage({ id: 'friendLink.batchDelete' })}
|
||||
</Button>
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<span className="selected-count">
|
||||
{intl.formatMessage(
|
||||
{ id: 'friendLink.selectedCount' },
|
||||
{ count: selectedRowKeys.length },
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="content-area">
|
||||
@ -496,18 +464,30 @@ const FriendLinkManage: React.FC = () => {
|
||||
<Input placeholder={intl.formatMessage({ id: 'friendLink.form.url.placeholder' })} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item name="thumbnail" label={intl.formatMessage({ id: 'friendLink.thumbnail' })}>
|
||||
<Upload
|
||||
listType="picture"
|
||||
<Form.Item
|
||||
name="thumbnail"
|
||||
label={intl.formatMessage({ id: 'friendLink.thumbnail' })}
|
||||
getValueFromEvent={(e) => {
|
||||
return e[0].url;
|
||||
}}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: intl.formatMessage({ id: 'friendLink.form.thumbnail.required' }),
|
||||
},
|
||||
]}
|
||||
>
|
||||
<FileUpload
|
||||
maxCount={1}
|
||||
fileList={fileList}
|
||||
onChange={handleFileChange}
|
||||
beforeUpload={() => false}
|
||||
>
|
||||
<Button icon={<UploadOutlined />}>
|
||||
{intl.formatMessage({ id: 'friendLink.form.thumbnail.upload' })}
|
||||
</Button>
|
||||
</Upload>
|
||||
maxSize={2}
|
||||
allowedTypes={['jpg', 'png']}
|
||||
listType="picture"
|
||||
tip={intl.formatMessage(
|
||||
{ id: 'component.fileUpload.fileTypeTip' },
|
||||
{ types: 'JPG, PNG' },
|
||||
)}
|
||||
buttonText={intl.formatMessage({ id: 'friendLink.form.thumbnail.upload' })}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
|
@ -96,3 +96,10 @@ export async function disableLink(id: string) {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取友情链接详情
|
||||
export async function getLinkDetail(id: string) {
|
||||
return request(`/portals/links/${id}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
12
src/servers/api/typings.d.ts
vendored
12
src/servers/api/typings.d.ts
vendored
@ -439,6 +439,18 @@ declare namespace API {
|
||||
createTime?: string;
|
||||
updateTime?: string;
|
||||
categoryName?: string; // 用于显示
|
||||
// 以下是详情接口返回的额外字段
|
||||
createBy?: string;
|
||||
createDate?: string | null;
|
||||
updateBy?: string | null;
|
||||
updateDate?: string | null;
|
||||
tenantId?: string | null;
|
||||
tenantName?: string | null;
|
||||
deleteFlag?: string | null;
|
||||
lastUpdateTime?: string | null;
|
||||
delFlag?: string;
|
||||
remark?: string | null;
|
||||
basePageRequest?: null;
|
||||
}
|
||||
// 友情链接分类请求参数
|
||||
export interface CategoryRequest {
|
||||
|
23
src/typings.d.ts
vendored
23
src/typings.d.ts
vendored
@ -40,25 +40,6 @@ declare interface Window {
|
||||
declare let ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: 'site' | undefined;
|
||||
|
||||
declare const REACT_APP_ENV: 'test' | 'dev' | 'pre' | false;
|
||||
/**ENV-商城2.0跳转地址 */
|
||||
declare const REACT_APP_MALL_V2_URL: string
|
||||
/**ENV-系统跳转参数KEY */
|
||||
declare const REACT_APP_CLIENT_KEY: string
|
||||
/**ENV-系统跳转参数SECRET */
|
||||
// declare const REACT_APP_CLIENT_SECRET: string
|
||||
/**ENV-密码加密参数CIPHERMODE */
|
||||
declare const REACT_APP_PASSWORD_CIPHERMODE: string
|
||||
/**ENV-密码加密参数PUBLICKEY */
|
||||
declare const REACT_APP_PASSWORD_PUBLICKEY: string
|
||||
/**ENV-环境参数 */
|
||||
declare const START_ENV: string
|
||||
/**ENV-询价查看报价跳转地址 */
|
||||
// declare const REACT_APP_XUNJIA_REDIRECT: string
|
||||
/**ENV-询价查看报价跳转地址 */
|
||||
declare const REACT_APP_XUNJIA_UID: string
|
||||
//智慧客服
|
||||
declare const REACT_APP_CUSTOMERSERVICE_USERCENTER: string
|
||||
declare const REACT_APP_CUSTOMERSERVICE_CLIENT_ID: string
|
||||
declare const REACT_APP_CUSTOMERSERVICE_REDIRECT: string
|
||||
|
||||
|
||||
declare const REQUEST_BASE: string;
|
||||
declare const UPLOAD_URL: string;
|
||||
|
@ -52,7 +52,7 @@ const codeMessage = {
|
||||
* 配置request请求时的默认参数
|
||||
*/
|
||||
const request = extend({
|
||||
prefix: '/api',
|
||||
prefix: REQUEST_BASE,
|
||||
// errorHandler, // 默认错误处理
|
||||
credentials: 'include' // 默认请求是否带上cookie
|
||||
});
|
||||
|
@ -19,7 +19,6 @@ const FileTypeMap = {
|
||||
|
||||
}
|
||||
export const validateFileSize = (file: File, maxSize: number,type: string[]) => {
|
||||
console.log(file)
|
||||
const { LIST_IGNORE } = Upload;
|
||||
const isLtMaxSize = file.size / 1024 / 1024 < maxSize;
|
||||
if (!isLtMaxSize) {
|
||||
|
Reference in New Issue
Block a user