Commit bb5f817d authored by 张烨's avatar 张烨

feat: 图片上传功能和代理配置

parent 6f787970
# PUBLIC_PATH = reactOMS, 默认转发 /cityinterface # PUBLIC_PATH = reactOMS, 默认转发 /cityinterface
PROXY = http://localhost:8005/ PROXY=/Cityinterface:http://192.168.10.151:8055;/Publish:http://192.168.10.151:8055;/Web4:http://192.168.10.151:8055;/CityTemp:http://192.168.10.151:8055
# 可设置第二个代理,test为转发前缀,后面为代理转发的地址 # 可设置第二个代理,test为转发前缀,后面为代理转发的地址
# PROXY2 = test : http://localhost:8006/ # PROXY2 = test : http://localhost:8006/
......
...@@ -14,6 +14,116 @@ function createWebpackMiddleware(compiler, publicPath) { ...@@ -14,6 +14,116 @@ function createWebpackMiddleware(compiler, publicPath) {
}); });
} }
const setupProxyFeature = (app, webpackConfig) => {
console.log(webpackConfig);
if (!Array.isArray(webpackConfig.proxy)) {
if (Object.prototype.hasOwnProperty.call(webpackConfig.proxy, 'target')) {
webpackConfig.proxy = [webpackConfig.proxy];
} else {
webpackConfig.proxy = Object.keys(webpackConfig.proxy).map(context => {
let proxyOptions;
// For backwards compatibility reasons.
const correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
if (typeof webpackConfig.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: webpackConfig.proxy[context],
};
} else {
proxyOptions = Object.assign({}, webpackConfig.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions;
});
}
}
// eslint-disable-next-line consistent-return
const getProxyMiddleware = proxyConfig => {
const context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return createProxyMiddleware(context, proxyConfig);
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
webpackConfig.proxy.forEach(proxyConfigOrCallback => {
let proxyMiddleware;
let proxyConfig =
typeof proxyConfigOrCallback === 'function'
? proxyConfigOrCallback()
: proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
if (proxyConfig.ws) {
this.websocketProxies.push(proxyMiddleware);
}
// eslint-disable-next-line consistent-return
const handle = (req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
const isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
const bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
};
app.use(handle);
// Also forward error requests to the proxy so it can handle them.
app.use((error, req, res, next) => handle(req, res, next));
});
};
module.exports = function addDevMiddlewares(app, webpackConfig) { module.exports = function addDevMiddlewares(app, webpackConfig) {
const compiler = webpack(webpackConfig); const compiler = webpack(webpackConfig);
const middleware = createWebpackMiddleware( const middleware = createWebpackMiddleware(
...@@ -27,65 +137,19 @@ module.exports = function addDevMiddlewares(app, webpackConfig) { ...@@ -27,65 +137,19 @@ module.exports = function addDevMiddlewares(app, webpackConfig) {
// Since webpackDevMiddleware uses memory-fs internally to store build // Since webpackDevMiddleware uses memory-fs internally to store build
// artifacts, we use it instead // artifacts, we use it instead
const fs = middleware.fileSystem; const fs = middleware.fileSystem;
let proxyHost = process.env.PROXY; if (process.env.PROXY) {
const proxyPrefix = process.env.PROXY_PREFIX || '/Cityinterface'; const proxies = process.env.PROXY.split(';');
app.get('/setproxy', (req, res) => { // 设置代理
if (req.query && req.query.host) { setupProxyFeature(app, {
proxyHost = req.query.host; proxy: proxies.map(proxyStr => {
res.send(200); const mathes = proxyStr.match(/^\s*([/\w]+)\s*:\s*(.+)\s*$/);
} else { return {
res.send(400); path: mathes[1],
} target: mathes[2],
});
if (
proxyHost &&
(proxyHost.toLowerCase() !== 'origin' ||
proxyHost.toLowerCase() !== 'off' ||
proxyHost !== '0')
) {
logger.info(`using proxy at: ${proxyHost}`);
logger.info(`proxy prefix: ${proxyPrefix}`);
app.use(
proxyPrefix,
createProxyMiddleware({
target: proxyHost,
changeOrigin: true,
// eslint-disable-next-line no-unused-vars
onProxyReq: (_prexyReq, _req, _res) => {
logger.info('onProxyReq');
},
// eslint-disable-next-line no-unused-vars
onProxyRes(_proxyRes, _req, _res) {
logger.info('onProxyRes');
},
}),
);
const proxy2 = process.env.PROXY2;
if (proxy2) {
const reg = /([/\w]+)\s*:\s*([\w:./]*)/;
const match = proxy2.match(reg);
const [, pre, host] = match;
logger.info(`using proxy2 at: ${host}`);
const prefix = `${pre[0] === '/' ? pre : `/${pre}`}`;
logger.info(`proxy2 prefix: ${prefix}`);
app.use(
prefix,
createProxyMiddleware({
target: host,
changeOrigin: true, changeOrigin: true,
// eslint-disable-next-line no-unused-vars };
onProxyReq: (_prexyReq, _req, _res) => { }),
logger.info('onProxyReq2'); });
},
// eslint-disable-next-line no-unused-vars
onProxyRes(_proxyRes, _req, _res) {
logger.info('onProxyRes2');
},
}),
);
}
} }
app.get('*', (_req, res) => { app.get('*', (_req, res) => {
......
...@@ -70,6 +70,7 @@ const BaseForm = props => { ...@@ -70,6 +70,7 @@ const BaseForm = props => {
getForm, // 用来获取表单实例 getForm, // 用来获取表单实例
formProps, formProps,
children, children,
...restProps
} = props; } = props;
const [form] = useForm(); const [form] = useForm();
...@@ -81,7 +82,7 @@ const BaseForm = props => { ...@@ -81,7 +82,7 @@ const BaseForm = props => {
}, []); }, []);
return ( return (
<Form size="small" form={form} {...formProps}> <Form size="small" form={form} {...formProps} {...restProps}>
{items && {items &&
items.map(item => { items.map(item => {
const { const {
......
...@@ -4,9 +4,10 @@ import { PlusOutlined, CheckCircleFilled } from '@ant-design/icons'; ...@@ -4,9 +4,10 @@ import { PlusOutlined, CheckCircleFilled } from '@ant-design/icons';
import ImgCrop from 'antd-img-crop'; import ImgCrop from 'antd-img-crop';
import classnames from 'classnames'; import classnames from 'classnames';
import { UploadFile, UploadChangeParam, RcFile } from 'antd/lib/upload/interface'; import { UploadFile, UploadChangeParam, RcFile } from 'antd/lib/upload/interface';
import { isDev, unParams, uuid } from '@/utils/tools'; import { uuid } from '@/utils/tools';
import { get } from '@/services'; import { get, PUBLISH_SERVICE } from '@/services';
import styles from './index.less'; import styles from './index.less';
import { getImageBases } from '@/services/common/api';
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -35,6 +36,7 @@ interface PicturesWallType { ...@@ -35,6 +36,7 @@ interface PicturesWallType {
onChange?: (v: any) => void; onChange?: (v: any) => void;
cropRate?: number | boolean; cropRate?: number | boolean;
isCrop?: boolean; isCrop?: boolean;
type?: 'CityTemp'|'icon'|'androidMenu'|'menuNew'
} }
class PicturesWall extends React.Component<PicturesWallType> { class PicturesWall extends React.Component<PicturesWallType> {
...@@ -43,11 +45,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -43,11 +45,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
previewImage: '', previewImage: '',
wallModalVisible: false, wallModalVisible: false,
previewTitle: '', previewTitle: '',
imgBed: { imgBed: [],
icon: [],
bg: [],
uploaded: [],
},
curSelectedImg: '', curSelectedImg: '',
fileList: this.props.fileList || [], fileList: this.props.fileList || [],
}; };
...@@ -90,9 +88,9 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -90,9 +88,9 @@ class PicturesWall extends React.Component<PicturesWallType> {
const fileList = [ const fileList = [
{ {
uid: uuid(8, 16), uid: uuid(8, 16),
name: 'h5-dooring图片库', name: '熊猫运维中台系统',
status: 'done', status: 'done',
url: this.state.curSelectedImg, url: this.getImageUrl(this.state.curSelectedImg),
}, },
]; ];
this.props.onChange && this.props.onChange(fileList); this.props.onChange && this.props.onChange(fileList);
...@@ -103,11 +101,11 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -103,11 +101,11 @@ class PicturesWall extends React.Component<PicturesWallType> {
this.setState({ fileList }); this.setState({ fileList });
if (file.status === 'done') { if (file.status === 'done') {
const files = fileList.map(item => { const files = fileList.map(item => {
const { uid, name, status } = item; const { status, data, name, thumbUrl } = item;
const url = item.url || item.response.result.url; const url = thumbUrl || this.getImageUrl(data);
return { uid, name, status, url }; return { uid: uuid(8, 16), name, status, url };
}); });
this.props.onChange && this.props.onChange(files); this.props.onChange && this.props.onChange( this.props.maxLen === 1 ? files[0].url : files.map(f => f.url));
} }
}; };
...@@ -128,12 +126,19 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -128,12 +126,19 @@ class PicturesWall extends React.Component<PicturesWallType> {
}; };
componentDidMount() { componentDidMount() {
get(`/visible/bed/get?tid=${unParams(location.search)!.tid}`).then(res => { const { type = ''} = this.props;
// res && getImageBases(type).then(res => {
// this.setState({ if(res.code === 0){
// imgBed: res, this.setState({imgBed: res.data})
// }); }
}); })
}
getImageUrl(path){
if(path.indexOf('http') === 0){
return path
}
return `${window.location.origin}/${path}`.replace(/\\/g, '/')
} }
render() { render() {
...@@ -147,7 +152,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -147,7 +152,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
curSelectedImg, curSelectedImg,
} = this.state; } = this.state;
const { const {
action = isDev ? 'http://192.168.1.8:3000/api/v0/files/upload/free' : '你的服务器地址', action = `${window.location.origin}${PUBLISH_SERVICE}/FileCenter/UploadSingleFile` ,
headers, headers,
withCredentials = true, withCredentials = true,
maxLen = 1, maxLen = 1,
...@@ -162,8 +167,6 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -162,8 +167,6 @@ class PicturesWall extends React.Component<PicturesWallType> {
</div> </div>
); );
const cates = Object.keys(imgBed);
return ( return (
<> <>
{isCrop ? ( {isCrop ? (
...@@ -178,14 +181,14 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -178,14 +181,14 @@ class PicturesWall extends React.Component<PicturesWallType> {
fileList={fileList} fileList={fileList}
onPreview={this.handlePreview} onPreview={this.handlePreview}
onChange={this.handleChange} onChange={this.handleChange}
name="file" name="singleFile"
listType="picture-card" listType="picture-card"
className={styles.avatarUploader} className={styles.avatarUploader}
action={action} action={action}
withCredentials={withCredentials} withCredentials={withCredentials}
headers={{ headers={{
'x-requested-with': localStorage.getItem('user') || '', 'x-requested-with': localStorage.getItem('user') || '',
authorization: localStorage.getItem('token') || '', token: localStorage.getItem('token') || '',
...headers, ...headers,
}} }}
beforeUpload={this.handleBeforeUpload} beforeUpload={this.handleBeforeUpload}
...@@ -198,14 +201,14 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -198,14 +201,14 @@ class PicturesWall extends React.Component<PicturesWallType> {
fileList={fileList} fileList={fileList}
onPreview={this.handlePreview} onPreview={this.handlePreview}
onChange={this.handleChange} onChange={this.handleChange}
name="file" name="singleFile"
listType="picture-card" listType="picture-card"
className={styles.avatarUploader} className={styles.avatarUploader}
action={action} action={action}
withCredentials={withCredentials} withCredentials={withCredentials}
headers={{ headers={{
'x-requested-with': localStorage.getItem('user') || '', 'x-requested-with': localStorage.getItem('user') || '',
authorization: localStorage.getItem('token') || '', token: localStorage.getItem('token') || '',
...headers, ...headers,
}} }}
beforeUpload={this.handleBeforeUpload} beforeUpload={this.handleBeforeUpload}
...@@ -214,7 +217,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -214,7 +217,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
</Upload> </Upload>
)} )}
<div className={styles.wallBtn} onClick={this.handleWallShow}> <div className={styles.wallBtn} onClick={this.handleWallShow}>
图片库 从图片库选择
</div> </div>
<Modal <Modal
visible={previewVisible} visible={previewVisible}
...@@ -222,7 +225,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -222,7 +225,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
footer={null} footer={null}
onCancel={this.handleCancel} onCancel={this.handleCancel}
> >
<img alt="预览图片" style={{ width: '100%' }} src={previewImage} /> <img alt="预览图片" style={{ width: '100%' }} src={this.getImageUrl(previewImage)} />
</Modal> </Modal>
<Modal <Modal
visible={wallModalVisible} visible={wallModalVisible}
...@@ -233,13 +236,12 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -233,13 +236,12 @@ class PicturesWall extends React.Component<PicturesWallType> {
onCancel={this.handleModalCancel} onCancel={this.handleModalCancel}
onOk={this.handleModalOk} onOk={this.handleModalOk}
> >
<Tabs defaultActiveKey={cates[0]} tabPosition="left" style={{ height: 520 }}> <Tabs defaultActiveKey={imgBed[0]?.moduleName} tabPosition="left" style={{ height: 520 }}>
{cates.map((item, i) => { {imgBed.map((item, i) => {
return ( return (
<TabPane tab={wallCateName[item]} key={item}> <TabPane tab={item.moduleName} key={item.moduleName}>
<div className={styles.imgBox}> <div className={styles.imgBox}>
{(imgBed as any)[item] && {item.child?.map(m => m.fileUrls).flat(Infinity).map((item: string, i: number) => {
(imgBed as any)[item].map((item: string, i: number) => {
return ( return (
<div <div
className={classnames( className={classnames(
...@@ -249,7 +251,7 @@ class PicturesWall extends React.Component<PicturesWallType> { ...@@ -249,7 +251,7 @@ class PicturesWall extends React.Component<PicturesWallType> {
key={i} key={i}
onClick={() => this.handleImgSelected(item)} onClick={() => this.handleImgSelected(item)}
> >
<img src={item} alt="熊猫运维中台系统" /> <img src={this.getImageUrl(item)} alt="熊猫运维中台系统" />
<span className={styles.iconBtn}> <span className={styles.iconBtn}>
<CheckCircleFilled /> <CheckCircleFilled />
</span> </span>
......
...@@ -193,7 +193,12 @@ export default props => { ...@@ -193,7 +193,12 @@ export default props => {
visible={visible} visible={visible}
maskClosable={false} maskClosable={false}
> >
<BaseForm {...formConfig} /> <BaseForm
{...formConfig}
onFinish={values => {
console.log(values);
}}
/>
</Drawer> </Drawer>
</div> </div>
); );
......
import { post, postForm, get, PUBLISH_SERVICE } from '../index';
export const getImageBases = moduleName =>
get(`${PUBLISH_SERVICE}/FileCenter/GetFileUrls`, { moduleName });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment