Commit 9262a8d9 authored by Bill's avatar Bill

Merge branch 'fix418' into 'v2-220418'

商品导入excel数据 See merge request linkseeks-design/pro-platform!99
parents 8bd9c80b 5fbb4352
......@@ -141,11 +141,11 @@ export default {
'commodity.products.step0Description.text.2' : '按照模板整理货品资料',
'commodity.products.step0Description.text.3' : '点击导入按钮,导入整理好的货品资料',
'commodity.products.step0Description.download' : '下载',
'commodity.products.step1Description.text.1' : '正在进行数据导入检查',
'commodity.products.step1Description.text.1' : '正在进行数据导入',
'commodity.products.step1Description.text.2' : '请稍后…',
'commodity.products.step1DescripSuccess.text.1' : '无错误格式数据',
'commodity.products.step1DescripSuccess.text.2' : '继续导入请按下一步',
'commodity.products.step1DescripSuccess.button' : '下一步',
'commodity.products.step1DescripSuccess.text.2' : '导入成功',
'commodity.products.step1DescripSuccess.button' : '完成',
'commodity.products.step1Exception.text.1' : '存在错误格式数据,已生成错误日志',
'commodity.products.step1Exception.text.2' : '请导出错误日志修正数据后再次导入',
'commodity.products.step2Description.text.1' : '正在进行数据导入',
......
......@@ -48,9 +48,9 @@ const ProductDescFormYang: React.FC<{}> = () => {
setFileImageList(() => {
const images = productInfoByEdit.commodityRemark?.imageList
return {
descriptionImages: images.filter(item => item.imageType === CommodityImagesType.DESCRIPTION_IMAGES),
certificationImages: images.filter(item => item.imageType === CommodityImagesType.CERTIFICATION_IMAGES),
reportImages: images.filter(item => item.imageType === CommodityImagesType.REPORT_IMAGES)
descriptionImages: images ? images.filter(item => item.imageType === CommodityImagesType.DESCRIPTION_IMAGES) : [],
certificationImages: images ? images.filter(item => item.imageType === CommodityImagesType.CERTIFICATION_IMAGES) : [],
reportImages: images ? images.filter(item => item.imageType === CommodityImagesType.REPORT_IMAGES) : [],
}
})
setVideoList(productInfoByEdit.commodityRemark?.video)
......
......@@ -42,7 +42,7 @@ const SelectGoodsForm: React.FC<{}> = (props) => {
item[next.id] = next;
return item
}, {}))
const filterGoods = goodsArr.filter(item => item['id'] !== 0)
const filterGoods = goodsArr ? goodsArr.filter(item => item['id'] !== 0) : []
if (filterGoods?.length > 0) {
setIsChecked(true)
setIsSelectGoods(true)
......
......@@ -269,3 +269,13 @@
white-space: nowrap;
text-overflow: ellipsis;
}
.importBtn {
:global {
.ant-upload.ant-upload-select.ant-upload-select-text {
display: block;
width: 100%;
}
}
}
import React, { useState, useEffect, useRef, useMemo } from 'react'
import { history, useIntl } from 'umi'
import { Button, Form, Card, Modal, Result, Progress, Select, Tooltip, Checkbox, Row, Col, Dropdown, Menu, Space, message, Badge, Tabs, Tag, Radio } from 'antd'
import { Button, Form, Card, Modal, Result, Progress, Select, Row, Col, Dropdown, Menu, Space, message, Badge, Tabs, Tag, Radio, Upload } from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import {
PlusOutlined,
......@@ -35,22 +35,18 @@ import PutawayGuide, { GuideMenu } from './components/putawayGuide'
import { useRowSelectionTable, useRowSelectionTableCtl } from '@/hooks/useRowSelectionTable'
import AuthButton from '@/components/AuthButton'
import { AuthUrl } from '@/components/AuthButton/AuthUrl'
import allRouters from '../../../../config/router.config.json'
import { postOrderCommonProductProcessFind } from '@/services/OrderNewV2Api'
import { ProductView, ProductSel } from './productModal'
import { getProductCommodityGetCommodityDraftList, postProductCommodityDeleteCommodityDraftBatch } from '@/services/ProductV2Api'
const { confirm } = Modal;
let timeChange: any;
const formActions = createFormActions();
const Products: React.FC<{}> = () => {
const intl = useIntl();
const ref = useRef<any>({})
const refDraft = useRef<any>({})
const judgeShopRef = useRef<boolean>(true)
const [upForm] = Form.useForm()
const [importModal, setImportModal] = useState(false)
const [deleteBatchModal, setDeleteBatchModal] = useState(false)
......@@ -72,6 +68,7 @@ const Products: React.FC<{}> = () => {
const [giudeVisible, setGiudeVisible] = useState<boolean>(false)
const [giudeStep, setGiudeStep] = useState<number>()
const [inconformityProductIds, setInconformityProductIds] = useState<number[]>([])
const { token } = getAuth() || {}
// 上游弹窗
const [upModal, setUpModal] = useState(false)
......@@ -216,7 +213,7 @@ const Products: React.FC<{}> = () => {
title: intl.formatMessage({ id: 'commodity.products.columns.name' }),
dataIndex: ['draft', 'name'],
key: 'name',
className: 'commonPickColor',
// className: 'commonPickColor',
width: 240,
ellipsis: true,
// render: (text: any, record: any) => <EyePreview url={`/memberCenter/commodityAbility/commodity/products/detail?id=${record.id}`}>
......@@ -413,6 +410,9 @@ const Products: React.FC<{}> = () => {
const handleCancel = () => {
setImportModal(false)
setModalStep(0)
setExceptionCheck(false)
setExceptionContent('')
}
const modalLoadTemplate = () => {
......@@ -431,20 +431,25 @@ const Products: React.FC<{}> = () => {
})
}
const modalUpload = () => {
console.log('上传')
setModalStep(1)
setModalTitle(intl.formatMessage({ id: 'commodity.products.modalTitle.2' }))
const exportErrorLog = () => {
download_txt('log.txt', exceptionContent)
setModalStep(0)
setImportModal(false)
}
const exportErrorLog = () => {
console.log('导出错误')
const download_txt = (filename: string, content: string, contentType?: string) => {
if (!contentType) contentType = 'application/octet-stream';
var a = document.createElement('a');
var blob = new Blob([content], { 'type': contentType });
a.href = window.URL.createObjectURL(blob);
a.download = filename;
a.click();
}
const modalImportData = () => {
setModalStep(2)
setModalTitle(intl.formatMessage({ id: 'commodity.products.modalTitle.3' }))
console.log('下一步,导入数据')
setModalStep(0)
setImportModal(false)
ref.current.reload()
}
const step0Description = <>
......@@ -455,10 +460,6 @@ const Products: React.FC<{}> = () => {
</ul>
</>
const step1Description = <div className={styles.step1Description}>
<h4>{intl.formatMessage({ id: 'commodity.products.step1Description.text.1' })}</h4>
<p>{intl.formatMessage({ id: 'commodity.products.step1Description.text.2' })}</p>
</div>
const step1DescripSuccess = <div className={styles.step1Description}>
<h4>{intl.formatMessage({ id: 'commodity.products.step1DescripSuccess.text.1' })}</h4>
<p>{intl.formatMessage({ id: 'commodity.products.step1DescripSuccess.text.2' })}</p>
......@@ -470,72 +471,11 @@ const Products: React.FC<{}> = () => {
<p>{intl.formatMessage({ id: 'commodity.products.step1Exception.text.2' })}</p>
</div>
const step2Description = <div className={styles.step1Description}>
<h4>{intl.formatMessage({ id: 'commodity.products.step2Description.text.1' })}</h4>
<p>{intl.formatMessage({ id: 'commodity.products.step2Description.text.2' })}</p>
</div>
const step2DescripSuccess = <div className={styles.step1Description}>
<h4>{intl.formatMessage({ id: 'commodity.products.step2DescripSuccess.text.1' })}</h4>
<p>{intl.formatMessage({ id: 'commodity.products.step2DescripSuccess.text.2' })}</p>
<Button type="primary">{intl.formatMessage({ id: 'commodity.products.step2DescripSuccess.button.1' })}</Button>&nbsp;&nbsp;&nbsp;&nbsp;<Button>{intl.formatMessage({ id: 'commodity.products.step2DescripSuccess.button.2' })}</Button>
</div>
const step2Exception = <div className={styles.step1Description}>
<h4>{intl.formatMessage({ id: 'commodity.products.step2Exception.text.1' })}</h4>
<p>{intl.formatMessage({ id: 'commodity.products.step2Exception.text.2' })}</p>
</div>
const [step1DescriptState, setStep1DescriptState] = useState(step1DescripSuccess)
const [step1DescriptState, setStep1DescriptState] = useState(step1Description)
const [step2DescriptState, setStep2DescriptState] = useState(step2Description)
// timer
const [exceptionContent, setExceptionContent] = useState<string>()
const [exceptionCheck, setExceptionCheck] = useState(false); // 默认无异常
const [exceptionData, setExceptionData] = useState(false); // 默认无异常
const [time, setTime] = useState(0); // timer
useEffect(() => {
clearInterval(timeChange)
}, [])
useEffect(() => {
console.log(modalStep)
if (modalStep === 1) runTimer()
if (modalStep === 2) runTimer()
}, [modalStep])
useEffect(() => {
if (time >= 100) {
clearInterval(timeChange)
setTime(100)
if (modalStep === 1) setStep1DescriptState(step1DescripSuccess)
if (modalStep === 2) setStep2DescriptState(step2DescripSuccess)
console.log('倒计时完毕!', modalStep)
}
}, [time])
const runTimer = () => {
setTime(0)
timeChange = setInterval(() => setTime(t => t + Math.floor(Math.random() * 10)), 200)
}
//timer end
const step1Icon = <>
<Progress
type="circle"
strokeColor={{
'0%': '#669EDE',
'100%': '#41CC9E',
}}
percent={time}
/>
</>
const step2Icon = <>
<Progress
type="circle"
strokeColor={{
'0%': '#669EDE',
'100%': '#41CC9E',
}}
percent={time}
/>
</>
const [importLoading, setImportLoading] = useState(false)
const handleOkDeleteBatch = () => {
setDeleteBatchModal(false)
......@@ -968,6 +908,40 @@ const Products: React.FC<{}> = () => {
console.log(key, 'key')
}
// 导入商品
const importProps = {
name: 'file',
action: '/api/product/commodity/importCommodity',
headers: {
token,
},
showUploadList: false,
maxCount: 1,
className: styles.importBtn,
onChange(info) {
setImportLoading(true)
setModalTitle(intl.formatMessage({ id: 'commodity.products.modalTitle.1' }))
if (info.file.status !== 'uploading') {
console.log(info.file);
}
if (info.file.status === 'done') {
console.log(info.file)
setModalStep(1)
setExceptionContent(info.file.response.message)
if(info.file.response.code === 1000) {
setExceptionCheck(false)
setStep1DescriptState(step1DescripSuccess)
} else {
setExceptionContent(info.file.response.message)
setExceptionCheck(true)
setStep1DescriptState(step1Exception)
}
} else if (info.file.status === 'error') {
console.log(info.file)
}
},
};
return (
<PageHeaderWrapper>
<Card>
......@@ -1037,14 +1011,18 @@ const Products: React.FC<{}> = () => {
<Result
icon={<FileExcelOutlined />}
title={step0Description}
extra={<Button style={{ width: '100%' }} type="primary" onClick={modalUpload}>{intl.formatMessage({ id: 'commodity.products.modal.button.1' })}</Button>}
extra={
<Upload {...importProps}>
<Button style={{ width: '100%' }} type="primary" loading={importLoading}>{intl.formatMessage({ id: 'commodity.products.modal.button.1' })}</Button>
</Upload>
}
/>
</>
}
{
modalStep === 1 && !exceptionCheck && <>
<Result
icon={step1Icon}
icon={<Progress type="circle" percent={100} status="success" />}
title={step1DescriptState}
/>
</>
......@@ -1058,23 +1036,6 @@ const Products: React.FC<{}> = () => {
/>
</>
}
{
modalStep === 2 && !exceptionData && <>
<Result
icon={step2Icon}
title={step2DescriptState}
/>
</>
}
{
modalStep === 2 && exceptionData && <>
<Result
icon={<Progress type="circle" percent={100} status="exception" />}
title={step2Exception}
extra={<Button onClick={exportErrorLog}>{intl.formatMessage({ id: 'commodity.products.modal.button.2' })}</Button>}
/>
</>
}
</Modal>
<Modal
title={intl.formatMessage({ id: 'commodity.products.modal.title.1' })}
......
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