Commit e4d80846 authored by 前端-黄佳鑫's avatar 前端-黄佳鑫

feat: 采购能力 -> 采购竞价国际化

parent 05440b86
...@@ -14,7 +14,7 @@ export default defineConfig({ ...@@ -14,7 +14,7 @@ export default defineConfig({
// "@formily/antd-components": 'FormilyComponent', // "@formily/antd-components": 'FormilyComponent',
// "@lingxi-design/ui": 'LingxiDesignUI', // "@lingxi-design/ui": 'LingxiDesignUI',
// 对antd的组件做一个远程映射 // 对antd的组件做一个远程映射
...ExternalsAntd // ...ExternalsAntd
}, },
scripts: [ scripts: [
'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/react.production.min.js', 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/react.production.min.js',
...@@ -23,7 +23,7 @@ export default defineConfig({ ...@@ -23,7 +23,7 @@ export default defineConfig({
'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/data-set.js', 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/data-set.js',
'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/BizCharts.min.js', 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/BizCharts.min.js',
// 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/LingXiUI.min.js', // 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/LingXiUI.min.js',
'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/antd.min.js', // 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/antd.min.js',
// 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/formily-component.min.js', // 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/formily-component.min.js',
// 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/lingxi-design-ui.min.js', // 'http://lingxi-frontend-prod.oss-cn-hangzhou.aliyuncs.com/static/js/lingxi-design-ui.min.js',
], ],
......
...@@ -2,8 +2,10 @@ const PurchaseLocales = { ...@@ -2,8 +2,10 @@ const PurchaseLocales = {
// table // table
'table.purchase.added': '新建', 'table.purchase.added': '新建',
'table.purchase.more': '更多', 'table.purchase.more': '更多',
'table.purchase.showMore': '显示更多',
'table.purchase.eidt': '修改', 'table.purchase.eidt': '修改',
'table.purchase.submit': '提交', 'table.purchase.submit': '提交',
'table.purchase.confirm': '确认',
'table.purchase.delete': '删除', 'table.purchase.delete': '删除',
'table.purchase.purchasePlanNo': '需求计划编号/摘要', 'table.purchase.purchasePlanNo': '需求计划编号/摘要',
'table.purchase.purchasePlanNo1': '需求计划编号/摘要', 'table.purchase.purchasePlanNo1': '需求计划编号/摘要',
...@@ -17,6 +19,7 @@ const PurchaseLocales = { ...@@ -17,6 +19,7 @@ const PurchaseLocales = {
'table.purchase.audit': '审核', 'table.purchase.audit': '审核',
'table.purchase.see': '查看', 'table.purchase.see': '查看',
'table.purchase.id': '序号', 'table.purchase.id': '序号',
'table.purchase.bidManage': '竞价管理',
'table.purchase.result': '确认授标结果', 'table.purchase.result': '确认授标结果',
'table.purchase.code': '招标编号/项目', 'table.purchase.code': '招标编号/项目',
'table.purchase.memberName': '招标会员', 'table.purchase.memberName': '招标会员',
...@@ -104,17 +107,27 @@ const PurchaseLocales = { ...@@ -104,17 +107,27 @@ const PurchaseLocales = {
'table.purchase.moduleWarning1': '请先创建采购门户!', 'table.purchase.moduleWarning1': '请先创建采购门户!',
// detail // detail
'detail.purchase.rankHeader': '竞价排名',
'detail.purchase.email': '电子邮箱', 'detail.purchase.email': '电子邮箱',
'detail.purchase.unitAddress': '单位地址', 'detail.purchase.unitAddress': '单位地址',
'detail.purchase.startSignUp': '报名要求时间', 'detail.purchase.startSignUp': '报名要求时间',
'detail.purchase.demandUrls': '报名要求附件', 'detail.purchase.demandUrls': '报名要求附件',
'detail.purchase.biddingStartTime': '竞价时间', 'detail.purchase.biddingStartTime': '竞价时间',
'detail.purchase.startingPrice': '起拍价', 'detail.purchase.startingPrice': '起拍价',
'detail.purchase.isStartingPrice': '是否有起拍价',
'detail.purchase.isStartingPrice1': '是否有目标价',
'detail.purchase.targetPrice': '目标价', 'detail.purchase.targetPrice': '目标价',
'detail.purchase.minPrice': '最小价差', 'detail.purchase.minPrice': '最小价差',
'detail.purchase.minPrice1': '最低价',
'detail.purchase.nowMinPrice1': '当前最低价',
'detail.purchase.isMinPrice': '是否有最小价差',
'detail.purchase.allowPurchaseCount': '允许报价次数', 'detail.purchase.allowPurchaseCount': '允许报价次数',
'detail.purchase.allowPurchaseCount1': '报价次数',
'detail.purchase.offerRank': '报价排名',
'detail.purchase.isOpenPurchase': '公开当前最低报价', 'detail.purchase.isOpenPurchase': '公开当前最低报价',
'detail.purchase.isOpenPurchase1': '是否公开当前最低报价',
'detail.purchase.isOpenRanking': '公开报价排名', 'detail.purchase.isOpenRanking': '公开报价排名',
'detail.purchase.isOpenRanking1': '是否公开报价排名',
'detail.purchase.externalLogStates': '外部流转', 'detail.purchase.externalLogStates': '外部流转',
'detail.purchase.interiorLogStates': '内部流转', 'detail.purchase.interiorLogStates': '内部流转',
'detail.purchase.examineInteriorLogStates': '竞价结果内部流转', 'detail.purchase.examineInteriorLogStates': '竞价结果内部流转',
...@@ -142,8 +155,10 @@ const PurchaseLocales = { ...@@ -142,8 +155,10 @@ const PurchaseLocales = {
'detail.purchase.summary': '采购计划摘要', 'detail.purchase.summary': '采购计划摘要',
'detail.purchase.innerStatus': '内部状态', 'detail.purchase.innerStatus': '内部状态',
'detail.purchase.startTime': '采购计划开始', 'detail.purchase.startTime': '采购计划开始',
'detail.purchase.startTime1': '开始时间',
'detail.purchase.purchaseStartTime': '计划开始时间', 'detail.purchase.purchaseStartTime': '计划开始时间',
'detail.purchase.endTime': '采购计划截止', 'detail.purchase.endTime': '采购计划截止',
'detail.purchase.endTime1': '结束时间',
'detail.purchase.purchaseEndTime': '计划结束时间', 'detail.purchase.purchaseEndTime': '计划结束时间',
'detail.purchase.operate': '编制部门', 'detail.purchase.operate': '编制部门',
'detail.purchase.department': '编制人', 'detail.purchase.department': '编制人',
...@@ -164,6 +179,7 @@ const PurchaseLocales = { ...@@ -164,6 +179,7 @@ const PurchaseLocales = {
'detail.purchase.unitName': '单位', 'detail.purchase.unitName': '单位',
'detail.purchase.unitNameId': '单位ID', 'detail.purchase.unitNameId': '单位ID',
'detail.purchase.isTax': '含税', 'detail.purchase.isTax': '含税',
'detail.purchase.isTax1': '含税/税率',
'detail.purchase.taxProbability': '税率', 'detail.purchase.taxProbability': '税率',
'detail.purchase.taxUnitPrice': '单价(含税)', 'detail.purchase.taxUnitPrice': '单价(含税)',
'detail.purchase.taxPrice': '金额(含税)', 'detail.purchase.taxPrice': '金额(含税)',
...@@ -242,6 +258,21 @@ const PurchaseLocales = { ...@@ -242,6 +258,21 @@ const PurchaseLocales = {
'detail.purchase.entryMall': '进入店铺', 'detail.purchase.entryMall': '进入店铺',
'detail.purchase.jointType': '对接方式', 'detail.purchase.jointType': '对接方式',
'detail.purchase.seeBidStep': '查看竞价过程', 'detail.purchase.seeBidStep': '查看竞价过程',
'detail.purchase.cancelOffer': '取消报价',
'detail.purchase.statusBoxStatus': '当前状态',
'detail.purchase.stillRunStart': '竞价中',
'detail.purchase.stillRunend': '竞价结束',
'detail.purchase.distanceStillRunend': '距离竞价结束还剩',
'detail.purchase.hour': '小时',
'detail.purchase.minute': '分钟',
'detail.purchase.second': '秒',
'detail.purchase.offerRule': '报价规则',
'detail.purchase.offerRule1': '项目总价(含税)',
'detail.purchase.offerRule2': '公开最低报价',
'detail.purchase.offerRule3': '我要报价',
'detail.purchase.offerRule4': '按项目总价排名',
'detail.purchase.offerRule5': '按项目总价排名',
'detail.purchase.null': '无',
'detail.purchase.modalTitle': '公开招标', 'detail.purchase.modalTitle': '公开招标',
'detail.purchase.modalTitle1': '选择货品', 'detail.purchase.modalTitle1': '选择货品',
...@@ -257,6 +288,7 @@ const PurchaseLocales = { ...@@ -257,6 +288,7 @@ const PurchaseLocales = {
'detail.purchase.modalTitle11': '确认竞价结果', 'detail.purchase.modalTitle11': '确认竞价结果',
'detail.purchase.modalTitle12': '提交竞价结果', 'detail.purchase.modalTitle12': '提交竞价结果',
'detail.purchase.modalTitle13': '报价明细', 'detail.purchase.modalTitle13': '报价明细',
'detail.purchase.modalTitle14': '竞价详情',
'detail.purchase.message1': '投标开始时间必须大于报名截止时间', 'detail.purchase.message1': '投标开始时间必须大于报名截止时间',
'detail.purchase.message2': '投标开始时间必须大于资质预审截止时间', 'detail.purchase.message2': '投标开始时间必须大于资质预审截止时间',
...@@ -300,6 +332,20 @@ const PurchaseLocales = { ...@@ -300,6 +332,20 @@ const PurchaseLocales = {
'detail.purchase.message40': '请选择对接方式', 'detail.purchase.message40': '请选择对接方式',
'detail.purchase.message41': '请选择会员', 'detail.purchase.message41': '请选择会员',
'detail.purchase.message42': '请勾选要汇总生成订单', 'detail.purchase.message42': '请勾选要汇总生成订单',
'detail.purchase.message43': '请输入竞价单摘要',
'detail.purchase.message44': '请添加适用地市',
'detail.purchase.message45': '请选择报名要求时间',
'detail.purchase.message46': '报名结束需要早于竞价开始时间',
'detail.purchase.message47': '请选择竞价时间',
'detail.purchase.message48': '竞价开始时间需要晚于报名截止时间',
'detail.purchase.message49': '起拍价不可为0',
'detail.purchase.message50': '目标价不可为0',
'detail.purchase.message51': '最小价差不可为0',
'detail.purchase.message52': '允许报价次数最小价差',
'detail.purchase.message53': '允许报价次数不可为0',
'detail.purchase.message54': '请选择交付日期',
'detail.purchase.message55': '请选择交付地址',
'detail.purchase.message56': '请输入金额',
'detail.purchase.placeholder': '选择开始日期', 'detail.purchase.placeholder': '选择开始日期',
'detail.purchase.placeholder1': '确定要执行这个操作?', 'detail.purchase.placeholder1': '确定要执行这个操作?',
...@@ -307,6 +353,13 @@ const PurchaseLocales = { ...@@ -307,6 +353,13 @@ const PurchaseLocales = {
'detail.purchase.placeholder3': '最长12个字符,6个汉字', 'detail.purchase.placeholder3': '最长12个字符,6个汉字',
'detail.purchase.placeholder4': '最长60个字符,30个汉字', 'detail.purchase.placeholder4': '最长60个字符,30个汉字',
'detail.purchase.placeholder5': '最长100字符,50个汉字', 'detail.purchase.placeholder5': '最长100字符,50个汉字',
'detail.purchase.placeholder6': '请选择市',
'detail.purchase.placeholder7': '请选择省',
'detail.purchase.placeholder8': '最长200个字符,100个汉字',
'detail.purchase.placeholder9': '请输入起拍价',
'detail.purchase.placeholder10': '请输入目标价',
'detail.purchase.placeholder11': '请输入最小价差',
'detail.purchase.placeholder12': '请输入报价次数',
'detail.purchase.priceMethod': '比价方式', 'detail.purchase.priceMethod': '比价方式',
'detail.purchase.purchaseType1': '有固定采购金额', 'detail.purchase.purchaseType1': '有固定采购金额',
...@@ -331,6 +384,9 @@ const PurchaseLocales = { ...@@ -331,6 +384,9 @@ const PurchaseLocales = {
'detail.purchase.tips14': '选择公开报价排名,竞价过程中将供应商当前报价排名在竞价页面即时公开。', 'detail.purchase.tips14': '选择公开报价排名,竞价过程中将供应商当前报价排名在竞价页面即时公开。',
'detail.purchase.isMix1': '公开当前最低', 'detail.purchase.isMix1': '公开当前最低',
'detail.purchase.isMix2': '报价', 'detail.purchase.isMix2': '报价',
'detail.purchase.tips15': '当前报价金额不满足最小价差要求,请修改后再报价!',
'detail.purchase.tips16': '当前报价次数已超过允许报价次数!',
} }
export default PurchaseLocales export default PurchaseLocales
import React, { useState, useRef, useEffect } from 'react'; import React, { useState, useRef, useEffect } from 'react';
import { history } from 'umi'; import { getIntl, history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout'; import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { SaveOutlined } from '@ant-design/icons'; import { SaveOutlined } from '@ant-design/icons';
import { Tabs, Card, Button, Badge } from 'antd'; import { Tabs, Card, Button, Badge } from 'antd';
...@@ -17,6 +17,7 @@ import BidRequirement from './components/bidRequirement'; ...@@ -17,6 +17,7 @@ import BidRequirement from './components/bidRequirement';
import Condition from './components/condition'; import Condition from './components/condition';
import File from './components/file'; import File from './components/file';
const intl = getIntl();
const { TabPane } = Tabs; const { TabPane } = Tabs;
...@@ -198,15 +199,15 @@ const AddForm = () => { ...@@ -198,15 +199,15 @@ const AddForm = () => {
return ( return (
<PageHeaderWrapper <PageHeaderWrapper
onBack={() => history.goBack()} onBack={() => history.goBack()}
backIcon={<ReutrnEle description="返回" />} backIcon={<ReutrnEle description={intl.formatMessage({ id: 'detail.purchase.back' })} />}
extra={ extra={
<Button loading={loading} type="primary" onClick={handleSubmit}><SaveOutlined /> 保存</Button> <Button loading={loading} type="primary" onClick={handleSubmit}><SaveOutlined /> {intl.formatMessage({ id: 'detail.purchase.save' })}</Button>
} }
> >
<Card> <Card>
<Tabs type='card'> <Tabs type='card'>
{/* 基本信息 */} {/* 基本信息 */}
<TabPane key='1' tab={<TabFormErrors dot={badge[0]}>基本信息</TabFormErrors>} forceRender> <TabPane key='1' tab={<TabFormErrors dot={badge[0]}>{intl.formatMessage({ id: 'detail.purchase.basicLayout' })}</TabFormErrors>} forceRender>
<Basic <Basic
currentRef={currentBasic} currentRef={currentBasic}
fetchdata={basic} fetchdata={basic}
...@@ -214,7 +215,7 @@ const AddForm = () => { ...@@ -214,7 +215,7 @@ const AddForm = () => {
/> />
</TabPane> </TabPane>
{/* 添加采购物料 */} {/* 添加采购物料 */}
<TabPane key='2' tab={<TabFormErrors dot={badge[1]}>采购物料</TabFormErrors>} forceRender> <TabPane key='2' tab={<TabFormErrors dot={badge[1]}>{intl.formatMessage({ id: 'detail.purchase.materialLayout' })}</TabFormErrors>} forceRender>
<Material <Material
currentRef={currentMaterial} currentRef={currentMaterial}
fetchdata={material} fetchdata={material}
...@@ -222,7 +223,7 @@ const AddForm = () => { ...@@ -222,7 +223,7 @@ const AddForm = () => {
/> />
</TabPane> </TabPane>
{/* 竞价规则 */} {/* 竞价规则 */}
<TabPane key='3' tab={<TabFormErrors dot={badge[2]}>竞价规则</TabFormErrors>} forceRender> <TabPane key='3' tab={<TabFormErrors dot={badge[2]}>{intl.formatMessage({ id: 'detail.purchase.bidRulesLayout' })}</TabFormErrors>} forceRender>
<BidRules <BidRules
currentRef={currentRules} currentRef={currentRules}
fetchdata={rules} fetchdata={rules}
...@@ -231,7 +232,7 @@ const AddForm = () => { ...@@ -231,7 +232,7 @@ const AddForm = () => {
/> />
</TabPane> </TabPane>
{/* 报名要求 */} {/* 报名要求 */}
<TabPane key='4' tab={<TabFormErrors dot={badge[3]}>报名要求</TabFormErrors>} forceRender> <TabPane key='4' tab={<TabFormErrors dot={badge[3]}>{intl.formatMessage({ id: 'detail.purchase.signUpLayout' })}</TabFormErrors>} forceRender>
<BidRequirement <BidRequirement
currentRef={currentRequirement} currentRef={currentRequirement}
fetchdata={requirement} fetchdata={requirement}
...@@ -240,7 +241,7 @@ const AddForm = () => { ...@@ -240,7 +241,7 @@ const AddForm = () => {
/> />
</TabPane> </TabPane>
{/* 交易条件 */} {/* 交易条件 */}
<TabPane key='5' tab={<TabFormErrors dot={badge[4]}>交易条件</TabFormErrors>} forceRender> <TabPane key='5' tab={<TabFormErrors dot={badge[4]}>{intl.formatMessage({ id: 'detail.purchase.conditionLayout' })}</TabFormErrors>} forceRender>
<Condition <Condition
currentRef={currentCondition} currentRef={currentCondition}
fetchdata={condition} fetchdata={condition}
...@@ -248,7 +249,7 @@ const AddForm = () => { ...@@ -248,7 +249,7 @@ const AddForm = () => {
/> />
</TabPane> </TabPane>
{/* 需求对接 */} {/* 需求对接 */}
<TabPane key='6' tab={<TabFormErrors dot={badge[5]}>需求对接</TabFormErrors>} forceRender> <TabPane key='6' tab={<TabFormErrors dot={badge[5]}>{intl.formatMessage({ id: 'detail.purchase.demandLayout' })}</TabFormErrors>} forceRender>
<Demand <Demand
currentRef={currentDemand} currentRef={currentDemand}
fetchdata={demand} fetchdata={demand}
...@@ -256,7 +257,7 @@ const AddForm = () => { ...@@ -256,7 +257,7 @@ const AddForm = () => {
badgeIndex={5} badgeIndex={5}
/> />
</TabPane> </TabPane>
<TabPane key='7' tab='附件' forceRender> <TabPane key='7' tab={intl.formatMessage({ id: 'detail.purchase.file' })} forceRender>
<File <File
fetchdata={file} fetchdata={file}
currentRef={currentFile} currentRef={currentFile}
......
...@@ -133,7 +133,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -133,7 +133,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
if (requisitionFormAddress[idx].provinceCode && requisitionFormAddress[idx].cityCode) { if (requisitionFormAddress[idx].provinceCode && requisitionFormAddress[idx].cityCode) {
setrequisitionFormAddress([...requisitionFormAddress, address]) setrequisitionFormAddress([...requisitionFormAddress, address])
} else { } else {
message.error('请完善适用城市信息') message.error(intl.formatMessage({ id: 'detail.purchase.message35' }))
} }
} }
...@@ -217,23 +217,23 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -217,23 +217,23 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
className={style.form} className={style.form}
> >
<Form.Item <Form.Item
label='竞价单摘要' label={intl.formatMessage({ id: 'detail.purchase.biddingDetails' })}
name='details' name='details'
rules={[ rules={[
{ required: true, message: '请输入竞价单摘要' }, { required: true, message: intl.formatMessage({ id: 'detail.purchase.message43' }) },
{ {
validator: (r, v) => validatorByte(v, 60) validator: (r, v) => validatorByte(v, 60)
} }
]} ]}
> >
<Input maxLength={60} placeholder='最长60个字符,30个汉字' /> <Input maxLength={60} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder4' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
rules={[ rules={[
{ required: true, message: '请添加适用地市' }, { required: true, message: intl.formatMessage({ id: 'detail.purchase.message44' }) },
]} ]}
required required
label={<Tooltip placement="right" title='设置了归属地市后,此商品可根据地市进行筛选,未设置时默认为所有地市'>适用地市<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip>} label={<Tooltip placement="right" title={intl.formatMessage({ id: 'detail.purchase.tips4' })}>{intl.formatMessage({ id: 'detail.purchase.areas' })}<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip>}
style={{ marginBottom: '0' }} style={{ marginBottom: '0' }}
> >
{requisitionFormAddress.map((item: any, idx: number) => { {requisitionFormAddress.map((item: any, idx: number) => {
...@@ -246,7 +246,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -246,7 +246,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
onChange={(value) => { onChange={(value) => {
handProvince(value, idx, 1) handProvince(value, idx, 1)
}} }}
placeholder='请选择省' placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder7' })}
> >
{province.map(items => { {province.map(items => {
return ( return (
...@@ -265,7 +265,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -265,7 +265,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
onChange={(value) => { onChange={(value) => {
handProvince(value, idx, 2) handProvince(value, idx, 2)
}} }}
placeholder='请选择市' placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder6' })}
> >
{(item.provinceCode && city.length > 0 && city[idx]) && city[idx].citydata.map(items => { {(item.provinceCode && city.length > 0 && city[idx]) && city[idx].citydata.map(items => {
return ( return (
...@@ -294,7 +294,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -294,7 +294,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
})} })}
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label='会员名称' label={intl.formatMessage({ id: 'detail.purchase.memberName' })}
name='memberName' name='memberName'
> >
<Text strong>{(fetchdata && fetchdata.memberName) && fetchdata.memberName}</Text> <Text strong>{(fetchdata && fetchdata.memberName) && fetchdata.memberName}</Text>
...@@ -306,7 +306,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => { ...@@ -306,7 +306,7 @@ const BasicInfo: React.FC<Iprops> = (props: any) => {
<Text strong>{(fetchdata && fetchdata.createTime) && formatTimeString(fetchdata.createTime)}</Text> <Text strong>{(fetchdata && fetchdata.createTime) && formatTimeString(fetchdata.createTime)}</Text>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label='竞价单号' label={intl.formatMessage({ id: 'detail.purchase.biddingNo' })}
name='purchaseInquiryNo' name='purchaseInquiryNo'
> >
<Text strong>{(fetchdata && fetchdata.biddingNo) && fetchdata.biddingNo}</Text> <Text strong>{(fetchdata && fetchdata.biddingNo) && fetchdata.biddingNo}</Text>
......
...@@ -16,6 +16,9 @@ import { getAuth } from '@/utils/auth' ...@@ -16,6 +16,9 @@ import { getAuth } from '@/utils/auth'
import { validatorByte } from '../../validator'; import { validatorByte } from '../../validator';
import styles from './index.less'; import styles from './index.less';
import { getIntl } from 'umi';
const intl = getIntl();
const { TextArea } = Input; const { TextArea } = Input;
const layout: any = { const layout: any = {
...@@ -79,7 +82,7 @@ const BidRequirement: React.FC<Iprops> = (props: any) => { ...@@ -79,7 +82,7 @@ const BidRequirement: React.FC<Iprops> = (props: any) => {
const beforeDocUpload = (file: any) => { const beforeDocUpload = (file: any) => {
const isLt20M = file.size / 1024 / 1024 < 20; const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) { if (!isLt20M) {
message.error('上传文件大小不超过 20M!'); message.error(intl.formatMessage({ id: 'detail.purchase.message21' }));
} }
return isLt20M; return isLt20M;
} }
...@@ -117,17 +120,17 @@ const BidRequirement: React.FC<Iprops> = (props: any) => { ...@@ -117,17 +120,17 @@ const BidRequirement: React.FC<Iprops> = (props: any) => {
className={styles.revise_style} className={styles.revise_style}
> >
<Form.Item <Form.Item
label='报名要求时间' label={intl.formatMessage({ id: 'detail.purchase.startSignUp' })}
name='signUpTime' name='signUpTime'
rules={[ rules={[
{ required: true, message: '请选择报名要求时间' }, () => ({ { required: true, message: intl.formatMessage({ id: 'detail.purchase.message45' }) }, () => ({
async validator(_, value) { async validator(_, value) {
let _exVal = await exRef.current.biddingTime(); let _exVal = await exRef.current.biddingTime();
if (_exVal[0] && moment(value[1]).isAfter(_exVal[0])) { if (_exVal[0] && moment(value[1]).isAfter(_exVal[0])) {
return Promise.reject(new Error('报名结束需要早于竞价开始时间')); return Promise.reject(new Error(intl.formatMessage({ id: 'detail.purchase.message46' })));
} }
if (!value[0] || !value[1]) { if (!value[0] || !value[1]) {
return Promise.reject(new Error('请选择报名要求时间')); return Promise.reject(new Error(intl.formatMessage({ id: 'detail.purchase.message45' })));
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
...@@ -138,13 +141,13 @@ const BidRequirement: React.FC<Iprops> = (props: any) => { ...@@ -138,13 +141,13 @@ const BidRequirement: React.FC<Iprops> = (props: any) => {
<DatePicker.RangePicker <DatePicker.RangePicker
showTime showTime
format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
placeholder={['开始时间', '结束时间']} placeholder={[intl.formatMessage({ id: 'detail.purchase.startTime1' }), intl.formatMessage({ id: 'detail.purchase.endTime1' })]}
disabledDate={(current) => { disabledDate={(current) => {
return current && current < moment().startOf('second') return current && current < moment().startOf('second')
}} /> }} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="报名要求" label={intl.formatMessage({ id: 'detail.purchase.signUpLayout' })}
name="demand" name="demand"
rules={[ rules={[
// { required: true, message: '请输入报名要求' }, // { required: true, message: '请输入报名要求' },
...@@ -153,10 +156,10 @@ const BidRequirement: React.FC<Iprops> = (props: any) => { ...@@ -153,10 +156,10 @@ const BidRequirement: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={200} placeholder="最长200个字符,100个汉字" /> <TextArea rows={3} maxLength={200} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder8' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="报名要求附件" label={intl.formatMessage({ id: 'detail.purchase.demandUrls' })}
name="demandUrls" name="demandUrls"
// rules={[{ required: true, message: '请上传报名要求附件' }]} // rules={[{ required: true, message: '请上传报名要求附件' }]}
> >
...@@ -182,8 +185,8 @@ const BidRequirement: React.FC<Iprops> = (props: any) => { ...@@ -182,8 +185,8 @@ const BidRequirement: React.FC<Iprops> = (props: any) => {
onChange={handleChange} onChange={handleChange}
headers={{ token }} headers={{ token }}
> >
<Button loading={loading} icon={<UploadOutlined />}>上传文件</Button> <Button loading={loading} icon={<UploadOutlined />}>{intl.formatMessage({ id: 'detail.purchase.uploadFile' })}</Button>
<div style={{ marginTop: '8px' }}>一次上传一个文件,每个附件大小不能超过 20M</div> <div style={{ marginTop: '8px' }}>{intl.formatMessage({ id: 'detail.purchase.placeholder2' })}</div>
</Upload> </Upload>
</Form.Item> </Form.Item>
</Form> </Form>
......
...@@ -7,6 +7,7 @@ import { getLogisticsSelectListReceiverAddress } from '@/services/LogisticsV2Api ...@@ -7,6 +7,7 @@ import { getLogisticsSelectListReceiverAddress } from '@/services/LogisticsV2Api
import { validatorByte } from '../../validator'; import { validatorByte } from '../../validator';
import style from './index.less'; import style from './index.less';
import { getIntl } from 'umi';
const { TextArea } = Input; const { TextArea } = Input;
const { Option } = Select; const { Option } = Select;
...@@ -23,6 +24,8 @@ interface Iprops { ...@@ -23,6 +24,8 @@ interface Iprops {
onBadge: (num: number, idx: number) => void onBadge: (num: number, idx: number) => void
} }
const intl = getIntl();
export type ADDRESS_TYPE = { export type ADDRESS_TYPE = {
address: string, address: string,
addressId: number, addressId: number,
...@@ -117,9 +120,9 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -117,9 +120,9 @@ const Condition: React.FC<Iprops> = (props: any) => {
className={style.form} className={style.form}
> >
<Form.Item <Form.Item
label="交付日期" label={intl.formatMessage({ id: 'table.purchase.deliveryTime' })}
name="deliver" name="deliver"
rules={[{ required: true, message: '请选择交付日期' }]} rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message54' }) }]}
> >
<DatePicker style={{ width: '100%' }} <DatePicker style={{ width: '100%' }}
disabledDate={(current) => { disabledDate={(current) => {
...@@ -128,13 +131,13 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -128,13 +131,13 @@ const Condition: React.FC<Iprops> = (props: any) => {
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="交付地址" label={intl.formatMessage({ id: 'detail.purchase.address' })}
name='addressId' name='addressId'
rules={[{ required: true, message: '请选择交付地址' }]} rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message55' }) }]}
> >
<Select <Select
onSelect={handleSelectAddress} onSelect={handleSelectAddress}
placeholder='请选择交付地址' placeholder={intl.formatMessage({ id: 'detail.purchase.message55' })}
> >
{address.map(v => ( {address.map(v => (
<Option key={v.id} value={v.id}>{v.fullAddress}</Option> <Option key={v.id} value={v.id}>{v.fullAddress}</Option>
...@@ -142,7 +145,7 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -142,7 +145,7 @@ const Condition: React.FC<Iprops> = (props: any) => {
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="报价要求" label={intl.formatMessage({ id: 'detail.purchase.offerAsk' })}
name="offer" name="offer"
rules={[ rules={[
// { required: true, message: '请输入报价要求' }, // { required: true, message: '请输入报价要求' },
...@@ -151,10 +154,10 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -151,10 +154,10 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="付款方式" label={intl.formatMessage({ id: 'detail.purchase.paymentType' })}
name="paymentType" name="paymentType"
rules={[ rules={[
// { required: true, message: '请输入付款方式' }, // { required: true, message: '请输入付款方式' },
...@@ -163,10 +166,10 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -163,10 +166,10 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="税费要求" label={intl.formatMessage({ id: 'detail.purchase.taxesAsk' })}
name="taxes" name="taxes"
rules={[ rules={[
// { required: true, message: '请输入税费要求' }, // { required: true, message: '请输入税费要求' },
...@@ -175,10 +178,10 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -175,10 +178,10 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="物流要求" label={intl.formatMessage({ id: 'detail.purchase.logisticsAsk' })}
name="logistics" name="logistics"
rules={[ rules={[
// { required: true, message: '请输入物流要求' }, // { required: true, message: '请输入物流要求' },
...@@ -187,10 +190,10 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -187,10 +190,10 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="包装要求" label={intl.formatMessage({ id: 'detail.purchase.packRequireAsk' })}
name="packRequire" name="packRequire"
rules={[ rules={[
// { required: true, message: '请输入包装要求' }, // { required: true, message: '请输入包装要求' },
...@@ -199,10 +202,10 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -199,10 +202,10 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
<Form.Item <Form.Item
label="其他要求" label={intl.formatMessage({ id: 'detail.purchase.otherRequireAsk' })}
name="otherRequire" name="otherRequire"
rules={[ rules={[
// { required: true, message: '请输入其他要求' }, // { required: true, message: '请输入其他要求' },
...@@ -211,7 +214,7 @@ const Condition: React.FC<Iprops> = (props: any) => { ...@@ -211,7 +214,7 @@ const Condition: React.FC<Iprops> = (props: any) => {
} }
]} ]}
> >
<TextArea rows={3} maxLength={100} placeholder="最长100个字符,50个汉字" /> <TextArea rows={3} maxLength={100} placeholder={intl.formatMessage({ id: 'detail.purchase.placeholder5' })} />
</Form.Item> </Form.Item>
</Form> </Form>
</> </>
......
...@@ -6,6 +6,7 @@ import { UPLOAD_TYPE } from '@/constants' ...@@ -6,6 +6,7 @@ import { UPLOAD_TYPE } from '@/constants'
import { getAuth } from '@/utils/auth' import { getAuth } from '@/utils/auth'
import styles from './index.less'; import styles from './index.less';
import { getIntl } from 'umi';
const layout: any = { const layout: any = {
colon: false, colon: false,
...@@ -14,6 +15,7 @@ const layout: any = { ...@@ -14,6 +15,7 @@ const layout: any = {
labelAlign: "left" labelAlign: "left"
}; };
const intl = getIntl()
export interface IProps { export interface IProps {
fetchdata: any, fetchdata: any,
currentRef: any currentRef: any
...@@ -30,7 +32,7 @@ const File: React.FC<IProps> = (props) => { ...@@ -30,7 +32,7 @@ const File: React.FC<IProps> = (props) => {
const beforeDocUpload = (file: any) => { const beforeDocUpload = (file: any) => {
const isLt20M = file.size / 1024 / 1024 < 20; const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) { if (!isLt20M) {
message.error('上传文件大小不超过 20M!'); message.error(intl.formatMessage({ id: 'detail.purchase.message21' }));
} }
return isLt20M; return isLt20M;
} }
...@@ -109,8 +111,8 @@ const File: React.FC<IProps> = (props) => { ...@@ -109,8 +111,8 @@ const File: React.FC<IProps> = (props) => {
onChange={handleChange} onChange={handleChange}
headers={{ token }} headers={{ token }}
> >
<Button loading={loading} icon={<UploadOutlined />}>上传文件</Button> <Button loading={loading} icon={<UploadOutlined />}>{intl.formatMessage({ id: 'detail.purchase.uploadFile' })}</Button>
<div style={{ marginTop: '8px' }}>一次上传一个文件,每个附件大小不能超过 20M</div> <div style={{ marginTop: '8px' }}>{intl.formatMessage({ id: 'detail.purchase.placeholder2' })}</div>
</Upload> </Upload>
</Form.Item> </Form.Item>
</Form> </Form>
......
...@@ -14,71 +14,71 @@ import Table from '../../components/table' ...@@ -14,71 +14,71 @@ import Table from '../../components/table'
const intl = getIntl(); const intl = getIntl();
import { import {
BID_EXTERNALSTATE_COLOR, BID_EXTERNALSTATE_COLOR,
BID_INTERNALSTATE_COLOR BID_INTERNALSTATE_COLOR
} from '../../constants/purchaseBid'; } from '../../constants/purchaseBid';
const { Text } = Typography; const { Text } = Typography;
const ReadyBid = () => { const ReadyBid = () => {
const ref = useRef<any>({}); const ref = useRef<any>({});
const columns: ColumnType<any>[] = [{ const columns: ColumnType<any>[] = [{
title: '序号', title: intl.formatMessage({ id: 'table.purchase.id' }),
align: 'center', align: 'center',
dataIndex: 'id', dataIndex: 'id',
key: 'id', key: 'id',
render: (t, r, i) => ++i render: (t, r, i) => ++i
}, { }, {
title: intl.formatMessage({ id: 'table.purchase.biddingNo' }), title: intl.formatMessage({ id: 'table.purchase.biddingNo' }),
key: 'biddingNo', key: 'biddingNo',
dataIndex: 'biddingNo', dataIndex: 'biddingNo',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
<Space direction='vertical' style={{width: 300}}> <Space direction='vertical' style={{ width: 300 }}>
<EyePreview url={`/memberCenter/procurementAbility/purchaseBid/readyBid/detail?id=${record.id}&number=${text}`}>{text}</EyePreview> <EyePreview url={`/memberCenter/procurementAbility/purchaseBid/readyBid/detail?id=${record.id}&number=${text}`}>{text}</EyePreview>
<Text type='secondary'>{record.details}</Text> <Text type='secondary'>{record.details}</Text>
</Space> </Space>
)
}, {
title: intl.formatMessage({ id: 'table.purchase.biddingStartTime' }),
key: 'biddingStartTime',
dataIndex: 'biddingStartTime',
render: (text: any, record: any) => <>
<div><PlayCircleOutlined />&nbsp;{formatTimeString(record.biddingStartTime)}</div>
<div><PoweroffOutlined />&nbsp;{formatTimeString(record.biddingEndTime)}</div>
</>,
width: 180
}, {
title: intl.formatMessage({ id: 'table.purchase.dementCreateTime' }),
key: 'createTime',
dataIndex: 'createTime',
render: (text: any, record: any) => formatTimeString(text),
width: 180
}, {
title: intl.formatMessage({ id: 'table.purchase.externalStatus' }),
key: 'externalState',
dataIndex: 'externalState',
render: (text: any, record: any) => <StatusTag type={BID_EXTERNALSTATE_COLOR(text)} title={record.externalStateName} />
}, {
title: intl.formatMessage({ id: 'table.purchase.innerStatus' }),
key: 'interiorState',
dataIndex: 'interiorState',
render: (text: any, record: any) => <Badge status={BID_INTERNALSTATE_COLOR(text)} text={record.interiorStateName} />
}, {
title: intl.formatMessage({ id: 'table.purchase.operate' }),
key: 'operate',
dataIndex: 'operate',
align: 'center',
render: (text: any, record: any) => <Button onClick={() => history.push(`/memberCenter/procurementAbility/purchaseBid/readyBid/management?id=${record.id}&number=${record.biddingNo}`)} type='link'>竞价管理</Button>
}];
return (
<Table
reload={ref}
schemaType="PURCHASEBIDOSIGNUP_SCHEMA"
columns={columns}
effects="biddingNo"
fetch={getPurchaseBiddingStayBiddingList}
/>
) )
}, {
title: intl.formatMessage({ id: 'table.purchase.biddingStartTime' }),
key: 'biddingStartTime',
dataIndex: 'biddingStartTime',
render: (text: any, record: any) => <>
<div><PlayCircleOutlined />&nbsp;{formatTimeString(record.biddingStartTime)}</div>
<div><PoweroffOutlined />&nbsp;{formatTimeString(record.biddingEndTime)}</div>
</>,
width: 180
}, {
title: intl.formatMessage({ id: 'table.purchase.dementCreateTime' }),
key: 'createTime',
dataIndex: 'createTime',
render: (text: any, record: any) => formatTimeString(text),
width: 180
}, {
title: intl.formatMessage({ id: 'table.purchase.externalStatus' }),
key: 'externalState',
dataIndex: 'externalState',
render: (text: any, record: any) => <StatusTag type={BID_EXTERNALSTATE_COLOR(text)} title={record.externalStateName} />
}, {
title: intl.formatMessage({ id: 'table.purchase.innerStatus' }),
key: 'interiorState',
dataIndex: 'interiorState',
render: (text: any, record: any) => <Badge status={BID_INTERNALSTATE_COLOR(text)} text={record.interiorStateName} />
}, {
title: intl.formatMessage({ id: 'table.purchase.operate' }),
key: 'operate',
dataIndex: 'operate',
align: 'center',
render: (text: any, record: any) => <Button onClick={() => history.push(`/memberCenter/procurementAbility/purchaseBid/readyBid/management?id=${record.id}&number=${record.biddingNo}`)} type='link'>{intl.formatMessage({ id: 'table.purchase.bidManage' })}</Button>
}];
return (
<Table
reload={ref}
schemaType="PURCHASEBIDOSIGNUP_SCHEMA"
columns={columns}
effects="biddingNo"
fetch={getPurchaseBiddingStayBiddingList}
/>
)
} }
export default ReadyBid export default ReadyBid
...@@ -10,59 +10,61 @@ import TriangleTag from '../triangleTag'; ...@@ -10,59 +10,61 @@ import TriangleTag from '../triangleTag';
import RankRow from '../rankRow'; import RankRow from '../rankRow';
import styles from './index.less'; import styles from './index.less';
import { getIntl } from 'umi';
const { TabPane } = Tabs; const { TabPane } = Tabs;
const intl = getIntl();
interface RankItemDetail { interface RankItemDetail {
dynamic : any, dynamic: any,
queryPriceDynamics : any, queryPriceDynamics: any,
signupMembers : any signupMembers: any
} }
interface RankItemProps { interface RankItemProps {
onTabChange: (key: string) => void, onTabChange: (key: string) => void,
detail: RankItemDetail detail: RankItemDetail
} }
const RankItem: React.FC<RankItemProps> = (props: any) => { const RankItem: React.FC<RankItemProps> = (props: any) => {
const { onTabChange, detail } = props; const { onTabChange, detail } = props;
const { queryPriceDynamics = [], signupMembers = [], dynamic = {} } = detail; const { queryPriceDynamics = [], signupMembers = [], dynamic = {} } = detail;
const [showMoreQuery, setShowMoreQuery] = useState<boolean>(false); const [showMoreQuery, setShowMoreQuery] = useState<boolean>(false);
const [showMoreSign, setShowMoreSign] = useState<boolean>(false); const [showMoreSign, setShowMoreSign] = useState<boolean>(false);
const queryPriceDynamicsData = showMoreQuery ? [...queryPriceDynamics].splice(0, 10) : queryPriceDynamics; const queryPriceDynamicsData = showMoreQuery ? [...queryPriceDynamics].splice(0, 10) : queryPriceDynamics;
const signupMembersData = showMoreSign ? [...signupMembers].splice(0, 10) : signupMembers; const signupMembersData = showMoreSign ? [...signupMembers].splice(0, 10) : signupMembers;
return ( return (
<div className={styles.rank}> <div className={styles.rank}>
<div className={styles.rankHeader}> <div className={styles.rankHeader}>
<h5>竞价排名</h5> <h5>{intl.formatMessage({ id: 'detail.purchase.rankHeader' })}</h5>
<div className={styles.rankHeaderBox}> <div className={styles.rankHeaderBox}>
<img src={level1} alt={`排名1`} /> <img src={level1} alt={`排名1`} />
<h4> <h4>
<div style={{ display: 'inline-block', position: 'relative', left: '-3%', top: '-5%' }}> <div style={{ display: 'inline-block', position: 'relative', left: '-3%', top: '-5%' }}>
{dynamic?.memberName && <TriangleTag text='最低价' wrapStyle={{ backgroundColor: '#EA8000' }} bgcolor='#EA8000' direction='right' />} {dynamic?.memberName && <TriangleTag text={intl.formatMessage({ id: 'detail.purchase.minPrice1' })} wrapStyle={{ backgroundColor: '#EA8000' }} bgcolor='#EA8000' direction='right' />}
</div>
{dynamic?.memberName}
</h4>
<div className={styles.rankHeaderBoxInfo}>
<div className={styles.rankHeaderBoxInfoChild}>当前最低价:<span>{dynamic?.minPrice ? `¥ ${priceFormat(dynamic?.minPrice)}` : '-'}</span></div>
<div className={styles.rankHeaderBoxInfoChild}>报价次数:<span>{dynamic?.count ?? '-'}</span></div>
</div>
</div>
</div> </div>
<Tabs defaultActiveKey="1" onChange={onTabChange}> {dynamic?.memberName}
<TabPane tab="报价排名" key="1"> </h4>
{queryPriceDynamicsData?.map((item) => <RankRow detail={item} key={`queryPriceDynamicsData_${item.id}`} />)} <div className={styles.rankHeaderBoxInfo}>
{queryPriceDynamics.length > 10 && !showMoreQuery && <Button type="link" block onClick={() => { setShowMoreQuery(true) }}>显示更多</Button>} <div className={styles.rankHeaderBoxInfoChild}>{intl.formatMessage({ id: 'detail.purchase.nowMinPrice1' })}<span>{dynamic?.minPrice ? `¥ ${priceFormat(dynamic?.minPrice)}` : '-'}</span></div>
</TabPane> <div className={styles.rankHeaderBoxInfoChild}>{intl.formatMessage({ id: 'detail.purchase.allowPurchaseCount1' })}<span>{dynamic?.count ?? '-'}</span></div>
<TabPane tab="报名会员" key="2"> </div>
{signupMembersData?.map((item) => <RankRow detail={item} key={`signupMembersData_${item.id}`} rowType={2} />)}
{signupMembers.length > 10 && !showMoreSign && <Button type="link" block onClick={() => { setShowMoreSign(true) }}>显示更多</Button>}
</TabPane>
</Tabs>
</div> </div>
) </div>
<Tabs defaultActiveKey="1" onChange={onTabChange}>
<TabPane tab={intl.formatMessage({ id: 'detail.purchase.offerRank' })} key="1">
{queryPriceDynamicsData?.map((item) => <RankRow detail={item} key={`queryPriceDynamicsData_${item.id}`} />)}
{queryPriceDynamics.length > 10 && !showMoreQuery && <Button type="link" block onClick={() => { setShowMoreQuery(true) }}>{intl.formatMessage({ id: 'table.purchase.showMore' })}</Button>}
</TabPane>
<TabPane tab={intl.formatMessage({ id: 'detail.purchase.inviteMemberName' })} key="2">
{signupMembersData?.map((item) => <RankRow detail={item} key={`signupMembersData_${item.id}`} rowType={2} />)}
{signupMembers.length > 10 && !showMoreSign && <Button type="link" block onClick={() => { setShowMoreSign(true) }}>{intl.formatMessage({ id: 'table.purchase.showMore' })}</Button>}
</TabPane>
</Tabs>
</div>
)
} }
export default RankItem; export default RankItem;
...@@ -11,82 +11,84 @@ import IMBtn from '../../../../../components/detail/components/iMBtn'; ...@@ -11,82 +11,84 @@ import IMBtn from '../../../../../components/detail/components/iMBtn';
import TriangleTag from '../triangleTag'; import TriangleTag from '../triangleTag';
import styles from './index.less'; import styles from './index.less';
import { getIntl } from 'umi';
const intl = getIntl();
interface RankRowProps { interface RankRowProps {
detail: any, detail: any,
rowType?: (1 | 2) & number rowType?: (1 | 2) & number
} }
const RankForLeve = { const RankForLeve = {
1: level1, 1: level1,
2: level2, 2: level2,
3: level3, 3: level3,
} }
const RankRow: React.FC<RankRowProps> = (props: any) => { const RankRow: React.FC<RankRowProps> = (props: any) => {
const { detail = {}, rowType } = props; const { detail = {}, rowType } = props;
const _returnBadge = (number) => { const _returnBadge = (number) => {
const _number = Number(number); const _number = Number(number);
switch (_number) { switch (_number) {
case 1: case 1:
case 2: case 2:
case 3: case 3:
return <img src={RankForLeve[_number]} alt={`第${_number}名`} />; return <img src={RankForLeve[_number]} alt={`第${_number}名`} />;
default: default:
return <div className={styles.rankRowLeftTopRank}>{_number}</div> return <div className={styles.rankRowLeftTopRank}>{_number}</div>
}
} }
const _returnRow = () => { }
if (rowType === 1) { const _returnRow = () => {
return ( if (rowType === 1) {
<div className={`${styles.rankRow} ${styles[`rankRow_level_${detail.ranking}`]}`}> return (
<div className={styles.rankRowLeft}> <div className={`${styles.rankRow} ${styles[`rankRow_level_${detail.ranking}`]}`}>
<div className={styles.rankRowLeftTop}> <div className={styles.rankRowLeft}>
{_returnBadge(detail.ranking)} <div className={styles.rankRowLeftTop}>
<Tooltip placement="top" title={detail.memberName}> {_returnBadge(detail.ranking)}
<div className={styles.rankRowLeftTopRankCalc}>{detail.memberName}</div> <Tooltip placement="top" title={detail.memberName}>
</Tooltip> <div className={styles.rankRowLeftTopRankCalc}>{detail.memberName}</div>
{detail.ranking === 1 && <TriangleTag text='最低价' wrapStyle={{ backgroundColor: '#EA8000', marginLeft: '8px' }} bgcolor='#EA8000' direction='left' />} </Tooltip>
</div> {detail.ranking === 1 && <TriangleTag text={intl.formatMessage({ id: 'detail.purchase.minPrice1' })} wrapStyle={{ backgroundColor: '#EA8000', marginLeft: '8px' }} bgcolor='#EA8000' direction='left' />}
<div className={styles.rankRowLeftBottom}> </div>
¥{priceFormat(detail.sumPrice)} <div className={styles.rankRowLeftBottom}>
<div className={styles.rankRowLeftBottomTag}>{detail.count}</div> ¥{priceFormat(detail.sumPrice)}
</div> <div className={styles.rankRowLeftBottomTag}>{detail.count}</div>
</div> </div>
<div className={styles.rankRowRight}> </div>
{detail.contacts} <div className={styles.rankRowRight}>
<IMBtn func={() => toChatRoom(detail.memberId)} /> {detail.contacts}
</div> <IMBtn func={() => toChatRoom(detail.memberId)} />
</div> </div>
) </div>
} else { )
return ( } else {
<div className={`${styles.rankRow}`}> return (
<div className={styles.rankRowLeft}> <div className={`${styles.rankRow}`}>
<Tooltip placement="top" title={detail.memberName}> <div className={styles.rankRowLeft}>
<div className={styles.rankRowLeftEllipsisTitle}>{detail.memberName}</div> <Tooltip placement="top" title={detail.memberName}>
</Tooltip> <div className={styles.rankRowLeftEllipsisTitle}>{detail.memberName}</div>
<div className={styles.rankRowLeftBottomPhone}>{detail.tel.replace(/^(.{3})(.*)(.{4})$/, '$1 $2 $3')}</div> </Tooltip>
</div> <div className={styles.rankRowLeftBottomPhone}>{detail.tel.replace(/^(.{3})(.*)(.{4})$/, '$1 $2 $3')}</div>
<div> </div>
<div className={styles.rankRowRight}> <div>
{detail.contacts} <div className={styles.rankRowRight}>
<IMBtn func={() => toChatRoom(detail.memberId)} /> {detail.contacts}
</div> <IMBtn func={() => toChatRoom(detail.memberId)} />
</div> </div>
</div> </div>
) </div>
} )
} }
}
return ( return (
_returnRow() _returnRow()
) )
} }
RankRow.defaultProps = { RankRow.defaultProps = {
rowType: 1 rowType: 1
} }
export default RankRow; export default RankRow;
...@@ -8,6 +8,7 @@ import { postPurchaseOnlineBiddingSubmitReportPrice } from '@/services/PurchaseV ...@@ -8,6 +8,7 @@ import { postPurchaseOnlineBiddingSubmitReportPrice } from '@/services/PurchaseV
import BtnItem from '../../../../../../components/detail/components/bidDetailBtnItem'; import BtnItem from '../../../../../../components/detail/components/bidDetailBtnItem';
import styles from './index.less'; import styles from './index.less';
import { getIntl } from 'umi';
const { Text } = Typography; const { Text } = Typography;
...@@ -17,9 +18,11 @@ interface DetailBottomDrawerProps { ...@@ -17,9 +18,11 @@ interface DetailBottomDrawerProps {
detail: any detail: any
} }
const intl = getIntl();
const transforType = { const transforType = {
1: '是', 1: intl.formatMessage({ id: 'detail.purchase.okText' }),
0: '否' 0: intl.formatMessage({ id: 'detail.purchase.cancelText' })
} }
const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
...@@ -40,7 +43,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -40,7 +43,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
}, [visible]) }, [visible])
const columns: ColumnType<any>[] = [ const columns: ColumnType<any>[] = [
{ {
title: '物料编号/名称', title: intl.formatMessage({ id: 'detail.purchase.type' }),
dataIndex: 'number', dataIndex: 'number',
key: 'number', key: 'number',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -50,11 +53,11 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -50,11 +53,11 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
</Space> </Space>
) )
}, },
{ title: '规格型号', key: 'model', dataIndex: 'model', }, { title: intl.formatMessage({ id: 'detail.purchase.nameCode' }), key: 'model', dataIndex: 'model', },
{ title: '品类', key: 'category', dataIndex: 'category', }, { title: intl.formatMessage({ id: 'detail.purchase.customerCategory' }), key: 'category', dataIndex: 'category', },
{ title: '品牌', key: 'brand', dataIndex: 'brand', }, { title: intl.formatMessage({ id: 'detail.purchase.brand' }), key: 'brand', dataIndex: 'brand', },
{ {
title: '采购数量/单位', title: intl.formatMessage({ id: 'detail.purchase.purchaseCount1' }),
dataIndex: 'unit', dataIndex: 'unit',
key: 'unit', key: 'unit',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -65,7 +68,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -65,7 +68,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
) )
}, },
{ {
title: '含税/税率', title: intl.formatMessage({ id: 'detail.purchase.isTax1' }),
dataIndex: 'isTax', dataIndex: 'isTax',
key: 'isTax', key: 'isTax',
render: (text: any, record: any) => (activeItem ? render: (text: any, record: any) => (activeItem ?
...@@ -76,7 +79,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -76,7 +79,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
: <Input value={record.taxRate} onChange={(e) => { _changeTax(record, e.target.value) }} addonAfter="%" />) : <Input value={record.taxRate} onChange={(e) => { _changeTax(record, e.target.value) }} addonAfter="%" />)
}, },
{ {
title: '单价(含税)', title: intl.formatMessage({ id: 'detail.purchase.taxUnitPrice' }),
dataIndex: 'unitPrice', dataIndex: 'unitPrice',
key: 'unitPrice', key: 'unitPrice',
render: (text: any, record: any, index: number) => (activeItem ? render: (text: any, record: any, index: number) => (activeItem ?
...@@ -85,13 +88,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -85,13 +88,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
<Form.Item <Form.Item
name={`unitPrice_${index}`} name={`unitPrice_${index}`}
style={{ margin: 0 }} style={{ margin: 0 }}
rules={[{ required: true, message: '请输入金额' }]} rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message56' }) }]}
> >
<Input value={record.unitPrice} onChange={(e) => { _changeUnitPrice(record, e.target.value) }} addonBefore="¥" /> <Input value={record.unitPrice} onChange={(e) => { _changeUnitPrice(record, e.target.value) }} addonBefore="¥" />
</Form.Item>) </Form.Item>)
}, },
{ {
title: '金额(含税)', title: intl.formatMessage({ id: 'detail.purchase.taxPrice' }),
dataIndex: 'price', dataIndex: 'price',
key: 'price', key: 'price',
render: (text: any, record: any) => <Text type='secondary'>{text && `¥${priceFormat(text)}`}</Text> render: (text: any, record: any) => <Text type='secondary'>{text && `¥${priceFormat(text)}`}</Text>
...@@ -149,7 +152,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -149,7 +152,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
form.validateFields().then(() => { form.validateFields().then(() => {
const _price = dataSource2.reduce((total: any, cur: any) => total + Number(cur.price), 0); const _price = dataSource2.reduce((total: any, cur: any) => total + Number(cur.price), 0);
if (detail?.minLowPrice && Number(detail.minLowPrice) - _price < detail.minPrice) { if (detail?.minLowPrice && Number(detail.minLowPrice) - _price < detail.minPrice) {
message.error('当前报价金额不满足最小价差要求,请修改后再报价!'); message.error(intl.formatMessage({ id: 'detail.purchase.tips15' }));
return; return;
} }
let _dataSource2 = dataSource2.map((item) => { let _dataSource2 = dataSource2.map((item) => {
...@@ -174,7 +177,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -174,7 +177,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
return ( return (
<Drawer <Drawer
title="竞价详情" title={intl.formatMessage({ id: 'detail.purchase.modalTitle14' })}
placement={'bottom'} placement={'bottom'}
closable={true} closable={true}
onClose={onClose} onClose={onClose}
...@@ -182,7 +185,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -182,7 +185,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
key={'bottom'} key={'bottom'}
height={450} height={450}
className={styles.drawer} className={styles.drawer}
closeIcon={<div>取消报价</div>} closeIcon={<div>{intl.formatMessage({ id: 'detail.purchase.cancelOffer' })}</div>}
> >
<div style={{ width: '100%', overflowX: 'auto' }}> <div style={{ width: '100%', overflowX: 'auto' }}>
<Row gutter={[8, 8]} style={{ marginBottom: '10px' }} wrap={false}> <Row gutter={[8, 8]} style={{ marginBottom: '10px' }} wrap={false}>
......
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Button, Divider,message } from 'antd'; import { Button, Divider, message } from 'antd';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import { priceFormat } from '@/utils/numberFomat'; import { priceFormat } from '@/utils/numberFomat';
...@@ -8,79 +8,81 @@ import useCountDown from '@/hooks/useCountDown'; ...@@ -8,79 +8,81 @@ import useCountDown from '@/hooks/useCountDown';
import DetailBottomDrawer from './detailBottomDrawer' import DetailBottomDrawer from './detailBottomDrawer'
import styles from './index.less' import styles from './index.less'
import { getIntl } from 'umi';
interface StatuBoxProps { interface StatuBoxProps {
detail: any, detail: any,
hasBidBtn?: boolean, hasBidBtn?: boolean,
} }
const intl = getIntl();
const transforType = { const transforType = {
1: '是', 1: intl.formatMessage({ id: 'detail.purchase.okText' }),
0: '否' 0: intl.formatMessage({ id: 'detail.purchase.cancelText' })
} }
const StatuBox: React.FC<StatuBoxProps> = (props: any) => { const StatuBox: React.FC<StatuBoxProps> = (props: any) => {
const { hasBidBtn, detail } = props; const { hasBidBtn, detail } = props;
const [hour, minute, second, stillRun] = useCountDown(detail?.biddingEndTime / 1000); const [hour, minute, second, stillRun] = useCountDown(detail?.biddingEndTime / 1000);
const [visible, setVisible] = useState<boolean>(false); const [visible, setVisible] = useState<boolean>(false);
const _handleBid = () => { const _handleBid = () => {
if(detail.allowPurchaseCount > detail.offerCount){ if (detail.allowPurchaseCount > detail.offerCount) {
setVisible(true) setVisible(true)
}else{ } else {
message.error('当前报价次数已超过允许报价次数!'); message.error(intl.formatMessage({ id: 'detail.purchase.tips16' }));
}
} }
}
return ( return (
<> <>
<div className='ant-card ant-card-bordered'> <div className='ant-card ant-card-bordered'>
<div className='ant-card-body'> <div className='ant-card-body'>
<div className={styles.statusBox}> <div className={styles.statusBox}>
<div className={styles.statusBoxStatus}>当前状态:<span>{stillRun ? `竞价中` : '竞价结束'}</span></div> <div className={styles.statusBoxStatus}>{intl.formatMessage({ id: 'detail.purchase.statusBoxStatus' })}<span>{stillRun ? intl.formatMessage({ id: 'detail.purchase.stillRunStart' }) : intl.formatMessage({ id: 'detail.purchase.stillRunend' })}</span></div>
<p className={styles.statusBoxTips}>距离竞价结束还剩</p> <p className={styles.statusBoxTips}>{intl.formatMessage({ id: 'detail.purchase.distanceStillRunend' })}</p>
<div className={styles.statusBoxTime}> <div className={styles.statusBoxTime}>
<div className={styles.statusBoxTimeChild}> <div className={styles.statusBoxTimeChild}>
<div className={styles.statusBoxTimeChild_top}>{hour}</div> <div className={styles.statusBoxTimeChild_top}>{hour}</div>
<p className={styles.statusBoxTimeChild_bottom}>小时</p> <p className={styles.statusBoxTimeChild_bottom}>{intl.formatMessage({ id: 'detail.purchase.hour' })}</p>
</div> </div>
<span>:</span> <span>:</span>
<div className={styles.statusBoxTimeChild}> <div className={styles.statusBoxTimeChild}>
<div className={styles.statusBoxTimeChild_top}>{minute}</div> <div className={styles.statusBoxTimeChild_top}>{minute}</div>
<p className={styles.statusBoxTimeChild_bottom}>分钟</p> <p className={styles.statusBoxTimeChild_bottom}>{intl.formatMessage({ id: 'detail.purchase.minute' })}</p>
</div> </div>
<span>:</span> <span>:</span>
<div className={styles.statusBoxTimeChild}> <div className={styles.statusBoxTimeChild}>
<div className={styles.statusBoxTimeChild_top}>{second}</div> <div className={styles.statusBoxTimeChild_top}>{second}</div>
<p className={styles.statusBoxTimeChild_bottom}></p> <p className={styles.statusBoxTimeChild_bottom}>{intl.formatMessage({ id: 'detail.purchase.second' })}</p>
</div> </div>
</div>
<Divider dashed style={{ color: '#EBECF0', margin: '6px 0' }} />
<h4>竞价规则</h4>
<div className={styles.statusBoxText}><div>报价规则:</div>项目总价(含税)</div>
<div className={styles.statusBoxText}><div>起拍价:</div>{detail.isStartingPrice ? `¥ ${priceFormat(detail?.startingPrice)}`: '无' }</div>
{!hasBidBtn && <div className={styles.statusBoxText}><div>目标价:</div>{detail.isTargetPrice ? `¥ ${priceFormat(detail?.targetPrice)}`: '无' }</div>}
<div className={styles.statusBoxText}><div>最小价差:</div>{detail.isMinPrice ? `¥ ${priceFormat(detail?.minPrice)}`: '无' }</div>
<div className={styles.statusBoxText}><div>允许报价次数:</div>{detail?.allowPurchaseCount}</div>
<div className={styles.statusBoxText}><div>报价排名:</div>{hasBidBtn ? (detail.isOpenPurchase ? '按项目总价排名' : '无' ): '按项目总价排名'}</div>
{hasBidBtn ? (
<Button disabled={!stillRun} type="primary" icon={<PlusOutlined />} block onClick={_handleBid} size={'large'} style={{ margin: '15px 0' }}>我要报价</Button>
) : (
<>
<div className={styles.statusBoxText}><div>公开最低报价:</div>{transforType[detail?.isOpenPurchase]}</div>
<div className={styles.statusBoxText}><div>公开报价排名:</div>{transforType[detail?.isOpenRanking]}</div>
</>
)}
</div>
</div>
</div> </div>
<DetailBottomDrawer <Divider dashed style={{ color: '#EBECF0', margin: '6px 0' }} />
visible={visible} <h4>{intl.formatMessage({ id: 'detail.purchase.bidRulesLayout' })}</h4>
onClose={() => { setVisible(false) }} <div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.offerRule' })}</div>{intl.formatMessage({ id: 'detail.purchase.offerRule1' })}</div>
detail={detail} <div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.startingPrice' })}</div>{detail.isStartingPrice ? `¥ ${priceFormat(detail?.startingPrice)}` : intl.formatMessage({ id: 'detail.purchase.null' })}</div>
/> {!hasBidBtn && <div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.targetPrice' })}</div>{detail.isTargetPrice ? `¥ ${priceFormat(detail?.targetPrice)}` : intl.formatMessage({ id: 'detail.purchase.null' })}</div>}
</> <div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.minPrice' })}</div>{detail.isMinPrice ? `¥ ${priceFormat(detail?.minPrice)}` : intl.formatMessage({ id: 'detail.purchase.null' })}</div>
) <div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.allowPurchaseCount' })}</div>{detail?.allowPurchaseCount}</div>
<div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.offerRank' })}</div>{hasBidBtn ? (detail.isOpenPurchase ? intl.formatMessage({ id: 'detail.purchase.offerRule4' }) : intl.formatMessage({ id: 'detail.purchase.null' })) : intl.formatMessage({ id: 'detail.purchase.offerRule5' })}</div>
{hasBidBtn ? (
<Button disabled={!stillRun} type="primary" icon={<PlusOutlined />} block onClick={_handleBid} size={'large'} style={{ margin: '15px 0' }}>{intl.formatMessage({ id: 'detail.purchase.offerRule3' })}</Button>
) : (
<>
<div className={styles.statusBoxText}><div>公开最低报价:</div>{transforType[detail?.isOpenPurchase]}</div>
<div className={styles.statusBoxText}><div>{intl.formatMessage({ id: 'detail.purchase.isOpenRanking' })}</div>{transforType[detail?.isOpenRanking]}</div>
</>
)}
</div>
</div>
</div>
<DetailBottomDrawer
visible={visible}
onClose={() => { setVisible(false) }}
detail={detail}
/>
</>
)
} }
export default StatuBox export default StatuBox
\ No newline at end of file
...@@ -3,41 +3,41 @@ import React from 'react'; ...@@ -3,41 +3,41 @@ import React from 'react';
import styles from './index.less'; import styles from './index.less';
interface TriangleTagProps { interface TriangleTagProps {
text: string, text: string,
wrapStyle: React.CSSProperties, wrapStyle: React.CSSProperties,
bgcolor?: string, bgcolor?: string,
direction?: string, direction?: string,
} }
const TriangleTag: React.FC<TriangleTagProps> = (props: any) => { const TriangleTag: React.FC<TriangleTagProps> = (props: any) => {
const { text, bgcolor, direction, wrapStyle } = props; const { text, bgcolor, direction, wrapStyle } = props;
const _returndirectionStyle = () => { const _returndirectionStyle = () => {
if(direction === 'left'){ if (direction === 'left') {
return { return {
borderColor: `transparent ${bgcolor} transparent transparent`, borderColor: `transparent ${bgcolor} transparent transparent`,
left: '-8px', left: '-8px',
top : '26%' top: '26%'
} }
}else if(direction === 'right'){ } else if (direction === 'right') {
return { return {
borderColor: `transparent ${bgcolor} transparent transparent`, borderColor: `transparent ${bgcolor} transparent transparent`,
transform: 'rotate(180deg)', transform: 'rotate(180deg)',
right: '-8px', right: '-8px',
top : '26%' top: '26%'
} }
}
} }
return ( }
<div className={styles.triangleTag} style={wrapStyle}> return (
<div className={styles.directionTriangle} style={_returndirectionStyle()}></div> <div className={styles.triangleTag} style={wrapStyle}>
{text} <div className={styles.directionTriangle} style={_returndirectionStyle()}></div>
</div> {text}
) </div>
)
} }
TriangleTag.defaultProps = { TriangleTag.defaultProps = {
bgcolor: '#EA8000', bgcolor: '#EA8000',
direction: 'left' direction: 'left'
} }
export default TriangleTag; export default TriangleTag;
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { history } from 'umi'; import { getIntl, history } from 'umi';
import { Row, Col } from 'antd'; import { Row, Col } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons'; import { ArrowLeftOutlined } from '@ant-design/icons';
import { isEmpty } from 'lodash' import { isEmpty } from 'lodash'
...@@ -19,6 +19,8 @@ import StatusBox from './components/statusBox'; ...@@ -19,6 +19,8 @@ import StatusBox from './components/statusBox';
import styles from './index.less'; import styles from './index.less';
const intl = getIntl();
const Management = () => { const Management = () => {
const { const {
query: { query: {
...@@ -52,7 +54,7 @@ const Management = () => { ...@@ -52,7 +54,7 @@ const Management = () => {
setAwardProcess(_data.awardProcesss); setAwardProcess(_data.awardProcesss);
setLowestList({ setLowestList({
type: 'min', type: 'min',
title: '最低价', title: intl.formatMessage({ id: 'detail.purchase.minPrice1' }),
list: _data.awardProcesss ? _data.awardProcesss.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : [] list: _data.awardProcesss ? _data.awardProcesss.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : []
}) })
} }
...@@ -114,7 +116,7 @@ const Management = () => { ...@@ -114,7 +116,7 @@ const Management = () => {
setAwardProcess(data); setAwardProcess(data);
setLowestList({ setLowestList({
type: 'min', type: 'min',
title: '最低价', title: intl.formatMessage({ id: 'detail.purchase.minPrice1' }),
list: data ? data.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : [] list: data ? data.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : []
}) })
}) })
......
...@@ -28,7 +28,7 @@ const ReadyConfirm = () => { ...@@ -28,7 +28,7 @@ const ReadyConfirm = () => {
const [confirmBidResultVisible, setConfirmBidResultVisible] = useState<boolean>(false); const [confirmBidResultVisible, setConfirmBidResultVisible] = useState<boolean>(false);
const [confirmRecord, setConfirmRecord] = useState<any>(); const [confirmRecord, setConfirmRecord] = useState<any>();
const columns: ColumnType<any>[] = [{ const columns: ColumnType<any>[] = [{
title: '序号', title: intl.formatMessage({ id: 'table.purchase.id' }),
align: 'center', align: 'center',
dataIndex: 'id', dataIndex: 'id',
key: 'id', key: 'id',
...@@ -44,7 +44,7 @@ const ReadyConfirm = () => { ...@@ -44,7 +44,7 @@ const ReadyConfirm = () => {
</Space> </Space>
) )
}, { }, {
title: '授标会员', title: intl.formatMessage({ id: 'table.purchase..biddingMemberName' }),
key: 'memberName', key: 'memberName',
dataIndex: 'memberName', dataIndex: 'memberName',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -80,7 +80,7 @@ const ReadyConfirm = () => { ...@@ -80,7 +80,7 @@ const ReadyConfirm = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleConfirm(record) }} type='link'>确认</Button> render: (text: any, record: any) => <Button onClick={() => { handleConfirm(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.confirm' })}</Button>
}]; }];
const handleConfirm = (record: any) => { const handleConfirm = (record: any) => {
...@@ -105,7 +105,7 @@ const ReadyConfirm = () => { ...@@ -105,7 +105,7 @@ const ReadyConfirm = () => {
/> />
<ConfirmBidResultModal <ConfirmBidResultModal
record={confirmRecord} record={confirmRecord}
title="确认竞价结果" title={intl.formatMessage({ id: 'detail.purchase.modalTitle11' })}
visible={confirmBidResultVisible} visible={confirmBidResultVisible}
fetch={postPurchaseBiddingStayConfirmBidding} fetch={postPurchaseBiddingStayConfirmBidding}
onCancel={() => setConfirmBidResultVisible(false)} onCancel={() => setConfirmBidResultVisible(false)}
......
...@@ -68,7 +68,7 @@ const ReadyExamineOne = () => { ...@@ -68,7 +68,7 @@ const ReadyExamineOne = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>审核</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.audit' })}</Button>
}]; }];
/** 批量审核 */ /** 批量审核 */
...@@ -114,7 +114,7 @@ const ReadyExamineOne = () => { ...@@ -114,7 +114,7 @@ const ReadyExamineOne = () => {
onClick={() => fetchSubmitBatch()} onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0} disabled={rowkeys.length === 0}
> >
批量审核通过 {intl.formatMessage({ id: 'table.purchase.submitBatch' })}
</Button> </Button>
</Space> </Space>
</Col> </Col>
...@@ -123,7 +123,7 @@ const ReadyExamineOne = () => { ...@@ -123,7 +123,7 @@ const ReadyExamineOne = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'table.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingExamine1} fetch={postPurchaseBiddingExamine1}
......
...@@ -38,7 +38,7 @@ const ReadyExamineResultOne = () => { ...@@ -38,7 +38,7 @@ const ReadyExamineResultOne = () => {
</Space> </Space>
) )
}, { }, {
title: '授标会员', title: intl.formatMessage({ id: 'table.purchase..biddingMemberName' }),
key: 'memberName', key: 'memberName',
dataIndex: 'memberName', dataIndex: 'memberName',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -74,7 +74,7 @@ const ReadyExamineResultOne = () => { ...@@ -74,7 +74,7 @@ const ReadyExamineResultOne = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>审核</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.audit' })}</Button>
}]; }];
/** 批量审核 */ /** 批量审核 */
...@@ -120,7 +120,7 @@ const ReadyExamineResultOne = () => { ...@@ -120,7 +120,7 @@ const ReadyExamineResultOne = () => {
onClick={() => fetchSubmitBatch()} onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0} disabled={rowkeys.length === 0}
> >
批量审核通过 {intl.formatMessage({ id: 'table.purchase.submitBatch' })}
</Button> </Button>
</Space> </Space>
</Col> </Col>
...@@ -129,7 +129,7 @@ const ReadyExamineResultOne = () => { ...@@ -129,7 +129,7 @@ const ReadyExamineResultOne = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'table.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingSubmitBidding1} fetch={postPurchaseBiddingSubmitBidding1}
......
...@@ -38,7 +38,7 @@ const ReadyExamineResultTwo = () => { ...@@ -38,7 +38,7 @@ const ReadyExamineResultTwo = () => {
</Space> </Space>
) )
}, { }, {
title: '授标会员', title: intl.formatMessage({ id: 'table.purchase..biddingMemberName' }),
key: 'memberName', key: 'memberName',
dataIndex: 'memberName', dataIndex: 'memberName',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -74,7 +74,7 @@ const ReadyExamineResultTwo = () => { ...@@ -74,7 +74,7 @@ const ReadyExamineResultTwo = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>审核</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.audit' })}</Button>
}]; }];
/** 批量审核 */ /** 批量审核 */
...@@ -120,7 +120,7 @@ const ReadyExamineResultTwo = () => { ...@@ -120,7 +120,7 @@ const ReadyExamineResultTwo = () => {
onClick={() => fetchSubmitBatch()} onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0} disabled={rowkeys.length === 0}
> >
批量审核通过 {intl.formatMessage({ id: 'table.purchase.submitBatch' })}
</Button> </Button>
</Space> </Space>
</Col> </Col>
...@@ -129,7 +129,7 @@ const ReadyExamineResultTwo = () => { ...@@ -129,7 +129,7 @@ const ReadyExamineResultTwo = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'table.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingSubmitBidding2} fetch={postPurchaseBiddingSubmitBidding2}
......
...@@ -27,7 +27,7 @@ const ReadyExamineSignUp = () => { ...@@ -27,7 +27,7 @@ const ReadyExamineSignUp = () => {
const [id, setId] = useState<any>(); const [id, setId] = useState<any>();
const [visible, setVisible] = useState<boolean>(false); const [visible, setVisible] = useState<boolean>(false);
const columns: ColumnType<any>[] = [{ const columns: ColumnType<any>[] = [{
title: '序号', title: intl.formatMessage({ id: 'table.purchase.id' }),
align: 'center', align: 'center',
dataIndex: 'id', dataIndex: 'id',
key: 'id', key: 'id',
...@@ -43,7 +43,7 @@ const ReadyExamineSignUp = () => { ...@@ -43,7 +43,7 @@ const ReadyExamineSignUp = () => {
</Space> </Space>
) )
}, { }, {
title: '报名会员/时间', title: intl.formatMessage({ id: 'table.purchase.signUpTime' }),
key: 'signUpTime', key: 'signUpTime',
dataIndex: 'signUpTime', dataIndex: 'signUpTime',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -53,7 +53,7 @@ const ReadyExamineSignUp = () => { ...@@ -53,7 +53,7 @@ const ReadyExamineSignUp = () => {
</Space> </Space>
) )
}, { }, {
title: '报名开始/结束时间', title: intl.formatMessage({ id: 'table.purchase.startSignUp' }),
key: 'startSignUp', key: 'startSignUp',
dataIndex: 'startSignUp', dataIndex: 'startSignUp',
render: (text: any, record: any) => <> render: (text: any, record: any) => <>
...@@ -82,7 +82,7 @@ const ReadyExamineSignUp = () => { ...@@ -82,7 +82,7 @@ const ReadyExamineSignUp = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>审核</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.audit' })}</Button>
}]; }];
const handleExamine = (record: any) => { const handleExamine = (record: any) => {
...@@ -107,7 +107,7 @@ const ReadyExamineSignUp = () => { ...@@ -107,7 +107,7 @@ const ReadyExamineSignUp = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'table.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingExaminBiddingSignup} fetch={postPurchaseBiddingExaminBiddingSignup}
......
...@@ -68,7 +68,7 @@ const ReadyExamineTwo = () => { ...@@ -68,7 +68,7 @@ const ReadyExamineTwo = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>审核</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.audit' })}</Button>
}]; }];
/** 批量审核 */ /** 批量审核 */
...@@ -114,7 +114,7 @@ const ReadyExamineTwo = () => { ...@@ -114,7 +114,7 @@ const ReadyExamineTwo = () => {
onClick={() => fetchSubmitBatch()} onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0} disabled={rowkeys.length === 0}
> >
批量审核通过 {intl.formatMessage({ id: 'table.purchase.submitBatch' })}
</Button> </Button>
</Space> </Space>
</Col> </Col>
...@@ -123,7 +123,7 @@ const ReadyExamineTwo = () => { ...@@ -123,7 +123,7 @@ const ReadyExamineTwo = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'detail.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingExamine2} fetch={postPurchaseBiddingExamine2}
......
...@@ -68,7 +68,7 @@ const ReadySubmit = () => { ...@@ -68,7 +68,7 @@ const ReadySubmit = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>提交</Button> render: (text: any, record: any) => <Button onClick={() => { handleExamine(record) }} type='link'>{intl.formatMessage({ id: 'table.purchase.submit' })}</Button>
}]; }];
/** 批量审核 */ /** 批量审核 */
...@@ -114,7 +114,7 @@ const ReadySubmit = () => { ...@@ -114,7 +114,7 @@ const ReadySubmit = () => {
onClick={() => fetchSubmitBatch()} onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0} disabled={rowkeys.length === 0}
> >
批量提交 {intl.formatMessage({ id: 'detail.purchase.submitBatch1' })}
</Button> </Button>
</Space> </Space>
</Col> </Col>
...@@ -123,7 +123,7 @@ const ReadySubmit = () => { ...@@ -123,7 +123,7 @@ const ReadySubmit = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="单据审核" title={intl.formatMessage({ id: 'detail.purchase.modelTitle' })}
modalType="audit" modalType="audit"
visible={visible} visible={visible}
fetch={postPurchaseBiddingSubmit} fetch={postPurchaseBiddingSubmit}
......
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { history } from 'umi'; import { getIntl, history } from 'umi';
import { ColumnType } from 'antd/lib/table/interface'; import { ColumnType } from 'antd/lib/table/interface';
import { Space, Button, Typography, Badge } from 'antd'; import { Space, Button, Typography, Badge } from 'antd';
import { PlayCircleOutlined, PoweroffOutlined } from '@ant-design/icons'; import { PlayCircleOutlined, PoweroffOutlined } from '@ant-design/icons';
...@@ -11,6 +11,7 @@ import { ENTERPRISE_CENTER_URL } from '@/constants' ...@@ -11,6 +11,7 @@ import { ENTERPRISE_CENTER_URL } from '@/constants'
import Table from '../../components/table' import Table from '../../components/table'
import SubmitResultModal from '../components/submitResultModal' import SubmitResultModal from '../components/submitResultModal'
const intl = getIntl();
import { import {
BID_EXTERNALSTATE_COLOR, BID_EXTERNALSTATE_COLOR,
...@@ -39,7 +40,7 @@ const ReadySubmitExamineResult = () => { ...@@ -39,7 +40,7 @@ const ReadySubmitExamineResult = () => {
</Space> </Space>
) )
}, { }, {
title: '授标会员', title: intl.formatMessage({ id: 'table.purchase..biddingMemberName' }),
key: 'memberName', key: 'memberName',
dataIndex: 'memberName', dataIndex: 'memberName',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
...@@ -75,7 +76,7 @@ const ReadySubmitExamineResult = () => { ...@@ -75,7 +76,7 @@ const ReadySubmitExamineResult = () => {
key: 'operate', key: 'operate',
dataIndex: 'operate', dataIndex: 'operate',
align: 'center', align: 'center',
render: (text: any, record: any) => <Button disabled={!(record.button === 1 || record.button === 2)} onClick={() => handleSubmit(record)} type='link'>{record.button === 1 ? '修改' : '提交审核'}</Button> render: (text: any, record: any) => <Button disabled={!(record.button === 1 || record.button === 2)} onClick={() => handleSubmit(record)} type='link'>{record.button === 1 ? intl.formatMessage({ id: 'table.purchase.eidt' }) : intl.formatMessage({ id: 'detail.purchase.submit' })}</Button>
}]; }];
const handleSubmit = (record: any) => { const handleSubmit = (record: any) => {
...@@ -116,7 +117,7 @@ const ReadySubmitExamineResult = () => { ...@@ -116,7 +117,7 @@ const ReadySubmitExamineResult = () => {
fetch={getPurchaseBiddingStaySubmitBiddingList} fetch={getPurchaseBiddingStaySubmitBiddingList}
/> />
<SubmitResultModal <SubmitResultModal
title={'提交竞价结果'} title={intl.formatMessage({ id: 'detail.purchase.modalTitle12' })}
visible={visible} visible={visible}
onOk={_handleBiddingReturn} onOk={_handleBiddingReturn}
onCancel={() => { setVisible(false) }} onCancel={() => { setVisible(false) }}
......
...@@ -26,7 +26,7 @@ const Search = () => { ...@@ -26,7 +26,7 @@ const Search = () => {
const [id, setId] = useState<number>(); const [id, setId] = useState<number>();
const [visible, setVisible] = useState<boolean>(false); const [visible, setVisible] = useState<boolean>(false);
const columns: ColumnType<any>[] = [{ const columns: ColumnType<any>[] = [{
title: '序号', title: intl.formatMessage({ id: 'table.purchase.id' }),
align: 'center', align: 'center',
dataIndex: 'id', dataIndex: 'id',
key: 'id', key: 'id',
...@@ -80,7 +80,7 @@ const Search = () => { ...@@ -80,7 +80,7 @@ const Search = () => {
setVisible(true); setVisible(true);
}} }}
> >
作废 {intl.formatMessage({ id: 'table.purchase.undo' })}
</Button> </Button>
) )
}]; }];
...@@ -103,7 +103,7 @@ const Search = () => { ...@@ -103,7 +103,7 @@ const Search = () => {
/> />
<ModalOperate <ModalOperate
id={id} id={id}
title="作废原因" title={intl.formatMessage({ id: 'table.purchase.undoCause' })}
visible={visible} visible={visible}
modalType='discard' modalType='discard'
maxNumber={50} maxNumber={50}
......
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