Commit 217de18c authored by wuting's avatar wuting

feat: 0418广告管理 / 待新增商城招标 / 待新增商城采购需求单 业务更新

parent dca06f35
......@@ -99,6 +99,26 @@
hideInMenu: true,
hidePageHeader: true,
},
//广告管理 todo:wuting
// {
// path: '/memberCenter/contentAbility/advertisement',
// name: 'advertisement',
// component: '@/pages/content/advertisement',
// },
// {
// path: '/memberCenter/contentAbility/advertisement/add',
// name: 'advertisementAdd',
// component: '@/pages/content/advertisement/advertisementInfo',
// hideInMenu: true,
// hidePageHeader: true,
// },
// {
// path: '/memberCenter/contentAbility/advertisement/detail',
// name: 'advertisementInfo',
// component: '@/pages/content/advertisement/advertisementInfo',
// hideInMenu: true,
// hidePageHeader: true,
// },
]
}
......
......@@ -19,7 +19,8 @@ import TranactionRoute from './tranactionRoute' // 交易能力路由
// import BalancedRoute from './balanceRoute';
import OrderRoute from './orderRoute'; // 订单能力
import asyncRoutes from '../router.config.json';
// import ProcurementRoute from './procurementRoute';
import ProcurementRoute from './procurementRoute'; // todo wuting
// import { callForBidsRoute } from './procurementRoute/callForBids';
// import { purchaseInquiryRoute } from './procurementRoute/purchaseInquiry';
// import contracRoute from './contracRoute';
......@@ -78,7 +79,7 @@ const memberCenterRoute = {
// TranactionRoute,
// ChannelRoute,
// ShopRoute,
// ProcurementRoute,
ProcurementRoute,
// // 合同能力
// contracRoute,
// AuthConfigRoute,
......
......@@ -68,6 +68,36 @@ export const callForBidsRoute = [
hideInMenu: true,
noMargin: true,
},
// 待新增商城招标
{
path: '/memberCenter/procurementAbility/callForBids/readyAddMallBid',
name: '待新增商城招标',
component: '@/pages/procurement/callForBids/readyAddMallBid',
},
// 待新增商城招标-新建
{
path: '/memberCenter/procurementAbility/callForBids/readyAddMallBid/add',
name: '新建商城招标',
component: '@/pages/procurement/callForBids/readyAddMallBid/add',
hideInMenu: true,
noMargin: true,
},
// 待新增商城招标-编辑
{
path: '/memberCenter/procurementAbility/callForBids/readyAddMallBid/edit',
name: '编辑商城招标',
component: '@/pages/procurement/callForBids/readyAddMallBid/add',
hideInMenu: true,
noMargin: true,
},
// 待新增商城招标-详情
{
path: '/memberCenter/procurementAbility/callForBids/readyAddMallBid/detail',
name: '待新增商城招标详情',
component: '@/pages/procurement/callForBids/readyAddMallBid/detail',
hideInMenu: true,
noMargin: true,
},
// 待审核招标
{
path: '/memberCenter/procurementAbility/callForBids/firstCheckedBid',
......
......@@ -69,6 +69,42 @@ export const purchaseInquiryRoute = [
hideInMenu: true,
},
{
// 待新增商城采购需求单
path: '/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry',
name: '待新增商城采购需求单',
component: '@/pages/transaction/purchaseAbility/purchaseInquiry/addMallInquiry'
},
{
// 待新增商城采购需求单预览
path: '/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/preview',
name: '待新增商城采购需求单详情',
component: '@/pages/transaction/purchaseAbility/purchaseInquiry/addMallInquiry/detail',
hideInMenu: true,
noMargin: true,
},
{
// 待新增商城采购需求单详情
path: '/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/detail',
name: '待新增商城采购需求单详情',
component: '@/pages/transaction/purchaseAbility/purchaseInquiry/addMallInquiry/detail',
hideInMenu: true,
noMargin: true,
},
{
// 新增商城采购需求单
path: '/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/add',
name: '新增商城采购需求单',
component: '@/pages/transaction/purchaseAbility/purchaseInquiry/addMallInquiry/add',
hideInMenu: true,
},
{
// 修改商城采购需求单
path: '/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/edit',
name: '修改商城采购需求单',
component: '@/pages/transaction/purchaseAbility/purchaseInquiry/addMallInquiry/add',
hideInMenu: true,
},
{
// 待审核采购需求单(一级)
path: '/memberCenter/procurementAbility/purchaseInquiry/auditInquiryOne',
name: '待审核采购需求单(一级)',
......@@ -134,6 +170,27 @@ export const purchaseInquiryRoute = [
hideInMenu: true,
noMargin: true,
},
//广告管理
// todo 测试 wuting 记得删除
{
path: '/memberCenter/procurementAbility/purchaseInquiry/advertisement',
name: 'advertisement',
component: '@/pages/content/advertisement',
},
{
path: '/memberCenter/procurementAbility/purchaseInquiry/advertisement/add',
name: 'advertisementAdd',
component: '@/pages/content/advertisement/advertisementInfo',
hideInMenu: true,
hidePageHeader: true,
},
{
path: '/memberCenter/procurementAbility/purchaseInquiry/advertisement/detail',
name: 'advertisementInfo',
component: '@/pages/content/advertisement/advertisementInfo',
hideInMenu: true,
hidePageHeader: true,
},
]
},
]
......@@ -37,6 +37,8 @@ import afterService from './en-US/afterService';
import marketing from './en-US/marketing'
import responseCode from './en-US/responseCode'
import constants from './en-US/constants'
import advertisement from './en-US/advertisement'
export default {
'global.siteName': '',
......@@ -79,4 +81,5 @@ export default {
...marketing,
...responseCode,
...constants,
...advertisement
}
export default {
'advertisement.title':"Advertising Management",
'advertisement.img':"Advertisement Image",
'advertisement.add':"Add Advertisement",
'advertisement.edit':"Edit advertisement",
'advertisement.detail':"View advertisement",
'advertisement.placeholder.column':"Please select a column",
'advertisement.sort': 'Advertising Sort',
'advertisement.placeholder.sort':"Please select the advertisement sort",
}
\ No newline at end of file
......@@ -109,6 +109,8 @@ export default {
'table.purchase.moduleWarning1': 'Please create a purchasing portal first! ',
'table.purchase.xjzb': 'New tender',
'table.purchase.bjzb': 'Edit bidding',
'table.purchase.xjsczb': 'New mall bidding',
'table.purchase.bjsczb': 'Edit Mall Tender',
'table.purchase.qingshuruzhaobiao1': 'Please enter tender number',
// detail
......@@ -321,7 +323,7 @@ export default {
'detail.purchase.modalTitle4': 'Choose goods to generate',
'detail.purchase.modalTitle5': 'Associated offer product',
'detail.purchase.modalTitle6': 'Publish to platform',
'detail.purchase.modalTitle7': 'Invite members',
'detail.purchase.modalTitle7': 'Designated Supply Member',
'detail.purchase.modalTitle8': 'Select item to add',
'detail.purchase.modalTitle9': 'Import goods generated',
'detail.purchase.modalTitle10': 'Purchase plan generated in summary',
......@@ -338,7 +340,7 @@ export default {
'detail.purchase.modalTitle21': 'Adjust the next round of quotation time',
'detail.purchase.modalTitle22': 'Enter key',
'detail.purchase.modalTitle23': 'System match',
'detail.purchase.modalTitle24': 'Designated Member',
'detail.purchase.modalTitle24': 'Designated Supply Member',
'detail.purchase.modalTitle25': 'Material Information',
'detail.purchase.modalTitle26': 'Demand plan details',
......@@ -471,9 +473,9 @@ export default {
'detail.purchase.tips3': 'Please select the procurement portal that needs to be released',
'detail.purchase.tips4': 'After setting the attribution city, this product can be filtered according to the city. If it is not set, it will default to all cities',
'detail.purchase.tips5': 'Turn on the switch, after the review is passed, the requirements will be sent to the selected attribution members',
'detail.purchase.tips6': 'Requirements are posted to the procurement portal',
'detail.purchase.tips7': 'Select members who have an attribution relationship with the current member and whose role type is a service provider (supplier), and the demand is only sent to the designated member',
'detail.purchase.tips8':
'detail.purchase.tips6': 'Post the purchase request form to the platform portal, and suppliers who log in to the platform portal can quote you',
'detail.purchase.tips7': 'Only send the purchase request form to the supplier you designate, and only the supplier who receives your request can make a quotation to you, and ask your supplier to apply for your membership first',
'detail.purchase.tips8':
'Whether to collect the selected demand plan to generate a purchase plan? After the purchase plan is generated, if you need to regenerate it, you need to delete the generated purchase plan',
'detail.purchase.tips9': 'Initial starting price, the first quotation must be lower than or equal to the starting price',
'detail.purchase.tips10': 'Expected transaction price',
......
......@@ -37,6 +37,8 @@ import afterService from './ko-KR/afterService';
import marketing from './ko-KR/marketing'
import responseCode from './ko-KR/responseCode'
import constants from './ko-KR/constants'
import advertisement from './ko-KR/advertisement'
export default {
'global.siteName': '',
......@@ -79,4 +81,5 @@ export default {
...marketing,
...responseCode,
...constants,
...advertisement
}
export default {
'advertisement.title': "광고 관리",
'advertisement.img': "광고 이미지",
'advertisement.add': "광고 추가",
'advertisement.edit': "광고 편집",
'advertisement.detail': "광고 보기",
'advertisement.placeholder.column': "열을 선택하십시오",
'advertisement.sort': '광고 정렬',
'advertisement.placeholder.sort': "광고 정렬을 선택하십시오",
}
\ No newline at end of file
......@@ -109,6 +109,8 @@ export default {
'table.purchase.moduleWarning1': '먼저 구매 포털을 만드세요!',
'table.purchase.xjzb': '신설 입찰 공고',
'table.purchase.bjzb': '편집 입찰',
'table.purchase.xjsczb': '신규 쇼핑몰 입찰',
'table.purchase.bjsczb': '몰 입찰 수정',
'table.purchase.qingshuruzhaobiao1': '입찰번호를 입력하십시오',
// detail
......@@ -321,7 +323,7 @@ export default {
'detail.purchase.modalTitle4': '상품 생성 선택',
'detail.purchase.modalTitle5': '관련 견적 상품',
'detail.purchase.modalTitle6': '플랫폼에 게시',
'detail.purchase.modalTitle7': '회원을 초청하다',
'detail.purchase.modalTitle7': '지정 공급 회원',
'detail.purchase.modalTitle8': '품목 추가 선택',
'detail.purchase.modalTitle9': '가져오기 품목 생성',
'detail.purchase.modalTitle10': '요약 생성 소싱 계획',
......@@ -338,7 +340,7 @@ export default {
'detail.purchase.modalTitle21': '다음 번 오퍼 시간을 조정하다.',
'detail.purchase.modalTitle22': '입력 스푼',
'detail.purchase.modalTitle23': '시스템 일치',
'detail.purchase.modalTitle24': '지정 회원',
'detail.purchase.modalTitle24': '지정 공급 회원',
'detail.purchase.modalTitle25': '재료 정보',
'detail.purchase.modalTitle26': '수요 계획 내역',
......@@ -471,9 +473,9 @@ export default {
'detail.purchase.tips3': '게시할 구매 포털을 선택하십시오.',
'detail.purchase.tips4': '귀속지 시를 설치한 후, 이 상품은 지시에 따라 선별할 수 있으며, 설치하지 않을 때는 기본적으로 모든 지시로 한다',
'detail.purchase.tips5': '스위치를 켜고 심사가 통과되면 선택한 귀속 회원에게 요구 사항을 발송합니다',
'detail.purchase.tips6': '요구 사항을 구매 포털에 게시',
'detail.purchase.tips7': '현재 회원과 귀속 관계가 있는 회원을 선택하고 캐릭터 유형이 서비스로 제공되는 회원(공급업체)을 선택하여 지정된 회원에게만 발송',
'detail.purchase.tips8':
'detail.purchase.tips6': '플랫폼 포털에 구매 요청 양식을 게시하면 플랫폼 포털에 로그인한 공급업체가 견적을 받을 수 있습니다',
'detail.purchase.tips7': '구매 수요 목록을 지정한 공급자에게만 보내야 하며, 당신의 수요를 받는 공급자가 당신에게 견적을 내고 공급자에게 먼저 회원 가입을 신청하도록 요청할 수 있습니다',
'detail.purchase.tips8':
'선택한 수요계획을 총괄하여 구매계획을 생성하시겠습니까?소싱 계획 생성 후 재생성하려면 먼저 생성된 소싱 계획을 삭제해야 합니다.',
'detail.purchase.tips9': '처음 경매 시작 가격, 첫 번째 오퍼는 경매 시작 가격보다 낮거나 같아야 한다.',
'detail.purchase.tips10': '기대 거래 가격',
......
......@@ -37,6 +37,8 @@ import afterService from './zh-CN/afterService';
import marketing from './zh-CN/marketing'
import responseCode from './zh-CN/responseCode'
import constants from './zh-CN/constants'
import advertisement from './zh-CN/advertisement'
export default {
'global.siteName': '',
......@@ -79,4 +81,5 @@ export default {
...marketing,
...responseCode,
...constants,
...advertisement
}
export default {
'advertisement.title':"广告管理",
'advertisement.img':"广告图片",
'advertisement.add':"新增广告",
'advertisement.edit':"编辑广告",
'advertisement.detail':"查看广告",
'advertisement.placeholder.column':"请选择栏目",
'advertisement.sort':'广告排序',
'advertisement.placeholder.sort':"请选择广告排序",
}
\ No newline at end of file
......@@ -109,6 +109,8 @@ export default {
'table.purchase.moduleWarning1': '请先创建采购门户!',
'table.purchase.xjzb': '新建招标',
'table.purchase.bjzb': '编辑招标',
'table.purchase.xjsczb': '新建商城招标',
'table.purchase.bjsczb': '编辑商城招标',
'table.purchase.qingshuruzhaobiao1': '请输入招标编号',
// detail
......@@ -320,8 +322,8 @@ export default {
'detail.purchase.modalTitle3': '添加方式',
'detail.purchase.modalTitle4': '选择货品生成',
'detail.purchase.modalTitle5': '关联报价商品',
'detail.purchase.modalTitle6': '发布至平台',
'detail.purchase.modalTitle7': '邀请会员',
'detail.purchase.modalTitle6': '发布至平台门户',
'detail.purchase.modalTitle7': '指定供应会员',
'detail.purchase.modalTitle8': '选择货品添加',
'detail.purchase.modalTitle9': '导入货品生成',
'detail.purchase.modalTitle10': '汇总生成采购计划',
......@@ -338,7 +340,7 @@ export default {
'detail.purchase.modalTitle21': '调整下轮报价时间',
'detail.purchase.modalTitle22': '输入密匙',
'detail.purchase.modalTitle23': '系统匹配',
'detail.purchase.modalTitle24': '指定会员',
'detail.purchase.modalTitle24': '指定供应会员',
'detail.purchase.modalTitle25': '物料信息',
'detail.purchase.modalTitle26': '需求计划明细',
......@@ -471,8 +473,8 @@ export default {
'detail.purchase.tips3': '请选择需要发布的采购门户',
'detail.purchase.tips4': '设置了归属地市后,此商品可根据地市进行筛选,未设置时默认为所有地市',
'detail.purchase.tips5': '打开开关,审核通过后,将发送需求至选择的归属会员',
'detail.purchase.tips6': '需求发布至采购门户',
'detail.purchase.tips7': '选择与当前会员有归属关系的会员且角色类型为服务提供的会员(供应商),需求只发送给指定会员',
'detail.purchase.tips6': '将采购需求单发布至平台门户,登录平台门户的供应商都能向您报价',
'detail.purchase.tips7': '只将采购需求单发送给您指定的供应商,收到您的需求的供应商才能向您报价,要求您的供应商先申请成为您的会员',
'detail.purchase.tips8':
'是否将选择的需求计划汇总生成采购计划?生成采购计划后如需重新生成,需要先删除已生成的采购计划',
'detail.purchase.tips9': '初始起拍价,首次报价要低于或等于起拍价',
......
import React, { useState } from 'react';
// import { PageHeaderWrapper } from "@ant-design/pro-layout";
// import ReutrnEle from '@/components/ReturnEle';
import { usePageStatus } from '@/hooks/usePageStatus';
import { history, Prompt, useIntl } from 'umi';
import { createFormActions, FormButtonGroup, Submit, FormEffectHooks } from '@formily/antd'
import advertisementInfoSchema from './schema/advertisementInfoSchema';
import { Input, Select, Button, Card } from 'antd';
// import CustomUpload from '@/components/NiceForm/components/CustomUpload';
import { useInitialValues } from '../hooks/useInitialValues';
import CustomUpload from '../components/WrapCustomUpload';
// import useCustomValidator from '../hooks/useValidator'
import { ADVERTISE_WEB_COLUMN_TYPE, ADVERTISE_APP_COLUMN_TYPE} from '../utils/utils';
import { getManageMemberAdvertGet, postManageMemberAdvertAdd, postManageMemberAdvertUpdate } from '@/services/ManageV2Api';
import NiceForm from '@/components/NiceForm';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
enum ChannelEnum {
WEB = 1,
APP = 2,
}
const WEB_COLUMN_TYPE = Object.keys(ADVERTISE_WEB_COLUMN_TYPE).map((item) => {
return {
label: ADVERTISE_WEB_COLUMN_TYPE[item],
value: parseInt(item)
}
})
const APP_COLUMN_TYPE = Object.keys(ADVERTISE_APP_COLUMN_TYPE).map((item) => {
return {
label: ADVERTISE_APP_COLUMN_TYPE[item],
value: parseInt(item)
}
})
const actions = createFormActions();
const { onFieldValueChange$ } = FormEffectHooks;
const AdvertisementInfo: React.FC = () => {
// useCustomValidator()
const intl = useIntl();
const { id, preview } = usePageStatus();
const initialValues = useInitialValues({id:id}, getManageMemberAdvertGet);
const [submitLoading, setSubmitLoading ] = useState(false);
const [unsaved, setUnsaved] = useState(true);
const isEdit = id && !preview;
const isAdd = !id && !preview;
const isView = id && preview;
const handleSubmit = (value) => {
console.log(value)
// const { title, columnType, sort, link, imageUrl} = value;
const serviceActions = isAdd
? postManageMemberAdvertAdd
: postManageMemberAdvertUpdate
let tempData = value;
const postData = isAdd ? tempData : {...tempData, id};
setSubmitLoading(true);
setUnsaved(false);
serviceActions(postData).then((data) => {
setSubmitLoading(false);
if(data.code === 1000) {
history.push('/content/advertisement')
}
})
}
const formEffects = () => () => {
let options: {label: string, value: number| string}[] = []
options = WEB_COLUMN_TYPE
console.log('WEB_COLUMN_TYPEWEB_COLUMN_TYPE',WEB_COLUMN_TYPE)
// if(fieldState.value === ChannelEnum.WEB) {
// options = WEB_COLUMN_TYPE
// } else {
// options = APP_COLUMN_TYPE
// }
console.log(options);
actions.setFieldState('columnType', (state) => {
state.props["enum"] = options;
})
// onFieldValueChange$('channel').subscribe(fieldState => {
// })
}
const handleCancel = () => {
history.push('/content/advertisement')
}
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
// backIcon={<ReutrnEle description="返回" />}
title={isAdd ? intl.formatMessage({ id: 'advertisement.add' }) : isEdit ? intl.formatMessage({ id: 'advertisement.edit' }) : intl.formatMessage({ id: 'advertisement.detail' })}
>
<Card>
<NiceForm
schema={advertisementInfoSchema}
actions={actions}
components={{
Select, Submit, CustomUpload
}}
initialValues={initialValues?.data}
onSubmit={handleSubmit}
editable={isAdd || isEdit}
effects={formEffects()}
expressionScope={{
label: (
<div>
{
isAdd || isEdit
? <span style={{color: '#ff4d4f'}}>* </span>
: null
}
{intl.formatMessage({ id: 'advertisement.img' })}
</div>
)
}}
>
{
isAdd || isEdit
? (
<FormButtonGroup offset={3}>
<Submit loading={submitLoading}>{intl.formatMessage({ id: 'common.button.submit' })}</Submit>
<Button onClick={handleCancel}>{intl.formatMessage({ id: 'common.button.cancel' })}</Button>
</FormButtonGroup>
)
: <></>
}
</NiceForm>
<Prompt when={unsaved} message={intl.formatMessage({ id: 'supplierEvaluation.ninhaiyouweibaocunde' })} />
</Card>
</PageHeaderWrapper>
)
}
export default AdvertisementInfo
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Space, Card, Button, Dropdown, Menu, Popconfirm, message } from 'antd';
import { StandardTable } from '@linkseeks/god';
import NiceForm from '@/components/NiceForm';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { getManageMemberAdvertPage, GetManageContentAdvertPageRequest, getManageContentColumnAll, getManageContentInformationPage, postManageMemberAdvertDelete, postManageMemberAdvertUpdateStatus, postManageContentInformationBatch, postManageContentInformationDelete, postManageContentInformationUpdateStatus } from '@/services/ManageV2Api';
import { createFormActions } from '@formily/antd';
import { getIntl, history } from 'umi'
import { schema } from './schema';
// import { COLUMN_CATEGORY } from '@/constants/const/content';
import EyePreview from '@/components/EyePreview';
import moment from 'moment';
import { PlusOutlined } from '@ant-design/icons';
import { ADVERTISE_APP_COLUMN_TYPE, ADVERTISE_WEB_COLUMN_TYPE } from '../utils/utils';
const ALL_TYPE = Object.assign({}, ADVERTISE_WEB_COLUMN_TYPE, ADVERTISE_APP_COLUMN_TYPE);
const formActions = createFormActions();
/** 待上架 */
const PENDING = 1;
/** 已上架 */
const IS_UP = 2
/** 已下架 */
const IS_DOWN = 3
// const STATUS = ["待上架", "已上架", "已下架"]
const STATUS = [getIntl().formatMessage({ id: 'content.common.waitUp' }), getIntl().formatMessage({ id: 'content.common.hadUp' }), getIntl().formatMessage({ id: 'content.common.hadDown' })]
const AllQuery = () => {
const ref = useRef<any>({});
const columns = [
{ title: 'ID', dataIndex: 'id' },
{
title: getIntl().formatMessage({ id: 'common.text.title' }),
dataIndex: 'title',
render: (text: string, record: any) => (
<EyePreview
url={`/content/advertisement/detail?id=${record.id}&preview=1`}
>
{text}
</EyePreview>
)
},
{
title: getIntl().formatMessage({ id: 'content.info.column'}),
dataIndex: 'columnType',
render: (text, record) => {
return (
<div>{ALL_TYPE[text]}</div>
)
},
},
{
title: getIntl().formatMessage({ id: 'content.info.time'}),
dataIndex: 'createTime',
render: (text) => (
moment(text).format('YYYY-MM-DD HH:mm:ss')
)
},
{
title: getIntl().formatMessage({ id: 'common.table.status'}),
dataIndex: 'status',
render: (value, record) => {
return <a>{STATUS[record.status - 1]}</a>
}
},
{
title: getIntl().formatMessage({ id: 'balance.accountsReceivable.invoice.columns.operation'}),
render: (value, record) => {
return (
<Space>
<a onClick={() => handleUp(record.id, record.status === IS_UP ? IS_DOWN : IS_UP)}>
{
record.status === PENDING || record.status === IS_DOWN ? getIntl().formatMessage({ id: 'commodity.products.buttonGroup.5'}) : getIntl().formatMessage({ id: 'commodity.products.buttonGroup.6'})
}
</a>
{
record.status === PENDING || record.status === IS_DOWN
? (
<Popconfirm
title={getIntl().formatMessage({ id: 'activityPage.ifConfirmDelete'})}
onConfirm={() => handleDelete(record.id)}
okText={getIntl().formatMessage({ id: 'balance.components.writeOffDrawer.ok'})}
cancelText={getIntl().formatMessage({ id: 'authConfig.cancel'})}
>
<a>{getIntl().formatMessage({ id: 'common.button.delete'})}</a>
</Popconfirm>
)
: null
}
</Space>
)
}
}
];
const handleUp = async (id: number, status: 2 | 3) => {
// 该方法是上下架 所以 enableStatus 无用,随意传
const { code, data } = await postManageMemberAdvertUpdateStatus({id, shelfStatus: status, enableStatus: 0})
if (code === 1000) {
formActions.submit();
}
}
const handleDelete = async (id: number) => {
message.loading(`${getIntl().formatMessage({ id:'member.management.import.query.delete-deleting'})}。。。`);
const { data, code } = await postManageMemberAdvertDelete({id});
if (code === 1000) {
formActions.submit();
}
}
const ControllerBtns = () => (
<Space>
<Button
type="primary"
onClick={() => { history.push('/content/advertisement/add') }}
icon={<PlusOutlined />}
>
{getIntl().formatMessage({ id: 'common.button.add'})}
</Button>
</Space>
);
const handleSearch = (values: GetManageContentAdvertPageRequest) => {
const format = 'YYYY-MM-DD';
const { startTime, endTime, ...rest } = values;
const withTimes = startTime && endTime
? {
startTime: moment(startTime, format).valueOf(),
endTime: moment(endTime, format).valueOf()
}
: {}
const postData = {
...withTimes,
...rest,
}
ref.current.reload(postData)
}
const fetchData = async (params: GetManageContentAdvertPageRequest) => {
const { data, code } = await getManageMemberAdvertPage(params);
if (code === 1000) {
return data
}
return {
totalCount: 0,
data: []
}
}
return (
<PageHeaderWrapper
title= {getIntl().formatMessage({ id: 'advertisement.title'})}
>
<Card>
<StandardTable
columns={columns as any}
currentRef={ref}
fetchTableData={(params: any) => fetchData(params)}
controlRender={
<NiceForm
components={{ControllerBtns}}
actions={formActions}
onSubmit={handleSearch}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'title', FORM_FILTER_PATH);
}}
schema={schema}
/>
}
/>
</Card>
</PageHeaderWrapper>
)
}
export default AllQuery
import { getIntl } from 'umi';
import { sortedList, } from '../../utils/utils';
const sortListOptions = sortedList(1, 6);
const schema = {
type: 'object',
properties: {
layout: {
type: 'object',
'x-component': 'mega-layout',
'x-component-props': {
labelCol: 3,
wrapperCol: 10,
labelAlign: 'left'
},
properties: {
title: {
type: 'string',
title: getIntl().formatMessage({ id: 'common.text.title' }),
'x-component-props': {
placeholder: getIntl().formatMessage({ id: 'detail.purchase.placeholder4' })
},
"x-rules": [
{
"required": true,
"message": getIntl().formatMessage({ id: 'detail.purchase.placeholder4' })
},
{
limitByte: true, // 自定义校验规则
maxByte: 60,
}
]
},
// channel: {
// title: '投放渠道',
// type: 'string',
// enum: [
// { label: 'Web', value: 1 },
// { label: 'App', value: 2 },
// ],
// "x-rules": [{
// "required": true,
// "message": "请选择投放渠道"
// }],
// },
columnType: {
title: getIntl().formatMessage({ id: 'content.info.column' }),
type: 'string',
enum: [],
// 'x-component': 'Select',
// 'x-component-props': {
// options: []
// },
"x-rules": [{
"required": true,
"message": getIntl().formatMessage({ id: 'advertisement.placeholder.column' })
}],
},
sort: {
title: getIntl().formatMessage({ id: 'advertisement.sort' }),
type: 'string',
enum: sortListOptions,
"x-rules": [{
"required": true,
"message": getIntl().formatMessage({ id: 'advertisement.placeholder.sort' })
}],
},
link: {
title: getIntl().formatMessage({ id: 'editor.setting.form.jumplink' }),
type: 'string',
"x-rules": [
{
limitByte: true, // 自定义校验规则
maxByte: 100,
}
]
},
imageUrl: {
type: "object",
title: "{{label}}",
name: "imageUrl",
"x-component": "CustomUpload",
"x-component-props": {
size: '无',
fileMaxSize: 300,
},
"x-rules": {
"required": true,
"message": getIntl().formatMessage({ id: "activePage.Pleaseuploadpictures" })
},
},
}
}
}
}
export default schema
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { ISchema } from '@formily/antd';
export const schema: ISchema = {
type: 'object',
properties: {
megaLayout: {
type: 'object',
'x-component': 'mega-layout',
properties: {
topLayout: {
type: 'object',
'x-component': 'Mega-Layout',
'x-component-props': {
grid: true,
},
properties: {
ctl: {
type: 'object',
// 'x-component': 'Children',
// 'x-component-props': {
// children: '{{controllerBtns}}',
// },
"x-component": 'ControllerBtns'
},
title: {
type: 'string',
'x-component': 'Search',
'x-component-props': {
placeholder: '标题',
},
},
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
colStyle: {
marginLeft: 20,
},
},
properties: {
status: {
type: 'string',
enum: [
{label: '全部', value: '0'},
{label: '待上架', value: '1'},
{label: '已上架',value: '2'},
{label: '已下架',value: '3'},
],
'x-component-props': {
placeholder: '状态',
allowClear: true,
},
},
"[startTime, endTime]": {
type: 'daterange',
'x-component-props': {
placeholder: ["发布开始时间", "发布结束时间"],
allowClear: true,
},
},
submit: {
'x-component': 'Submit',
'x-mega-props': {
span: 1,
},
'x-component-props': {
children: '查询',
},
},
},
},
},
},
},
};
......@@ -57,16 +57,16 @@ const sortedList = (start, end) => {
// 内容管理 - 广告栏目
const ADVERTISE_WEB_COLUMN_TYPE = {
"1": "会员首页-活动广告1",
"2": "会员首页-活动广告2",
"3": "会员首页-活动广告3",
// "1": "会员首页-活动广告1",
// "2": "会员首页-活动广告2",
// "3": "会员首页-活动广告3",
"4": "企业采购首页--轮播广告",
"5": "企业采购首页--顶部广告栏",
"6": "企业门户首页--轮播广告",
// "6": "企业门户首页--轮播广告",
"7": "采购商机页--右侧广告栏",
"8": "渠道服务首页--轮播广告",
"9": "物流服务首页--轮播广告",
"10": "加工服务首页--轮播广告"
// "8": "渠道服务首页--轮播广告",
// "9": "物流服务首页--轮播广告",
// "10": "加工服务首页--轮播广告"
}
const ADVERTISE_APP_COLUMN_TYPE = {
......
......@@ -172,6 +172,7 @@ const AddNewBid: React.FC<AddNewBidProps> = (props) => {
}))
}
})
params.shopType = 6
let res = await postPurchaseInviteTenderSaveOrUpdateInviteTender(params)
if (res.code === 1000) {
history.goBack()
......
......@@ -21,7 +21,8 @@ export interface ReadyAddBidProps { }
const fetchTableData = async (params) => {
const { data } = await postPurchaseInviteTenderGetAddInviteTenderList({
...params
...params,
shopType:6
}, { ctlType: "none" })
return data
}
......
import React, {useEffect} from 'react'
import { ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd'
import { useModalTable } from '../../model/useModalTable'
// import { columnsSetMember } from '../../constant'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import ModalSearch from '@/components/NiceForm/components/Search'
import Submit from '@/components/NiceForm/components/Submit'
import { usePageStatus } from '@/hooks/usePageStatus'
import { clearModalParams, omit } from '@/utils'
import { formSearch } from '../../schema/modal'
import { inviteMemberColumns } from '../../constant'
import DrawerTable from '@/components/DrawerTable'
import { postMemberManageLowerProviderPage } from '@/services/MemberV2Api'
export interface MemberModalProps {
type?: 'radio' | 'checkbox',
schemaAction: ISchemaFormActions | ISchemaFormAsyncActions,
currentRef?: any,
}
const MemberModal:React.FC<MemberModalProps> = (props) => {
const { type = "checkbox", schemaAction, currentRef, ...restProps } = props
const {
visible,
setVisible,
rowSelection,
rowSelectionCtl,
} = useModalTable({type, customKey: "memberId"})
const {
id,
preview,
pageStatus
} = usePageStatus()
useEffect(() => {
if (currentRef) {
currentRef.current = {
setVisible,
visible,
rowSelectionCtl
}
}
}, [])
// 添加会员
const handleOkAddMember = () => {
setVisible(false)
let processedData = rowSelectionCtl.selectRow.map(item => {
delete item['id']
return { ...item, isSubMember: true, isSend: true }
})
schemaAction.setFieldValue('memberList', [])
setTimeout(() => {
schemaAction.setFieldValue('memberList', processedData)
}, 300)
clearModalParams()
}
const handleCancelAddMember = () => {
setVisible(false)
clearModalParams()
}
const fetchMemberList = async (params) => {
const res = await postMemberManageLowerProviderPage(params, {ctlType: 'none'});
return res.data
}
return (
<DrawerTable
confirm={handleOkAddMember}
cancel={handleCancelAddMember}
visible={visible}
columns={[...inviteMemberColumns].slice(0, 5)}
rowSelection={rowSelection}
fetchTableData={params => fetchMemberList(params)}
formilyProps={
{
ctx: {
schema: formSearch,
components: {
ModalSearch,
Submit,
},
effects: ($, actions) => {
actions.reset()
useStateFilterSearchLinkageEffect(
$,
actions,
'name',
FORM_FILTER_PATH,
);
},
}
}
}
resetDrawer={{
destroyOnClose: true
}}
tableProps={{
rowKey: 'memberId'
}}
/>
)
}
MemberModal.defaultProps = {}
export default MemberModal
import React, { useRef, useContext } from 'react'
import { Form, Input, Select, Cascader } from 'antd';
import { store } from '@/store'
import { inject, observer } from 'mobx-react'
export interface ProductTableCellProps {
title: React.ReactNode;
editable: boolean;
children: React.ReactNode;
dataIndex: string;
record: any;
handleSave: (record: any) => Promise<any>;
forceEdit: boolean,
formItem: string,
formItemProps: any}
const EditableContext = React.createContext<any>({});
export const ProductEditableRow: React.FC<any> = ({...props }) => {
const [form] = Form.useForm();
const ctx = {
form
}
return (
<Form form={form} component={false}>
<EditableContext.Provider value={ctx}>
<tr {...props} />
</EditableContext.Provider>
</Form>
);
}
export const ProductTableCell:React.FC<ProductTableCellProps> = ({
title,
editable,
children,
dataIndex,
record,
handleSave,
forceEdit,
formItem,
formItemProps={},
...restProps
}) => {
const formItemRef = useRef<any>();
const { form } = useContext(EditableContext);
const { BidTenderStore } = store
const {
commonCategoryData,
commonUnitData
} = BidTenderStore
// input的change
const save = async (e, idx) => {
console.log(e, idx)
try {
const values = await form.validateFields();
values[idx] = idx === 'count' ? Number(values.count) : values[idx]
handleSave({ ...record, ...values });
} catch (errInfo) {
console.log('Save failed', errInfo);
}
};
// select的change
const change = async (va, op, idx) => {
console.log(va, op, idx)
try {
const values = await form.validateFields();
values[idx] = op['label']
values['unitId'] = op['value']
handleSave({ ...record, ...values });
} catch (errInfo) {
console.log('Save failed', errInfo);
}
}
// cascader的change
const toggle = (va, op ,idx) => {
console.log(va, op, idx)
}
const chooseFormItem = (type, v) => {
console.log(commonCategoryData, commonUnitData)
switch(type) {
// input输入类型
case 'input': {
return <Input
style={{width: 140}}
type='number'
ref={formItemRef}
onChange={(e) => save(e, dataIndex)}
{...formItemProps}
id={dataIndex + record.id}
className="purchase_amount_input"
/>
}
// select选择类型
case 'select': {
return <Select
style={{width: 140}}
ref={formItemRef}
onChange={(value, option) => change(value, option, dataIndex)}
id={dataIndex + record.id}
className="purchase_amount_input"
options={commonUnitData.map(item => ({ label: item.name, value: item.id }))}
{...formItemProps}
/>
}
// Cascader选择类型
case 'cascader': {
return <Cascader
style={{width: 140}}
ref={formItemRef}
onChange={(value, option) => toggle(value, option, dataIndex)}
id={dataIndex + record.id}
className="purchase_amount_input"
displayRender={(label) => {
return label[label.length - 1];
}}
showSearch={false}
notFoundContent={null}
fieldNames={{ label: 'title', value: 'id', children: 'children' }}
options={commonCategoryData}
{...formItemProps}
/>
}
}
}
let childNode = children;
if (editable) {
childNode =
<Form.Item
style={{ margin: 0 }}
name={dataIndex}
initialValue={record[dataIndex] || ''}
// @todo 根据字段类型再做处理
// rules={[
// {
// required: true,
// message: `${title}必须填写`,
// },
// {
// pattern: /^\d+(\.\d{1,3})?$/,
// message: '采购数量仅限三位小数',
// },
// ]}
>
{chooseFormItem(formItem, record[dataIndex] || '')}
</Form.Item>
}
return <td {...restProps}>{childNode}</td>;
}
ProductTableCell.defaultProps = {}
export default observer(ProductTableCell)
import React, { useContext } from 'react'
import { createFormActions, ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd'
import { Tooltip } from "antd"
import ModalForm from '@/components/ModalForm'
import { BidDetailContext } from '@/pages/procurement/_public/bid/context'
import { useHttpRequest } from '@/hooks/useHttpRequest'
import { publicBidModalSchema } from '../../schema/modal'
import { QuestionCircleOutlined } from '@ant-design/icons'
import BASE_CONFIG from '../../../../../../../../config/base.config.json'
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import { omit } from '@/utils'
import { postContractContractSignSaleSignContractCreate } from '@/services/ContractV2Api'
import { getIntl } from 'umi';
const shopInfo = BASE_CONFIG.web.shopInfo
export interface PublicBidModalProps {
currentRef?: any,
pageAction?: ISchemaFormActions | ISchemaFormAsyncActions,
}
const schemaActions = createFormActions()
const { pageStatus } = usePageStatus()
// 公开招标方式 发布商城弹窗
const PublicBidModal: React.FC<PublicBidModalProps> = (props) => {
const intl = getIntl();
const { currentRef, pageAction, ...restProps } = props
const { data } = useContext(BidDetailContext)
const { run, loading } = useHttpRequest(postContractContractSignSaleSignContractCreate, { ctlType: 'none' })
const handleSubmit = async (value) => {
const { publishShop } = value
const result = shopInfo.filter(item => publishShop.includes(item.id))
if (pageStatus === PageStatus.ADD)
pageAction.setFieldValue('inviteTenderShopList', result.map(item => {
item.shopId = item['id']
return omit(item, ['id'])
}))
else if (pageStatus === PageStatus.EDIT)
pageAction.setFieldValue('inviteTenderShopList', result)
currentRef.current.setVisible(false)
}
const handleConfirm = () => {
schemaActions.submit()
}
const help = (text: string, desc: string) => (<>
{text}&nbsp;
<Tooltip title={desc}>
<QuestionCircleOutlined />
</Tooltip>
</>)
return (
<ModalForm
modalTitle={intl.formatMessage({ id: 'detail.purchase.modalTitle' })}
previewPlaceholder=' '
currentRef={currentRef}
schema={publicBidModalSchema}
actions={schemaActions}
onSubmit={handleSubmit}
confirm={handleConfirm}
modalProps={{
confirmLoading: loading
}}
effects={($, actions) => {
$('onFormInit').subscribe(async () => {
})
}}
expressionScope={{
help
}}
/>
)
}
PublicBidModal.defaultProps = {}
export default PublicBidModal
.card-list {
font-size: 12px;
line-height: 20px;
padding: 8px;
// margin-top: 24px;
}
.card-list_title {
font-size: 12px;
color: #909399;
}
.parentDrawerWrapper {
.ant-input-group-addon {
padding: 0;
border: none;
}
.connectBtn {
width: 80px;
height: 32px;
line-height: 32px;
background: #909399;
color: #fff;
text-align: center;
cursor: pointer;
}
:global {
.ant-space-item {
width: 100% !important;
}
}
}
import { ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd';
import { getProductCustomerGetCustomerCategoryTree, getProductSelectGetSelectBrand, getProductSelectGetSelectCnUnit } from '@/services/ProductV2Api';
// 高级筛选schema中用于输入搜索品牌的Effect
export const searchBrandOptionEffect = (context: any, fieldName: string) => {
context.getFieldState(fieldName, state => {
getProductSelectGetSelectBrand({ name: state.props['x-component-props'].searchValue }).then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data
})
})
})
}
// 高级筛选schema中用于输入搜索商品品类的Effect
export const searchCustomerCategoryOptionEffect = (context: any, fieldName: string) => {
context.getFieldState(fieldName, state => {
getProductCustomerGetCustomerCategoryTree().then(res => {
context.setFieldState(fieldName, state => {
state.props['x-component-props'].dataoption = res.data
})
})
})
}
// select显示单位
export const showAllUnitList = (context: any, fieldName: string) => {
context.getFieldState(fieldName, state => {
getProductSelectGetSelectCnUnit({ name: '' }).then(res => {
context.setFieldState(fieldName, state => {
state.props['enum'] = res.data.map(item => ({ label: item['name'], value: item['id'] }))
})
})
})
}
// 监听附件列表字段变动 处理编辑情况下的id问题
export const useAttachmentChangeForEdit = (ctx: ISchemaFormActions | ISchemaFormAsyncActions) => {
// FormEffectHooks.onFieldValueChange$('orderProductRequests').subscribe(state => {
// })
}
import React, { useState } from 'react'
import { ISchemaFormActions, ISchemaFormAsyncActions } from '@formily/antd';
import { Button } from 'antd';
import { materialInfoColumns } from '../constant';
import ProductTableCell, { ProductEditableRow } from '../components/productTableCell';
import { useModalTable } from './useModalTable';
import { usePageStatus, PageStatus } from '@/hooks/usePageStatus';
import { EyeOutlined, PlusOutlined } from '@ant-design/icons';
import { getIntl } from 'umi';
const { pageStatus } = usePageStatus()
let orderModel = null;
/**
* @param ctx 页面表单schemaAction
* @param goodRef 生成货品抽屉的ref
* @param drawerSchemaAction 抽屉表单action
*/
export const useMaterialTable = (ctx: ISchemaFormActions | ISchemaFormAsyncActions, goodRef: any, drawerSchemaAction: ISchemaFormActions | ISchemaFormAsyncActions) => {
const { visible, setVisible, rowSelection, rowSelectionCtl } = useModalTable({type: 'checkbox'})
const intl = getIntl();
orderModel = ctx.getFieldValue('orderModel')
const handleDelete = (record) => {
const newData = [...ctx.getFieldValue('materielList')]
// 删除formvalue
const colIndex = newData.findIndex(v => v.id === record.id)
newData.splice(colIndex, 1)
// 删除选中的项
rowSelectionCtl.setSelectRow(newData)
rowSelectionCtl.setSelectedRowKeys(newData.map(v => v.id))
ctx.setFieldValue('materielList', newData)
// // 商品行数变动 清空之前的支付信息
// if (pageStatus === PageStatus.ADD) {
// let paymentInfo = ctx.getFieldValue('paymentInformationResponses').map(item => {
// let _item = {...item}
// delete _item.channel
// delete _item.payWay
// delete _item.payRatio
// return _item
// })
// ctx.setFieldValue('paymentInformationResponses', [])
// // ctx.setFieldValue('paymentInformationResponses', paymentInfo)
// }
}
const handleEdit = async (record) => {
console.log(record, '编辑物料')
goodRef.current.setVisible(true)
setTimeout(async () => {
await ctx.setFieldValue('isEdit', true)
await drawerSchemaAction.setFieldValue('code', record['code'])
await drawerSchemaAction.setFieldValue('name', record['name'])
await drawerSchemaAction.setFieldValue('type', record['type'])
await drawerSchemaAction.setFieldValue('categoryId', record['categoryId'])
await drawerSchemaAction.setFieldValue('categoryName', record['categoryName'])
await drawerSchemaAction.setFieldValue('brandName', record['brandName'])
await drawerSchemaAction.setFieldValue('unitId', record['unitId'])
await drawerSchemaAction.setFieldValue('unitName', record['unitName'])
await drawerSchemaAction.setFieldValue('count', record['count'])
await drawerSchemaAction.setFieldValue('has', record['has'])
await drawerSchemaAction.setFieldState('code', state => {
state.props["x-component-props"].disabled = true
state.props["x-component-props"].addonAfter = ''
})
}, 200)
if (pageStatus === PageStatus.EDIT) {
await drawerSchemaAction.setFieldValue('file', record['file'])
}
}
const handlePreive = (record) => {
console.log(record, '查看')
}
const [materialColumns, setMaterialColumns] = useState(() => {
materialInfoColumns[materialInfoColumns.length - 1].render = (text, record) => <>
<Button type='link' onClick={() => handleEdit(record)}>{intl.formatMessage({ id: 'detail.purchase.edit' })}</Button>
<Button type='link' onClick={() => handleDelete(record)}>{intl.formatMessage({ id: 'detail.purchase.detele' })}</Button>
</>
// // 渲染查看
// materialInfoColumns[1].render = (text, record) => <>
// <Button type='link' onClick={() => handlePreive(record)}>{text} <EyeOutlined /></Button>
// </>
return materialInfoColumns
})
const handleShowProduct = () => {
ctx.setFieldValue('isEdit', false)
goodRef.current.setVisible(true)
}
const materialAddButton = <Button onClick={handleShowProduct} block icon={<PlusOutlined/>} type='dashed' style={{marginBottom: 16}}>{intl.formatMessage({ id: 'detail.purchase.added' })}</Button>
const materialComponents = {
body: {
row: ProductEditableRow,
cell: ProductTableCell
}
}
const handleSave = row => {
return new Promise((resolve, reject) => {
const newData = [...ctx.getFieldValue('materielList')];
const index = newData.findIndex(item => row.code === item.code);
const item = newData[index];
newData.splice(index, 1, {
...item,
...row,
});
ctx.setFieldValue('materielList', newData)
resolve({item, newData})
})
};
const materialMergeColumns = materialColumns.map(col => {
if (!col.editable) {
return col;
}
return {
...col,
onCell: record => ({
record,
editable: ctx.getFormState().editable === false ? false : col.editable,
dataIndex: col.dataIndex,
title: col.title,
formItem: col.formItem,
formItemProps: col.formItemProps,
handleSave
}),
};
})
return {
// materialRef,
materialAddButton,
materialColumns: materialMergeColumns,
materialComponents,
visible,
setVisible,
rowSelection,
rowSelectionCtl
}
}
import { useState } from 'react'
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable'
export const useModalTable = (options?) => {
const [visible, setVisible] = useState(false)
const [rowSelection, rowSelectionCtl] = useRowSelectionTable(options)
return {
visible,
setVisible,
rowSelection,
rowSelectionCtl
}
}
.anchorGap {
div {
&:target {
padding-top: 190px;
margin-top: -190px;
}
}
}
import React from 'react';
import OrderDetailWrapper from '@/pages/transaction/components/orderDetailWrapper';
import PreLoading from '@/components/PreLoading';
import { BidDetailContext } from '@/pages/procurement/_public/bid/context';
import { useBidDetail } from '@/pages/procurement/_public/bid/effects/useBidDetail';
import BidDetailHeader from '@/pages/procurement/components/bidDetailHeader';
import BidDetailSection from '@/pages/procurement/components/bidDetailSection';
import { getIntl } from 'umi';
const intl = getIntl();
const CallForBidsSearchDetail: React.FC = () => {
const { formContext } = useBidDetail({ type: 'callForBid' })
const { data } = formContext
// type? 用于区分DescriptionsInfo组件的内容
// componentName? 用于区分不同组件的渲染
const anchorTitleList = [
{ title: intl.formatMessage({ id: 'table.purchase.liuzhuanjindu' }), id: 'transferProcess', componentName: "TransferProcess" },
{ title: intl.formatMessage({ id: 'table.purchase.jibenxinxi' }), id: 'baseicInfo', type: "basicInfo" },
{ title: intl.formatMessage({ id: 'table.purchase.zhaobiaowuliao' }), id: 'bidMaterial', componentName: "BidMaterial" },
{ title: intl.formatMessage({ id: 'table.purchase.zhaobiaoyaoqiu' }), id: 'bidNeed', type: "bidNeed" },
{ title: intl.formatMessage({ id: 'table.purchase.baomingyaoqiu' }), id: 'registerNeed', type: "registerNeed" },
{ title: intl.formatMessage({ id: 'table.purchase.baomingxinxi' }), id: 'registerInfoList', componentName: "RegisterInfoList", type: "registerList" },
{ title: intl.formatMessage({ id: 'table.purchase.zigeyushenyao' }), id: 'checkNeed', type: "checkNeed" },
{ title: intl.formatMessage({ id: 'table.purchase.zigeyushenxin' }), id: 'preCheckInfoList', componentName: "RegisterInfoList", type: "preCheckList" },
{ title: intl.formatMessage({ id: 'table.purchase.pingbiaoyaoqiu' }), id: 'remarkNeed', type: "remarkNeed" },
{ title: intl.formatMessage({ id: 'table.purchase.pingbiaobaogao' }), id: 'remarkBidReport', componentName: "RemarkBidReport" },
{ title: intl.formatMessage({ id: 'table.purchase.qitayaoqiu' }), id: 'otherNeed', type: "otherNeed" },
{ title: intl.formatMessage({ id: 'table.purchase.zhaobiaofangshi' }), id: 'bidWay', componentName: "BidMethod" },
{ title: intl.formatMessage({ id: 'table.purchase.zhaobiaojieguo' }), id: 'bidConfirm', componentName: "BidConfirm" },
{ title: intl.formatMessage({ id: 'table.purchase.liuzhuanjilu' }), id: 'transferRecord', componentName: "BidTransformRecord" },
]
// 勾选资格预审 才有资格预审信息
if (!data?.isQualificationCheck) {
anchorTitleList.forEach((ele, index) => ele['title'] === intl.formatMessage({ id: 'table.purchase.zigeyushenyao' }) && anchorTitleList.splice(index, 1))
anchorTitleList.forEach((ele, index) => ele['title'] === intl.formatMessage({ id: 'table.purchase.zigeyushenxin' }) && anchorTitleList.splice(index, 1))
}
// 招标完成 才显示招标结果
if (!data?.isFinish) {
anchorTitleList.forEach((ele, index) => ele['title'] === intl.formatMessage({ id: 'table.purchase.zhaobiaojieguo' }) && anchorTitleList.splice(index, 1))
}
return (
<div>
<BidDetailContext.Provider value={formContext}>
<BidDetailHeader
formContext={formContext}
anchorList={anchorTitleList}
/>
<OrderDetailWrapper>
<PreLoading loading={!formContext.data} active paragraph={{ rows: 6 }}>
<BidDetailSection formContext={formContext} anchorList={anchorTitleList} type="callForBid" />
</PreLoading>
</OrderDetailWrapper>
</BidDetailContext.Provider>
</div>
);
};
export default CallForBidsSearchDetail;
import React from 'react'
import { getIntl, history } from 'umi'
import { Card, Button, Space, message } from 'antd'
import StandardTable from '@/components/StandardTable';
import { PageHeaderWrapper } from '@ant-design/pro-layout'
import { PlusCircleOutlined } from '@ant-design/icons'
import { tableListSchema } from './schema'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import Submit from '@/components/NiceForm/components/Submit'
import { useSelfTable } from './model'
import { useHttpRequest } from '@/hooks/useHttpRequest'
import DateRangePickerUnix from '@/components/NiceForm/components/DateRangePickerUnix'
import '../../constants/index.less'
import { postPurchaseInviteTenderApplyCheckInviteTender, postPurchaseInviteTenderDeleteInviteTender, postPurchaseInviteTenderGetAddInviteTenderList } from '@/services/PurchaseV2Api'
import AuthButton from '@/components/AuthButton';
const intl = getIntl();
// 待新增招标
export interface ReadyAddBidProps { }
const fetchTableData = async (params) => {
const { data } = await postPurchaseInviteTenderGetAddInviteTenderList({
...params,
shopType:1
}, { ctlType: "none" })
return data
}
const ReadyAddBid: React.FC<ReadyAddBidProps> = (props) => {
// 删除api
const { run: deleteRun } = useHttpRequest(postPurchaseInviteTenderDeleteInviteTender)
// 提交审核api
const { loading: submitLoading, run: submitRun } = useHttpRequest(postPurchaseInviteTenderApplyCheckInviteTender)
const { columns, ref, rowSelection, rowSelectionCtl } = useSelfTable()
// // {intl.formatMessage({ id: 'table.purchase.deleteBatch' })}
// const handleMenuClick = async (e) => {
// switch(e.key) {
// case '1': {
// // {intl.formatMessage({ id: 'table.purchase.deleteBatch' })}
// const canDelete = !rowSelectionCtl.selectRow.some(v => v.inviteTenderInStatus !== BidInsideWorkState.Not_Submitted_Check_Invite_Tender)
// if (canDelete) {
// const { code } = await deleteRun({idList: rowSelectionCtl.selectedRowKeys})
// if (code === 1000) {
// ref.current.reload()
// rowSelectionCtl.setSelectRow([])
// rowSelectionCtl.setSelectedRowKeys([])
// }
// } else {
// message.error('只能删除内部状态为待提交审核且从未提交过审核的招标')
// }
// break;
// }
// }
// }
const handleBitchRemove = async () => {
if (!rowSelectionCtl.selectRow.length) return message.error(intl.formatMessage({ id: 'table.purchase.qingxuanzezhaobiao' }))
// const canDelete = !rowSelectionCtl.selectRow.some(v => v.inviteTenderInStatus !== BidInsideWorkState.Not_Submitted_Check_Invite_Tender)
// if (canDelete) {
const { code } = await deleteRun({ idList: rowSelectionCtl.selectedRowKeys })
if (code === 1000) {
ref.current.reload()
rowSelectionCtl.setSelectRow([])
rowSelectionCtl.setSelectedRowKeys([])
}
// } else {
// message.error('只能删除内部状态为待提交审核且从未提交过审核的招标')
// }
}
// 批量审核
const handleBitchPush = async () => {
// const canDelete = !rowSelectionCtl.selectRow.some(v => v.inviteTenderInStatus !== BidInsideWorkState.Not_Submitted_Check_Invite_Tender)
if (!rowSelectionCtl.selectedRowKeys.length) { return message.error(intl.formatMessage({ id: 'table.purchase.qingxuanzezhaobiao' })) }
// if (canDelete) {
const { code } = await submitRun({ idList: rowSelectionCtl.selectedRowKeys })
if (code === 1000) {
ref.current.reload()
rowSelectionCtl.setSelectRow([])
rowSelectionCtl.setSelectedRowKeys([])
}
// } else {
// message.error('只能提交内部状态为待提交审核招标的招标')
// }
}
return <PageHeaderWrapper>
<Card>
<StandardTable
fetchTableData={params => fetchTableData(params)}
rowSelection={rowSelection}
columns={columns}
currentRef={ref}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: tableListSchema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'inviteTenderCode',
FORM_FILTER_PATH,
);
},
components: {
DateRangePickerUnix,
Submit
}
},
layouts: {
order: 2,
span: 16
}
}}
formilyChilds={{
children: <Space>
<AuthButton btnCode='readyAddBid.add' >
<Button
icon={<PlusCircleOutlined />}
type='primary'
onClick={() => history.push('/memberCenter/procurementAbility/callForBids/readyAddMallBid/add')}
>
{intl.formatMessage({ id: 'table.purchase.added' })}
</Button>
</AuthButton>
<AuthButton btnCode='readyAddBid.batchsubmit' >
<Button onClick={handleBitchPush} loading={submitLoading}>{intl.formatMessage({ id: 'table.purchase.submitBatch' })}</Button>
</AuthButton>
<AuthButton btnCode='readyAddBid.batchdel' >
<Button onClick={handleBitchRemove} loading={submitLoading}>{intl.formatMessage({ id: 'table.purchase.deleteBatch' })}</Button>
</AuthButton>
{/* <DropDeleteDown>
<Menu onClick={(e) => handleMenuClick(e)}>
<Menu.Item key="1" icon={<DeleteOutlined />}>
{intl.formatMessage({ id: 'table.purchase.deleteBatch' })}
</Menu.Item>
</Menu>
</DropDeleteDown> */}
</Space>,
layouts: {
span: 8
}
}}
/>
</Card>
</PageHeaderWrapper>
}
ReadyAddBid.defaultProps = {}
export default ReadyAddBid
import { useRef } from 'react'
import { Button, Popconfirm } from 'antd'
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable'
import { getIntl, history } from 'umi'
import { baseBidListColumns } from '@/pages/procurement/constants'
import { postPurchaseInviteTenderApplyCheckInviteTender, postPurchaseInviteTenderDeleteInviteTender } from '@/services/PurchaseV2Api'
const intl = getIntl();
import AuthButton from '@/components/AuthButton'
// 待新增招标逻辑
export const useSelfTable = () => {
const ref = useRef<any>({})
const [rowSelection, rowSelectionCtl] = useRowSelectionTable({ customKey: 'id' })
const handleSubmit = async (record) => {
// // 从待新增直接传到一级审核, 状态写死
// if(record.inviteTenderInStatus !== BidInsideWorkState.Not_Submitted_Check_Invite_Tender) {
// return message.error('只能提交内部状态为待提交审核招标的招标')
// }
await postPurchaseInviteTenderApplyCheckInviteTender({ idList: [record.id] })
ref.current.reload()
}
const handleDelete = async (record) => {
// if(record.inviteTenderInStatus !== BidInsideWorkState.Not_Submitted_Check_Invite_Tender) {
// return message.error('只能删除内部状态为待提交审核且从未提交过审核的招标')
// }
await postPurchaseInviteTenderDeleteInviteTender({ idList: [record.id] })
ref.current.reload()
}
const handleEdit = (record: any) => {
history.push(`/memberCenter/procurementAbility/callForBids/readyAddMallBid/edit?id=${record.id}`)
}
const secondColumns: any[] = baseBidListColumns.concat([
{
title: intl.formatMessage({ id: 'table.purchase.caozuo' }),
align: 'left',
dataIndex: 'ctl',
key: 'ctl',
width: 200,
render: (text, record) => {
return <>
{record.isSubmitCheck &&
<AuthButton btnCode='readyAddBid.submit' >
<Button type='link' onClick={() => handleSubmit(record)}>{intl.formatMessage({ id: 'table.purchase.submit' })}</Button>
</AuthButton>
}
<AuthButton btnCode='readyAddBid.eidt' >
<Button type='link' onClick={() => handleEdit(record)}>{intl.formatMessage({ id: 'table.purchase.eidt' })}</Button>
</AuthButton>
{record.isAddTenderDelete &&
<AuthButton btnCode='readyAddBid.del' >
<Popconfirm title={intl.formatMessage({ id: 'table.purchase.shifouyaoshanchu' })} onConfirm={() => handleDelete(record)}>
<Button type='link'>{intl.formatMessage({ id: 'table.purchase.delete' })}</Button>
</Popconfirm>
</AuthButton>
}
</>
}
}
])
return {
columns: secondColumns,
ref,
rowSelection,
rowSelectionCtl
}
}
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { getIntl } from 'umi';
const intl = getIntl();
/**
* 除了订单必填字段, 默认
*/
export const tableListSchema: ISchema = {
type: 'object',
properties: {
inviteTenderCode: {
type: 'string',
"x-component": 'SearchFilter',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'table.purchase.qingshuruzhaobiao' }),
align: 'flex-end',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
inline: true,
colStyle: {
marginLeft: 20
},
},
properties: {
projectName: {
type: 'string',
'x-component-props': {
placeholder: intl.formatMessage({ id: 'table.purchase.qingshuruzhaobiao1' }),
}
},
"[startTime,endTime]": {
type: 'array',
"x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: [intl.formatMessage({ id: 'table.purchase.fabukaishishi' }),intl.formatMessage({ id: 'table.purchase.fabujieshushi' })],
},
},
submit: {
'x-component': 'Submit',
'x-component-props': {
children: intl.formatMessage({ id: 'table.purchase.chaxun' }),
},
},
},
},
}
}
......@@ -65,6 +65,7 @@ const AddForm = () => {
...conditionRef.data,
...demandRef.data,
transactionUurls: fileRef.data,
shopType:6
}
let res: {
code: number,
......
import React, { useState, useRef, useEffect } from 'react';
import { getIntl, history } from 'umi';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { Tabs, Card, Button, Badge } from 'antd';
import Basic from './components/basic';
import Material from './components/material';
import Condition from './components/condition';
import Demand from './components/demand';
import File from './components/file';
import ReutrnEle from '@/components/ReturnEle';
import { getAuth } from '@/utils/auth';
import { getPurchasePurchaseInquiryDetails, GetPurchasePurchaseInquiryDetailsResponse, PostPurchasePurchaseInquiryAddRequest, postPurchasePurchaseInquiryAdd, postPurchasePurchaseInquiryUpdate } from '@/services/PurchaseV2Api';
const { TabPane } = Tabs;
const TabFormErrors = (props) => {
return (
<Badge size="small" count={props.dot} offset={[6, -5]}>
{props.children}
</Badge>
)
}
const intl = getIntl();
const AddForm = () => {
const { id, number } = history.location.query;
const { memberId, memberRoleId, name } = getAuth();
/** 基本信息 */
const [basic, setBasic] = useState<any>({});
/** 添加采购物料 */
const [material, setMaterial] = useState<any>({});
/** 交易条件 */
const [condition, setCondition] = useState<any>({});
/** 需求对接 */
const [demand, setDemand] = useState<any>({});
/** 附件 */
const [file, setfile] = useState<any>([]);
const [badge, setbadge] = useState<any>([0, 0, 0, 0]);
const [loading, setLoading] = useState<boolean>(false);
/** 拿表单数据的 */
const currentBasic = useRef<any>({});
const currentMaterial = useRef<any>({});
const currentCondition = useRef<any>({});
const currentDemand = useRef<any>({});
const currentFile = useRef<any>({});
/** 提交&修改 */
const handleSubmit = async () => {
setLoading(true);
const basicRef = await currentBasic.current.get();
const materialRef = await currentMaterial.current.get();
const conditionRef = await currentCondition.current.get();
const demandRef = await currentDemand.current.get();
const fileRef = await currentFile.current.get();
if (basicRef.state && materialRef.state && conditionRef.state && demandRef.state && fileRef.state) {
const params: PostPurchasePurchaseInquiryAddRequest = {
memberId,
memberRoleId,
memberName: name,
details: basicRef.data.details,
areas: basicRef.data.requisitionFormAddress,
priceContrast: basicRef.data.priceContrast,
purchaseType: basicRef.data.purchaseType,
...materialRef.data,
...conditionRef.data,
...demandRef.data,
transactionUurls: fileRef.data,
shopType:1,
}
let res: {
code: number,
message: string,
time: number,
} = null;
if (id) {
res = await postPurchasePurchaseInquiryUpdate({ id, ...params })
} else {
res = await postPurchasePurchaseInquiryAdd({ ...params });
}
if (res.code !== 1000) {
setLoading(false);
return
}
history.goBack()
} else {
setLoading(false);
}
}
/**必填没填写出现角标 */
const getError = (num: number, idx: number) => {
const data = [...badge];
data[idx] = num;
setbadge(data);
if (num !== 0) {
setLoading(false);
}
}
/** 修改获取信息 */
useEffect(() => {
if (id && number) {
const parmas = {
id,
number,
current: '1',
pageSize: '1',
}
getPurchasePurchaseInquiryDetails(parmas).then((res: any) => {
if (res.code === 1000) {
const params: GetPurchasePurchaseInquiryDetailsResponse = res.data;
const basicInfo: GetPurchasePurchaseInquiryDetailsResponse = { ...basic };
const materialInfo: GetPurchasePurchaseInquiryDetailsResponse = { ...material };
const conditionInfo: GetPurchasePurchaseInquiryDetailsResponse = { ...condition };
const demandInfo: GetPurchasePurchaseInquiryDetailsResponse = { ...demand };
basicInfo.details = params.details;
basicInfo.purchaseType = params.purchaseType;
basicInfo.priceContrast = params.priceContrast;
basicInfo.areas = params.areas || [{
provinceCode: '',
province: '',
cityCode: '',
city: ''
}];
basicInfo.createMemberName = params.createMemberName;
basicInfo.memberName = params.memberName;
basicInfo.purchaseInquiryNo = params.purchaseInquiryNo;
basicInfo.createTime = params.createTime;
basicInfo.externalState = params.externalState
basicInfo.interiorState = params.interiorState;
setBasic(basicInfo);
materialInfo.materielMode = params.materielMode;
materialInfo.materiels = params.materiels;
setMaterial(materialInfo);
conditionInfo.deliveryTime = params.deliveryTime;
conditionInfo.offerEndTime = params.offerEndTime;
conditionInfo.address = params.address;
conditionInfo.addressId = params.addressId;
conditionInfo.offer = params.offer;
conditionInfo.paymentType = params.paymentType;
conditionInfo.taxes = params.taxes;
conditionInfo.logistics = params.logistics;
conditionInfo.packRequire = params.packRequire;
conditionInfo.otherRequire = params.otherRequire;
setCondition(conditionInfo);
demandInfo.type = params.type;
demandInfo.shopIds = params.shopIds;
demandInfo.demandMembers = params.demandMembers;
setDemand(demandInfo);
params.transactionUurls && setfile(params.transactionUurls)
}
}).catch(error => {
console.warn(error)
})
}
}, [id, number])
return (
<PageHeaderWrapper
onBack={() => history.goBack()}
backIcon={<ReutrnEle description={intl.formatMessage({ id: 'detail.purchase.back' })} />}
extra={
<Button loading={loading} type="primary" onClick={handleSubmit}> {intl.formatMessage({ id: 'detail.purchase.save' })}</Button>
}
>
<Card>
<Tabs type='card'>
{/* 基本信息 */}
<TabPane key='1' tab={<TabFormErrors dot={badge[0]}>{intl.formatMessage({ id: 'detail.purchase.basicLayout' })}</TabFormErrors>} forceRender>
<Basic
currentRef={currentBasic}
fetchdata={basic}
onBadge={getError}
/>
</TabPane>
{/* 添加采购物料 */}
<TabPane key='2' tab={<TabFormErrors dot={badge[1]}>{intl.formatMessage({ id: 'detail.purchase.addMaterialLayout' })}</TabFormErrors>} forceRender>
<Material
currentRef={currentMaterial}
fetchdata={material}
onBadge={getError}
/>
</TabPane>
{/* 交易条件 */}
<TabPane key='3' tab={<TabFormErrors dot={badge[2]}>{intl.formatMessage({ id: 'detail.purchase.conditionLayout' })}</TabFormErrors>} forceRender>
<Condition
currentRef={currentCondition}
fetchdata={condition}
onBadge={getError}
/>
</TabPane>
{/* 需求对接 */}
<TabPane key='4' tab={<TabFormErrors dot={badge[3]}>{intl.formatMessage({ id: 'detail.purchase.demandLayout' })}</TabFormErrors>} forceRender>
<Demand
currentRef={currentDemand}
fetchdata={demand}
onBadge={getError}
/>
</TabPane>
<TabPane key='5' tab={intl.formatMessage({ id: 'detail.purchase.file' })} forceRender>
<File
fetchdata={file}
currentRef={currentFile}
/>
</TabPane>
</Tabs>
</Card>
</PageHeaderWrapper>
)
}
export default AddForm
import React, { useState, useEffect } from 'react';
import { Form, Row, Col, Input, DatePicker, Select } from 'antd';
import moment from 'moment';
import { getLogisticsSelectListReceiverAddress } from '@/services/LogisticsV2Api';
import { getIntl } from 'umi';
const { TextArea } = Input;
const { Option } = Select;
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
labelAlign: "left"
}
interface Iprops {
currentRef: any,
fetchdata: { [key: string]: any },
onBadge?: Function
}
export type ADDRESS_TYPE = {
address: string,
addressId: number,
}
const intl = getIntl();
const Condition: React.FC<Iprops> = (props: any) => {
const [form] = Form.useForm();
const {
currentRef,
fetchdata,
onBadge
} = props;
const [address, setAddress] = useState<Array<any>>([]);
const [deliveryTime, setDeliveryTime] = useState<any>()
const [selAddress, setSelAddress] = useState<ADDRESS_TYPE>();
/** 获取交付地址 */
const handleGetLogistics = async () => {
const service = getLogisticsSelectListReceiverAddress;
const res = await service();
if (res.code === 1000) {
setAddress(res.data);
}
}
useEffect(() => {
handleGetLogistics();
}, [])
/** 选择地址 */
const handleSelectAddress = (val: any, option: any) => {
const params: ADDRESS_TYPE = {
address: option.children,
addressId: option.value,
}
setSelAddress(params);
}
useEffect(() => {
currentRef.current = {
get: () => new Promise((resolve: any) => {
form.validateFields().then(res => {
resolve({
state: true,
name: 'condition',
data: {
deliveryTime: moment(res.deliveryTime).format('x'),
offerEndTime: moment(res.offerEndTime).format('x'),
logistics: res.logistics,
offer: res.offer,
otherRequire: res.otherRequire,
packRequire: res.packRequire,
paymentType: res.paymentType,
taxes: res.taxes,
...selAddress,
},
})
onBadge(0, 2)
}).catch(error => {
if (error && error.errorFields) {
onBadge(error.errorFields.length, 2)
}
})
})
}
}, [selAddress])
/** 回显数据 */
useEffect(() => {
console.log(fetchdata)
if (fetchdata) {
form.setFieldsValue({
deliveryTime: fetchdata.deliveryTime ? moment(fetchdata.deliveryTime) : undefined,
addressId: fetchdata.addressId,
offerEndTime: fetchdata.offerEndTime ? moment(fetchdata.offerEndTime) : undefined,
offer: fetchdata.offer,
paymentType: fetchdata.paymentType,
taxes: fetchdata.taxes,
logistics: fetchdata.logistics,
packRequire: fetchdata.packRequire,
otherRequire: fetchdata.otherRequire
})
const params: ADDRESS_TYPE = {
address: fetchdata.address,
addressId: fetchdata.addressId,
}
setSelAddress(params);
}
}, [fetchdata])
const deliveryTimeChange = (val) => {
setDeliveryTime(val)
}
return (
<>
<Form
{...layout}
form={form}
>
<Row gutter={[24, 24]}>
<Col span={12}>
<Form.Item
label={intl.formatMessage({ id: 'table.purchase.deliveryTime' })}
name="deliveryTime"
rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message38' }) }]}
>
<DatePicker
showTime={{ format: 'HH:mm' }}
style={{ width: '100%' }}
format={"YYYY-MM-DD HH:mm"}
disabledDate={(current) => current && current < moment().startOf('day')}
onChange={(val) => deliveryTimeChange(val)}
/>
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.address' })}
name='addressId'
rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message38' }) }]}
>
<Select
onSelect={handleSelectAddress}
>
{address.map(v => (
<Option key={v.id} value={v.id}>{v.fullAddress}</Option>
))}
</Select>
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'table.purchase.quotedPriceTime1' })}
name="offerEndTime"
rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message39' }) }]}
>
<DatePicker
showTime={{ format: 'HH:mm' }}
style={{ width: '100%' }}
format={"YYYY-MM-DD HH:mm"}
disabledDate={(current) => current && current < moment().startOf('day')}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.offerAsk' })}
name="offer"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.paymentType' })}
name="paymentType"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.taxesAsk' })}
name="taxes"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.logisticsAsk' })}
name="logistics"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.packRequireAsk' })}
name="packRequire"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.otherRequireAsk' })}
name="otherRequire"
>
<TextArea rows={3} maxLength={50} />
</Form.Item>
</Col>
</Row>
</Form>
</>
)
}
export default Condition
import React, { useState, useEffect } from 'react';
import { Form, Button, Upload, message, Typography } from 'antd';
import styles from './index.less';
import { UploadOutlined, DeleteOutlined, LinkOutlined } from '@ant-design/icons';
import UploadProps from '@/pages/transaction/common/uploadProps';
import { getIntl } from 'umi';
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 9 },
labelAlign: "left"
};
export interface IProps {
fetchdata: any,
currentRef: any
}
const intl = getIntl();
const File: React.FC<IProps> = (props) => {
const { fetchdata, currentRef } = props;
const [form] = Form.useForm();
const [files, setFiles] = useState([]);
const [loading, setloading] = useState(false);
/**判断文件类型和大小 */
const beforeDocUpload = (file: any) => {
const isLt20M = file.size / 1024 / 1024 < 20;
if (!isLt20M) {
message.error(intl.formatMessage({ id: 'detail.purchase.message21' }));
}
return isLt20M;
}
// 上传回调
const handleChange = ({ file }) => {
const arr: any = files;
setloading(true);
if (file.response) {
if (file.response.code === 1000) {
arr.push({
name: file.name,
url: file.response.data
})
setloading(false);
}
}
setFiles([...arr])
}
// 删除附件
const removeFiles = (index: any) => {
const arr = [...files];
arr.splice(index, 1);
setFiles(arr);
}
useEffect(() => {
if (Object.keys(fetchdata).length > 0) {
setFiles(fetchdata)
}
}, [fetchdata])
useEffect(() => {
currentRef.current = {
get: () => new Promise((resolve: any) => {
form.validateFields().then(res => {
resolve({
state: true,
name: 'explain',
data: files,
})
}).catch(error => {
if (error && error.errorFields) {
}
})
})
}
})
return (
<Form
form={form}
{...layout}
className={styles.revise_style}
>
<Form.Item label={intl.formatMessage({ id: 'detail.purchase.file' })} name='upload'>
<div className={styles.upload_data}>
{files.length > 0 && files.map((v, index) => (
<div key={index} className={styles.upload_item}>
<div className={styles.upload_left}>
<Typography.Link
style={{ display: 'block' }}
key={`link_${index + 1}`}
href={`/api/contract/contractTemplate/downloadContract?contractName=${v.name}&contractUrl=${v.url}`}
target="_blank"
>
<LinkOutlined style={{ marginRight: '5px' }} />
{v.name}
</Typography.Link>
</div>
<div className={styles.upload_right} onClick={() => removeFiles(index)}>
<DeleteOutlined />
</div>
</div>
))}
</div>
<Upload
{...UploadProps}
showUploadList={false}
accept='.doc,.docx,.pdf,.ppt,.pptx,.xls,.xlsx'
beforeUpload={beforeDocUpload}
onChange={handleChange}
>
<Button loading={loading} icon={<UploadOutlined />}>{intl.formatMessage({ id: 'detail.purchase.uploadFile' })}</Button>
<div style={{ marginTop: '8px' }}>{intl.formatMessage({ id: 'detail.purchase.placeholder2' })}</div>
</Upload>
</Form.Item>
</Form>
)
}
export default File;
.form {
:global {
.ant-col {
position: relative;
}
}
.formButton {
position: absolute;
right: -100px;
display: flex;
width: 90px;
:global {
.ant-form-item {
width: 32px;
margin-right: 10px;
.ant-btn {
width: 32px;
padding: 0;
margin-right: 10px;
}
}
}
}
}
.editableRow {
:global {
.ant-form-item-explain {
position: absolute;
top: 100%;
font-size: 12px
}
}
}
.revise_style {
:global {
.ant-form-item-label {
width: 174px;
label {
color:#6B778C
}
}
.ant-form-item-control {
width: 500px;
.ant-form-item-control-input-content {
position: relative;
.ant-btn-link {
position: absolute;
right: -120px;
}
.ant-picker {
width: 100%;
}
}
.ant-input-group-addon {
.ant-input-search-button {
background-color: #6B778C;
border-color: #6B778C;
}
}
}
.ant-radio-group-solid {
.ant-radio-button-wrapper-checked {
background: #6B778C;
border-color: #6B778C;
&:hover {
background: #6B778C;
border-color: #6B778C;
}
}
}
}
.upload_item {
padding: 5px 8px;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FAFBFC;
.upload_left {
display: flex;
align-items: center;
color: #303133;
:global {
.anticon-file-word {
color: #4279df;
font-size: 20px;
margin-right: 8px;
}
}
}
.upload_right {
color: #00B37A;
cursor: pointer;
:global {
.anticon-delete {
margin-left: 19px;
color: #C0C4CC;
}
}
}
}
}
import React, { useEffect, useState } from 'react';
import {
Form,
Radio,
Button,
Table,
Input,
InputNumber,
Cascader,
Spin
} from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
import { PlusOutlined } from '@ant-design/icons';
import style from './index.less';
import DrawerWrite from '../modal/drawerWrite';
import UploadImport from '@/components/UploadImport';
import EyePreview from '@/components/EyePreview';
import AnchorModal from '../modal';
import { getIntl } from 'umi';
const intl = getIntl();
const layout: any = {
colon: false,
labelCol: { style: { width: '174px' } },
wrapperCol: { span: 24 },
labelAlign: "left"
}
interface Iprops {
currentRef: any,
fetchdata: { [key: string]: any },
onBadge?: Function
}
const BUTTONTEXT = {
1: intl.formatMessage({ id: 'detail.purchase.modalTitle8' }),
2: intl.formatMessage({ id: 'detail.purchase.modalTitle9' }),
}
const Material: React.FC<Iprops> = (props: any) => {
const [form] = Form.useForm();
const { currentRef, fetchdata, onBadge } = props;
/** 表单表头 */
const [flag, setFlag] = useState<boolean>(false);
const [edit, setEdit] = useState<any>({});
const [dataSource, setDataSource] = useState<any>([]);
const [eidtIndex, setEditIndex] = useState<number | null>();
const [isPreview, setIsPreview] = useState<boolean>(false);
/** 删除列表 */
const handleRemove = (index: number) => {
const data = [...dataSource];
data.splice(index, 1);
setDataSource(data)
}
/** 编辑列表 */
const handleEdit = (data, index, preview?) => {
setEditIndex(index)
setEdit(data);
setFlag(true)
setIsPreview(preview)
}
const columns: ColumnType<Object>[] = [
{
title: intl.formatMessage({ id: 'detail.purchase.materialCode' }),
key: 'number',
dataIndex: 'number'
},
{
title: intl.formatMessage({ id: 'detail.purchase.materialName' }),
key: 'name',
dataIndex: 'name',
render: (text: any, record: any, index: number) => (
<EyePreview type='button' handleClick={() => handleEdit(record, index, true) } >{text}</EyePreview>
)
},
{
title: intl.formatMessage({ id: 'detail.purchase.nameCode' }),
key: 'model',
dataIndex: 'model',
},
{
title: intl.formatMessage({ id: 'detail.purchase.customerCategory' }),
key: 'category',
dataIndex: 'category',
},
{
title: intl.formatMessage({ id: 'detail.purchase.brand' }),
key: 'brand',
dataIndex: 'brand',
},
{
title: intl.formatMessage({ id: 'detail.purchase.unitName' }),
key: 'unit',
dataIndex: 'unit',
},
{
title: intl.formatMessage({ id: 'detail.purchase.purchaseCount' }),
key: 'purchaseCount',
dataIndex: 'purchaseCount',
},
{
title: intl.formatMessage({ id: 'detail.purchase.option' }),
key: 'operate',
dataIndex: 'operate',
render: (_text: any, record: any, index: number) => (
<>
<Button type='link' onClick={() => handleEdit(record, index)}>{intl.formatMessage({ id: 'detail.purchase.edit' })}</Button>
<Button onClick={() => handleRemove(index)} type='link'>{intl.formatMessage({ id: 'detail.purchase.detele' })}</Button>
</>
)
}
]
/** RADIO选择 1: 选择货品添加,2: 导入货品生成 */
const [materielMode, setMaterielMode] = useState<number>(0)
const checkRadio = (e) => {
const { value } = e.target;
setFlag(false);
setMaterielMode(value);
}
/** 打开添加方式 */
const handleAddmode = () => {
setFlag(true)
setEdit({})
setEditIndex(null)
}
/** 关闭 */
const handleClose = () => {
setFlag(false)
setIsPreview(false)
}
/** 添加列表 */
const fetchTableList = (data: any) => {
if (Object.keys(data).length > 0) {
if (eidtIndex || eidtIndex === 0) {
dataSource[eidtIndex] = data;
setDataSource([...dataSource]);
} else {
setDataSource([...dataSource, data]);
}
setFlag(false);
}
}
/** 导入列表 */
const fetchData = (data: any) => {
if (Object.keys(data).length > 0) {
setDataSource([...dataSource, ...data]);
}
}
useEffect(() => {
currentRef.current = {
get: () => new Promise((resolve: any) => {
form.validateFields().then(res => {
resolve({
state: true,
name: 'material',
data: {
materielMode: res.materielMode,
materiels: dataSource,
},
})
onBadge(0, 1)
}).catch(error => {
if (error && error.errorFields) {
onBadge(error.errorFields.length, 1)
}
})
})
}
})
useEffect(() => {
/**编辑回显数据 */
if (Object.keys(fetchdata).length > 0) {
form.setFieldsValue({
materielMode: fetchdata.materielMode
})
setMaterielMode(fetchdata.materielMode)
setDataSource(fetchdata.materiels)
}
}, [fetchdata])
return (
<>
<Form
{...layout}
form={form}
>
<Form.Item
label={intl.formatMessage({ id: 'detail.purchase.modalTitle3' })}
name='materielMode'
rules={[{ required: true, message: intl.formatMessage({ id: 'detail.purchase.message12' }) }]}
>
<Radio.Group onChange={checkRadio}>
<Radio value={1}>{intl.formatMessage({ id: 'detail.purchase.modalTitle8' })}</Radio>
{/* <Radio value={2}>导入货品生成</Radio> */}
</Radio.Group>
</Form.Item>
{materielMode >= 1
&& (
<>
<Button
type='dashed'
block
onClick={handleAddmode}
style={{
marginBottom: '24px',
}}
>
<PlusOutlined />
{BUTTONTEXT[materielMode]}
</Button>
<Table
columns={columns}
dataSource={dataSource}
rowClassName={style.editableRow}
/>
</>
)}
{materielMode === 1
&& (
<AnchorModal
dataSource={dataSource}
preview={isPreview}
edit={edit}
visible={flag}
onClose={handleClose}
onConfirm={fetchTableList}
/>
)}
{materielMode === 2
&& (
<UploadImport
visible={flag}
title='导入'
downLink="https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/采购需求单导入12ce2f3f6f7e4dfa8d8a7bc4cdf66f1d.xlsx"
checkfetch='/api/purchase/purchase/inquiry/import/excel/check'
importfetch='/api/purchase/purchase/inquiry/import/excel'
fetchData={fetchData}
onClose={() => setFlag(false)}
/>
)}
</Form>
</>
)
}
export default Material;
import React, { Fragment, useEffect, useState } from 'react';
import { Tag, Badge, Tooltip, Button, Typography } from 'antd';
import { getIntl, history } from 'umi';
import { GlobalConfig } from '@/global/config'
import { Context } from '../../../components/detail/components/context';
import PeripheralLayout from '../../../components/detail';
import ProgressLayout from '../../../components/detail/components/progressLayout';
import BasicLayout from '../../../components/detail/components/basicLayout';
import ConditionLayout from '../../../components/detail/components/conditionLayout';
import RecordLyout from '../../../components/detail/components/recordLyout';
import moment from 'moment';
import {
OFFTER_EXTERNALSTATE_COLOR,
OFFTER_INTERNALSTATE_COLOR
} from '../../../constants';
import { CheckCircleOutlined, LinkOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import MaterialLayout from '../../../components/detail/components/materialLayout';
import DemandLayout from '../../../components/detail/components/demandLayout';
import ModalOperate from '../../../components/modalOperate';
import { getPurchasePurchaseInquiryDetails, getPurchasePurchaseInquiryProductlistList, postPurchasePurchaseInquiryExamine1, postPurchasePurchaseInquiryExamine2 } from '@/services/PurchaseV2Api';
const ICON_STYLE: any = {
color: '#C0C4CC',
fontSize: '14px',
marginLeft: '5px'
}
const intl = getIntl();
const TABLINK = [
{ id: 'progressLayout', title: intl.formatMessage({ id: 'detail.purchase.progressLayout' }) },
{ id: 'basicLayout', title: intl.formatMessage({ id: 'detail.purchase.basicLayout' })},
{ id: 'materialLayout', title: intl.formatMessage({ id: 'detail.purchase.materialLayout' }) },
{ id: 'conditionLayout', title: intl.formatMessage({ id: 'detail.purchase.conditionLayout' }) },
{ id: 'demandLayout', title: intl.formatMessage({ id: 'detail.purchase.demandLayout' }) },
{ id: 'recordLyout', title: intl.formatMessage({ id: 'detail.purchase.recordLyout' }) },
]
const DemandDetailed = () => {
const format = (text, fmt?: string) => {
return <>{moment(text).format(fmt || "YYYY-MM-DD HH:mm:ss")}</>
// return <>{moment(text).format("YYYY-MM-DD HH:mm:ss")}</>
}
const {
query: {
id,
number
},
pathname,
} = history.location;
const [path] = useState(pathname.split('/')[pathname.split('/').length - 1]);
const [pathPci] = useState(pathname.split('/')[pathname.split('/').length - 2]);
const [visible, setVisible] = useState<boolean>(false);
const [dataSource, setDataSource] = useState<any>({});
const [basicEffect, setBasicEffect] = useState<any>([]);
const [conditionEffect, setConditionEffect] = useState<any>([]);
const [storeList, setStoreList] = useState<Array<any>>([]);
const handleBasicEffect = (data: any) => {
setBasicEffect([
{
col: [
{ label: intl.formatMessage({ id: 'table.purchase.dementNo' }), extra: data.purchaseInquiryNo },
{ label: intl.formatMessage({ id: 'table.purchase.externalStatus' }), extra: <Tag color={OFFTER_EXTERNALSTATE_COLOR[data.externalState] || 'default'}>{data.externalStateName}</Tag> },
{ label: intl.formatMessage({ id: 'detail.purchase.innerStatus' }), extra: <Badge status={OFFTER_INTERNALSTATE_COLOR[data.interiorState] || 'default'} text={data.interiorStateName} /> },
{ label: intl.formatMessage({ id: 'table.purchase.dementCreateTime' }), extra: format(data.createTime,) },
]
},
{
col: [
{ label: intl.formatMessage({ id: 'table.purchase.details' }), extra: data.details },
{
label: (
<Tooltip placement="top" title={intl.formatMessage({ id: 'detail.purchase.tips' })}>
{intl.formatMessage({ id: 'table.purchase.purchaseType' })}:<QuestionCircleOutlined style={ICON_STYLE} />
</Tooltip>
), extra: data.purchaseType === 1 ? intl.formatMessage({ id: 'detail.purchase.purchaseType1' }) : intl.formatMessage({ id: 'detail.purchase.purchaseType2' }),
colon: true
},
{
label: (
<Tooltip placement="top" title={intl.formatMessage({ id: 'detail.purchase.tips1' })}>
{intl.formatMessage({ id: 'detail.purchase.priceMethod' })}:<QuestionCircleOutlined style={ICON_STYLE} />
</Tooltip>
), extra: data.priceContrast === 1 ? intl.formatMessage({ id: 'detail.purchase.priceContrast1' }) : intl.formatMessage({ id: 'detail.purchase.priceContrast2' }),
colon: true
},
{ label: intl.formatMessage({ id: 'detail.purchase.memberName' }), extra: data.createMemberName },
]
},
{
col: [
{
label: intl.formatMessage({ id: 'detail.purchase.areas' }), extra: (
<div>
{data.areas && data.areas.map((it: any, idx: number) => (
<p key={`areas${idx + 1}`}>{`${it.province}/${it.city}`}</p>
))}
</div>
)
},
]
},
])
}
const handleConditionEffect = (data: any) => {
setConditionEffect([
{
col: [
{ label: intl.formatMessage({ id: 'table.purchase.deliveryTime' }), extra: format(data.deliveryTime) },
{ label: intl.formatMessage({ id: 'detail.purchase.address' }), extra: data.address },
{ label: intl.formatMessage({ id: 'detail.purchase.offerEndTime' }), extra: format(data.offerEndTime) },
{
label: intl.formatMessage({ id: 'detail.purchase.file' }),
extra: <>
{data.transactionUurls.map((item: any, index: number) => (
<Typography.Link
style={{ display: 'block', paddingBottom: '8px' }}
key={`link_${index + 1}`}
href={`/api/contract/contractTemplate/downloadContract?contractName=${item.name}&contractUrl=${item.url}`}
target="_blank"
>
<LinkOutlined style={{ marginRight: '5px' }} />
{item.name}
</Typography.Link>
))}
</>
},
]
},
{
col: [
{ label: intl.formatMessage({ id: 'detail.purchase.offerAsk' }), extra: data.offer },
{ label: intl.formatMessage({ id: 'detail.purchase.paymentType' }), extra: data.paymentType },
{ label: intl.formatMessage({ id: 'detail.purchase.taxesAsk' }), extra: data.taxes },
]
},
{
col: [
{ label: intl.formatMessage({ id: 'detail.purchase.logisticsAsk' }), extra: data.logistics },
{ label: intl.formatMessage({ id: 'detail.purchase.packRequireAsk' }), extra: data.packRequire },
{ label: intl.formatMessage({ id: 'detail.purchase.otherRequireAsk' }), extra: data.otherRequire },
]
},
])
}
const fetchDataSource = async () => {
let shopList = GlobalConfig.web.shopInfo.filter(v => v.type == 6).map(
v => v
)
const params = {
id,
number,
current: '1',
pageSize: '1'
}
await getPurchasePurchaseInquiryDetails({ ...params } as any).then(res => {
if (res.code !== 1000) {
history.goBack();
return;
}
const { data } = res;
if (data.shopIds) {
const ids = data.shopIds;
const filterStore = shopList.filter(item => ids.indexOf(item.id) !== -1);
setStoreList([...filterStore]);
}
setDataSource(data);
handleBasicEffect(data);
handleConditionEffect(data);
}).catch(error => {
console.warn(error)
})
}
useEffect(() => {
fetchDataSource();
}, [])
const fetchLink = () => {
let fetchSoure: any = null;
switch (pathPci) {
case 'auditInquiryOne':
fetchSoure = postPurchasePurchaseInquiryExamine1
break;
case 'auditInquiryTwo':
fetchSoure = postPurchasePurchaseInquiryExamine2
break;
}
return fetchSoure
}
return (
<Context.Provider value={dataSource}>
<PeripheralLayout
no={dataSource.purchaseInquiryNo}
tabLink={TABLINK}
effect={
<>
{path === 'detail'
&& (
<Button
onClick={() => setVisible(true)}
type='primary'
>
<CheckCircleOutlined />
{intl.formatMessage({ id: 'detail.purchase.modelTitle' })}
</Button>
)}
</>
}
components={
<Fragment>
<ProgressLayout />
<BasicLayout effect={basicEffect} />
<MaterialLayout
id={id as any}
number={number as any}
fetch={getPurchasePurchaseInquiryProductlistList}
/>
<ConditionLayout effect={conditionEffect} />
<DemandLayout storeList={storeList} />
<RecordLyout />
</Fragment>
}
/>
<ModalOperate
id={id as any}
title={intl.formatMessage({ id: 'detail.purchase.modelTitle' })}
modalType="audit"
visible={visible}
fetch={fetchLink()}
onCancel={() => setVisible(false)}
onOk={() => history.goBack()}
/>
</Context.Provider>
)
}
export default DemandDetailed;
import React, { useRef, useState } from 'react';
import Table from '../../components/table'
import { getIntl, history } from 'umi';
import { ColumnType } from 'antd/lib/table/interface';
import EyePreview from '@/components/EyePreview';
import moment from 'moment'
import { Row, Col, Space, Button, Tag, Badge, Popconfirm, Typography, message, Modal } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import {
INQUIRY_EXTERNALSTATE_COLOR,
INQUIRY_INTERNALSTATE_COLOR,
OFFTER_EXTERNALSTATE_TYPE,
OFFTER_INTERNALSTATE_TYPE,
BUTTONAUTHORITY
} from '../../constants';
import { getPurchasePurchaseInquiryShopAddList, postPurchasePurchaseInquiryDelete, postPurchasePurchaseInquiryDeleteBatch, postPurchasePurchaseInquirySubmit, postPurchasePurchaseInquirySubmitBatch } from '@/services/PurchaseV2Api';
import { getTemplateWebMemberPurchaseWebFindCurrMemberPurchase } from '@/services/TemplateV2Api';
import AuthButton from '@/components/AuthButton';
const { Text } = Typography;
const intl = getIntl();
const AddInquiry = () => {
const ref = useRef<any>({});
const format = (text, fmt?: string) => {
return <>{moment(text).format(fmt || "YYYY-MM-DD HH:mm")}</>
}
const columns: ColumnType<any>[] = [{
title: intl.formatMessage({ id: 'table.purchase.purchaseInquiryNo' }),
key: 'purchaseInquiryNo',
dataIndex: 'purchaseInquiryNo',
render: (text: any, record: any) => (
<Space direction='vertical'>
<EyePreview
url={`/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/preview?id=${record.id}&number=${record.purchaseInquiryNo}`}>{text}</EyePreview>
<Text type="secondary">{record.details}</Text>
</Space>
)
}, {
title: intl.formatMessage({ id: 'table.purchase.deliveryTime' }),
key: 'deliveryTime',
dataIndex: 'deliveryTime',
render: (text: any, record: any) => format(text, 'YYYY-MM-DD')
}, {
title: intl.formatMessage({ id: 'table.purchase.quotedPriceTime' }),
key: 'offerEndTime',
dataIndex: 'offerEndTime',
render: (text: any, record: any) => format(text)
}, {
title: intl.formatMessage({ id: 'table.purchase.dementCreateTime' }),
key: 'createTime',
dataIndex: 'createTime',
render: (text: any, record: any) => format(text)
}, {
title: intl.formatMessage({ id: 'table.purchase.externalStatus' }),
key: 'externalState',
dataIndex: 'externalState',
render: (text: any, record: any) => <Tag color={INQUIRY_EXTERNALSTATE_COLOR[text]}>{record.externalStateName}</Tag>
}, {
title: intl.formatMessage({ id: 'detail.purchase.innerStatus' }),
key: 'interiorState',
dataIndex: 'interiorState',
render: (text: any, record: any) => <Badge status={INQUIRY_INTERNALSTATE_COLOR[text]} text={record.interiorStateName} />
}, {
title: intl.formatMessage({ id: 'detail.purchase.option' }),
key: 'operate',
dataIndex: 'operate',
render: (text: any, record: any) => (
<>
{(record.button === BUTTONAUTHORITY.ONE) &&
<AuthButton btnCode='purchaseInquiry.submit' >
<Popconfirm title={intl.formatMessage({ id: 'table.purchase.popconfirm' })} okText={intl.formatMessage({ id: 'table.purchase.okText' })} cancelText={intl.formatMessage({ id: 'table.purchase.cancelText' })} onConfirm={() => fetchSubmitBatch(record.id)}>
<Button type='link'>
{intl.formatMessage({ id: 'table.purchase.submit' })}
</Button>
</Popconfirm>
</AuthButton>
}
{(record.button === BUTTONAUTHORITY.ONE || record.button === BUTTONAUTHORITY.TWO) &&
<AuthButton btnCode='purchaseInquiry.edit' >
<Button type='link' onClick={() => history.push(`/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/edit?id=${record.id}&number=${record.purchaseInquiryNo}`)}>{intl.formatMessage({ id: 'table.purchase.eidt' })}</Button>
</AuthButton>
}
{(record.button === BUTTONAUTHORITY.ONE) &&
<AuthButton btnCode='purchaseInquiry.del' >
<Popconfirm title={intl.formatMessage({ id: 'table.purchase.popconfirm2' })} okText={intl.formatMessage({ id: 'table.purchase.okText' })} cancelText={intl.formatMessage({ id: 'table.purchase.cancelText' })} onConfirm={() => fetchDeleteBatch(record.id)}>
<Button type='link'>
{intl.formatMessage({ id: 'table.purchase.delete' })}
</Button>
</Popconfirm>
</AuthButton>
}
</>
)
}];
const [rowkeys, setRowKeys] = useState<Array<number>>([]);
/** 批量审核 */
const fetchSubmitBatch = async (id?: number) => {
let res = null;
if (id) {
res = await postPurchasePurchaseInquirySubmit({ id: Number(id) })
} else {
res = await postPurchasePurchaseInquirySubmitBatch({ ids: rowkeys });
}
if (res.code === 1000) {
ref.current.reload();
setRowKeys([])
}
}
/**
* 删除或批量删除
* @type: 1: 单个删除, 2: 批量删除
* */
const fetchDeleteBatch = async (id?: number) => {
let res = null;
if (id) {
res = await postPurchasePurchaseInquiryDelete({ id });
} else {
res = await postPurchasePurchaseInquiryDeleteBatch({ ids: rowkeys });
}
if (res.code === 1000) {
ref.current.reload();
setRowKeys([])
}
}
const addFn = async () => {
await getTemplateWebMemberPurchaseWebFindCurrMemberPurchase().then(res => {
if (res.code !== 1000) {
message.error(intl.formatMessage({ id: `${res.code}` }));
return
}
if (!res.data) {
Modal.warning({
title: intl.formatMessage({ id: 'table.purchase.moduleWarning' }),
content: intl.formatMessage({ id: 'table.purchase.moduleWarning1' }),
okText: intl.formatMessage({ id: 'detail.purchase.confirm' }),
onOk: () => history.push('/memberCenter/procurementAbility/purchasDoor/purchasInfo'),
})
return
}
history.push('/memberCenter/procurementAbility/purchaseInquiry/addMallInquiry/add')
})
}
return (
<Table
selectedRow
reload={ref}
schemaType="INQUIRYWAITORDER_SCHEMA"
columns={columns}
effects="purchaseInquiryNo"
fetch={getPurchasePurchaseInquiryShopAddList}
fetchRowkeys={(e) => setRowKeys(e)}
controllerBtns={
<Row>
<Col span={24}>
<Space direction="horizontal" size={16}>
<AuthButton btnCode='purchaseInquiry.added' >
<Button
onClick={() => addFn()}
type="primary"
icon={<PlusOutlined />}
>
{intl.formatMessage({ id: 'table.purchase.added' })}
</Button>
</AuthButton>
<AuthButton btnCode='purchaseInquiry.batchsubmit' >
<Button
onClick={() => fetchSubmitBatch()}
disabled={rowkeys.length === 0}
>
{intl.formatMessage({ id: 'table.purchase.submitBatch' })}
</Button>
</AuthButton>
<AuthButton btnCode='purchaseInquiry.batchdel' >
<Button
onClick={() => fetchDeleteBatch()}
disabled={rowkeys.length === 0}
>
{intl.formatMessage({ id: 'table.purchase.deleteBatch' })}
</Button>
</AuthButton>
</Space>
</Col>
</Row>
}
/>
)
}
export default AddInquiry
import React, { useState } from 'react';
import {
Modal,
Row,
Col,
Image,
Progress,
Button,
Upload
} from 'antd';
import style from './index.less';
import excelIcon from '@/assets/imgs/excel.png';
import cx from 'classnames'
import { getIntl } from 'umi';
interface Iprops {
flag: boolean,
onClose: () => void,
}
const intl = getIntl();
const Import: React.FC<Iprops> = (props: any) => {
const { flag, onClose } = props;
const [next, setNext] = useState<number>(1);
return (
<Modal
width={400}
title='导入'
visible={flag}
onCancel={onClose}
footer={
next !== 1 ? null :
<Upload>
<Button type='primary'>导入</Button>
</Upload>
}
>
{ next === 1 &&
<Row
style={{
flexDirection: 'column',
}}
>
<Col
style={{
display: 'flex',
justifyContent: 'center',
}}
>
<Image
width={72}
height={72}
preview={false}
src={excelIcon}
/>
</Col>
<Col
span={24}
className={style.colStyle}
>
<span className={style.badgeStyle}>1</span>
<span className={style.textStyle}>点击下载 EXCEL文件模板</span>
<Button style={{ fontSize: '14px' }} type='link'>下载</Button>
</Col>
<Col
span={24}
className={style.colStyle}
>
<span className={style.badgeStyle}>2</span>
<span className={style.textStyle}>按照模板整理货品资料</span>
</Col>
<Col
span={24}
className={style.colStyle}
>
<span className={style.badgeStyle}>3</span>
<span className={style.textStyle}>点击导入按钮,导入整理好的货品资料</span>
</Col>
</Row>
}
{ next === 2 &&
<Row
style={{
alignItems: 'center',
flexDirection: 'column',
}}
>
<Col
style={{
display: 'flex',
justifyContent: 'center',
}}
>
<Progress type="circle" percent={30} width={64} />
</Col>
<Col
span={24}
style={{ marginTop: '44px' }}
>
<span className={cx(style.textStyle, style.fontColor)}>正在进行数据导入检查</span>
</Col>
<Col
span={24}
>
<span className={style.textStyle}>请稍后…</span>
</Col>
<Col
span={24}
className={style.marginTop}
>
<Button type='primary'>下一步</Button>
</Col>
</Row>
}
{ next === 3 &&
<Row
style={{
alignItems: 'center',
flexDirection: 'column',
}}
>
<Col
style={{
display: 'flex',
justifyContent: 'center',
}}
>
<Progress type="circle" percent={30} width={64} />
</Col>
<Col
span={24}
style={{ marginTop: '44px' }}
>
<span className={cx(style.textStyle, style.fontColor)}>正在进行数据导入</span>
</Col>
<Col
span={24}
>
<span className={style.textStyle}>请稍后…</span>
</Col>
<Col
span={24}
className={style.marginTop}
>
<Button type='primary'>继续导入</Button>
<Button>导入完成</Button>
</Col>
</Row>
}
</Modal>
)
}
export default Import
.drawer {
:global {
.ant-drawer-body {
padding: 0;
.ant-row {
height: 100%;
.ant-anchor {
padding-left: 0px;
.ant-anchor-ink {
display: none;
}
.ant-anchor-link {
padding: 12px 12px 12px 12px;
}
.ant-anchor-link-active {
box-sizing: border-box;
border-left: 2px solid #00B37A;
}
}
}
}
.ant-anchor-wrapper {
margin-left: 0;
padding-left: 0;
}
}
.upload_item {
padding: 5px 8px;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FAFBFC;
.upload_left {
display: flex;
align-items: center;
color: #303133;
:global {
.anticon-file-word {
color: #4279df;
font-size: 20px;
margin-right: 8px;
}
}
}
.upload_right {
color: #00B37A;
cursor: pointer;
:global {
.anticon-delete {
margin-left: 19px;
color: #C0C4CC;
}
}
}
}
}
/** 导入样式 */
.badgeStyle {
width: 16px;
height: 16px;
display: inline-block;
border-radius: 50%;
background-color: #6198FF;
text-align: center;
color:#FFFFFF;
font-weight: 500;
margin-right: 5px;
}
.textStyle {
font-size: 14px;
color: #909399;
}
.colStyle {
padding-left: 40px;
}
.fontColor {
color: #303133;
}
.marginTop {
margin-top: 48px;
}
.container {
display: flex;
height: 100%;
overflow: hidden;
.menu {
width: 200px;
height: 100%;
border-right: 1px solid #F4F5F7;
.menuItem {
padding: 18px 16px;
color: #606266;
}
.active {
position: relative;
font-weight: bold;
color: #303133;
&::after {
content: '';
height: 24px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border-left: 3px solid @main-color;
transform: scaleY(1);
opacity: 1;
transition: transform .15s cubic-bezier(.645,.045,.355,1),opacity .15s cubic-bezier(.645,.045,.355,1);
}
}
}
.content {
width: 100%;
padding: 24px 16px;
overflow-y: scroll;
.anchor {
color: #909399;
font-size: 14px;
position: relative;
padding-left: 6px;
&::after {
content: '';
height: 14px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
border-left: 2px solid @main-color;
transform: scaleY(1);
opacity: 1;
transition: transform .15s cubic-bezier(.645,.045,.355,1),opacity .15s cubic-bezier(.645,.045,.355,1);
}
}
.upload_item {
padding: 5px 8px;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FAFBFC;
.upload_left {
display: flex;
align-items: center;
color: #303133;
:global {
.anticon-file-word {
color: #4279df;
font-size: 20px;
margin-right: 8px;
}
}
}
.upload_right {
color: @main-color;
cursor: pointer;
:global {
.anticon-delete {
margin-left: 19px;
color: #C0C4CC;
}
}
}
}
}
}
import React, { useEffect, useRef } from 'react';
import {
Drawer,
Button
} from 'antd';
import StandardTable from '@/components/StandardTable';
import { ColumnType } from 'antd/lib/table/interface';
import { createFormActions } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import {
formSearch,
} from '../../../schema';
import { postMemberManageLowerProviderPage } from '@/services/MemberV2Api';
import { getIntl } from 'umi';
const formActions = createFormActions();
interface Iprops {
rowCtl?: any,
visible: boolean,
onclose?(),
confirm?(e: any),
}
const intl = getIntl();
const SelectMenber: React.FC<Iprops> = (props: any) => {
const ref = useRef({});
const { visible, onclose, confirm, rowCtl } = props;
const [rowSelection, RowCtl] = useRowSelectionTable({ customKey: 'memberId' });
const columns: ColumnType<any>[] = [
{
title: intl.formatMessage({ id: 'detail.purchase.memberId' }),
key: 'memberId',
dataIndex: 'memberId',
},
{
title: intl.formatMessage({ id: 'detail.purchase.memberName' }),
key: 'name',
dataIndex: 'name',
},
{
title: intl.formatMessage({ id: 'detail.purchase.memberType' }),
key: 'memberTypeName',
dataIndex: 'memberTypeName',
},
{
title: intl.formatMessage({ id: 'detail.purchase.role' }),
key: 'roleName',
dataIndex: 'roleName',
},
{
title: intl.formatMessage({ id: 'detail.purchase.leveTag' }),
key: 'levelTag',
dataIndex: 'levelTag',
}
]
const fetchGoodsData = (params: any) => {
return new Promise(resolve => {
postMemberManageLowerProviderPage({ ...params }, { ctlType: 'none' }).then(res => {
const { data } = res
resolve(data)
}).catch(error => {
console.warn(error)
})
})
}
useEffect(() => {
if (rowCtl) {
console.log(rowCtl)
RowCtl.setSelectRow(rowCtl)
RowCtl.setSelectedRowKeys(rowCtl.map(v => v.memberId))
}
}, [visible])
return (
<Drawer
visible={visible}
onClose={onclose}
title={intl.formatMessage({ id: 'detail.purchase.selectMenber' })}
width={900}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={onclose} style={{ marginRight: 8 }}>
{intl.formatMessage({ id: 'detail.purchase.cancel' })}
</Button>
<Button onClick={() => confirm(RowCtl)} type="primary">
{intl.formatMessage({ id: 'detail.purchase.confirm' })}
</Button>
</div>
}
>
<StandardTable
currentRef={ref}
columns={columns}
tableProps={{ rowKey: 'memberId' }}
rowSelection={rowSelection}
fetchTableData={(params) => fetchGoodsData(params)}
formilyProps={
{
ctx: { schema: formSearch }
}
}
/>
</Drawer>
)
}
export default SelectMenber
import React, { useRef } from 'react';
import {
Drawer,
Button
} from 'antd';
import StandardTable from '@/components/StandardTable';
import { ColumnType } from 'antd/lib/table/interface';
import NiceForm from '@/components/NiceForm';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { createFormActions, FormEffectHooks } from '@formily/antd';
import { useRowSelectionTable } from '@/hooks/useRowSelectionTable';
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch';
import { searchSelectGetSelectCategoryOptionEffect } from '@/pages/transaction/effect/index';
import {
SelectProductSchema,
} from '../../../schema';
import { getProductGoodsGetGoodsList } from '@/services/ProductV2Api';
import { getIntl } from 'umi';
const formActions = createFormActions();
interface Iprops {
visible: boolean,
onclose?(),
confirm?(e:any),
}
const intl = getIntl();
const SelectProduct: React.FC<Iprops> = (props: any) => {
const ref = useRef({});
const { visible, onclose, confirm } = props;
const [rowSelection, RowCtl] = useRowSelectionTable({ customKey: 'id', type: 'radio' });
const columns: ColumnType<any>[] = [
{
title: intl.formatMessage({ id: 'detail.purchase.code' }),
key: 'code',
dataIndex: 'code'
},
{
title: intl.formatMessage({ id: 'detail.purchase.productName' }),
key: 'name',
dataIndex: 'name'
},
{
title: intl.formatMessage({ id: 'detail.purchase.nameCode' }),
key: 'type',
dataIndex: 'type'
},
{
title: intl.formatMessage({ id: 'detail.purchase.customerCategory' }),
key: 'customerCategory',
dataIndex: 'customerCategory',
render: (text: any) => <span>{(text && Object.keys(text).length > 0) && text.name}</span>
},
{
title: intl.formatMessage({ id: 'detail.purchase.brand' }),
key: 'brand',
dataIndex: 'brand',
render: (text: any) => <span>{(text && Object.keys(text).length > 0) && text.name}</span>
},
{
title: intl.formatMessage({ id: 'detail.purchase.unitName' }),
key: 'unitName',
dataIndex: 'unitName'
},
]
const fetchGoodsData = (params: any) => {
return new Promise(resolve => {
getProductGoodsGetGoodsList(params).then(res => {
const { data } = res
resolve(data)
}).catch(error => {
console.warn(error)
})
})
}
return (
<Drawer
visible={visible}
onClose={onclose}
title={intl.formatMessage({ id: 'detail.purchase.modalTitle1' })}
width={900}
footer={
<div
style={{
textAlign: 'right',
}}
>
<Button onClick={onclose} style={{ marginRight: 8 }}>
{intl.formatMessage({ id: 'detail.purchase.cancel' })}
</Button>
<Button onClick={() => confirm(RowCtl)} type="primary">
{intl.formatMessage({ id: 'detail.purchase.confirm' })}
</Button>
</div>
}
>
<StandardTable
currentRef={ref}
columns={columns}
tableProps={{ rowkey: 'id' }}
rowSelection={rowSelection}
fetchTableData={(params) => fetchGoodsData(params)}
controlRender={
<NiceForm
actions={formActions}
effects={($, actions) => {
useStateFilterSearchLinkageEffect($, actions, 'name', FORM_FILTER_PATH)
FormEffectHooks.onFieldChange$('category').subscribe(state => {
searchSelectGetSelectCategoryOptionEffect(actions, 'category')
})
}}
schema={SelectProductSchema}
>
</NiceForm>
}
/>
</Drawer>
)
}
export default SelectProduct
import React, { useState } from 'react';
import { Modal, Row, Col, Tooltip, Checkbox } from 'antd';
import { QuestionCircleOutlined } from '@ant-design/icons';
import { getIntl } from 'umi';
const CheckboxGroup = Checkbox.Group;
export interface IProps {
visible: boolean,
storeList: Array<any>,
onCancel?: () => void,
getStroeList?: (e:any) => void,
}
const intl = getIntl();
const Store: React.FC<IProps> = (props: any) => {
const {
visible,
storeList,
onCancel,
getStroeList,
} = props;
const [storeId, setStoreId] = useState<any>([])
/** 确定 */
const handleSubmit = () => {
getStroeList(storeId)
}
/** 选择商城 */
const onchange = (value) => {
setStoreId(value)
}
return (
<Modal
title={intl.formatMessage({ id: 'detail.purchase.selectMall' })}
visible={visible}
onCancel={onCancel}
onOk={handleSubmit}
>
<Checkbox.Group
style={{ width: '100%' }}
onChange={onchange}
>
<Row gutter={[8, 24]}>
<Col span={24}>
<Tooltip placement="topRight" title={intl.formatMessage({ id: 'detail.purchase.tips2' })}>{intl.formatMessage({ id: 'detail.purchase.tips3' })}<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip>
</Col>
{storeList.map((item: any) => (
<Col span={8} key={item.id}>
<Checkbox value={item.id}>{item.name}</Checkbox>
</Col>
))}
</Row>
</Checkbox.Group>
</Modal>
)
}
export default Store
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