Commit 9463e013 authored by alwayOnlie's avatar alwayOnlie

Merge branch 'dev-srm' of http://10.0.0.22:3000/lingxi/lingxi-business-paltform into dev-srm

parents 6ec88aa0 e7c35fdb
.steps {
padding-top: 2px;
overflow: auto;
}
\ No newline at end of file
.steps {
padding-top: 2px;
overflow: auto;
:global {
.ant-steps-item-title {
margin-right: 16px;
// &:last-child {
// margin-right: 0px;
// }
}
}
}
......@@ -8,6 +8,7 @@
import React, { useState, useEffect } from 'react';
import {
Steps,
Tooltip,
} from 'antd';
import MellowCard, { MellowCardProps } from '@/components/MellowCard';
import ButtonSwitch from '@/components/ButtonSwitch';
......@@ -102,6 +103,17 @@ const AuditProcess: React.FC<AuditProcessProp> = ({
),
].filter(Boolean);
const titleRender = (stepTitle: string, stepLength: number) => {
if(stepLength <= 6) {
return <span>{stepTitle}</span>
}
return (
<Tooltip placement="top" title={stepTitle}>
<span style={{maxWidth: '100px', marginRight: '8px', textAlign: 'center'}}>{`${stepTitle}`}</span>
</Tooltip>
)
}
return (
<MellowCard
title="流转进度"
......@@ -120,7 +132,7 @@ const AuditProcess: React.FC<AuditProcessProp> = ({
{outerVerifySteps && outerVerifySteps.map(item => (
<Steps.Step
key={customKey ? item[customKey] : item.step}
title={customTitleKey ? item[customTitleKey] : item.stepName}
title={titleRender(customTitleKey ? item[customTitleKey] : item.stepName, outerVerifySteps.length)}
description={item.roleName}
status={item.status}
/>
......@@ -134,7 +146,7 @@ const AuditProcess: React.FC<AuditProcessProp> = ({
{innerVerifySteps && innerVerifySteps.map(item => (
<Steps.Step
key={customKey ? item[customKey] : item.step}
title={customTitleKey ? item[customTitleKey] : item.stepName}
title={titleRender(customTitleKey ? item[customTitleKey] : item.stepName, innerVerifySteps.length)}
description={item.roleName}
status={item.status}
/>
......
......@@ -192,6 +192,10 @@ export const complaintAddSchema: ISchema = {
{
limitByte: true, // 自定义校验规则
maxByte: 60
},
{
required: true,
message: "请填写事件描述"
}
]
},
......
......@@ -13,7 +13,7 @@ import { Link } from 'umi';
import { useAsyncSelect } from '@/formSchema/effects/useAsyncSelect';
const defaultColumns = setColumnsByLinks({
detail: '/memberCenter/memberAbility/memberEvaluate/tobeInformed',
detail: '/memberCenter/memberAbility/memberEvaluate/tobeInformed/detail',
});
interface Iprops {};
......
......@@ -3,6 +3,7 @@ import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { message } from 'antd'
import { processLogResponses } from '@/pages/procurement/constants'
interface OrderDetailHookProps {
/** 招标-招标详情,投标-投标详情,招标-投标详情,投标-招标详情,custom自定义 配合requestApi字段 */
......@@ -132,11 +133,15 @@ export const useBidDetail = (options: OrderDetailHookProps) => {
}
// 流程状态(内/外)
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
// 招投标 投标里面的投标流程单独调接口
const processRes = type === 'tender' ?
await PublicApi.getPurchaseSubmitTenderGetSubmitTenderProcess({ submitTenderId: id })
:
await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
const { interiorLogs, externalLogs } = processLogResponses(processRes.data)
setInteriorWorkflowFlowRecordLogResponses(interiorLogs)
setExternalWorkflowFlowRecordLogResponses(externalLogs)
}
}
}, [id])
......
......@@ -3,6 +3,7 @@ import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { message } from 'antd'
import { processLogResponses } from '@/pages/procurement/constants'
/**
* 待定标(审核定标、确认定标)详情context共用逻辑
......@@ -63,8 +64,9 @@ export const useConfirmDetail = (options: {}) => {
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
const { interiorLogs, externalLogs } = processLogResponses(processRes.data)
setInteriorWorkflowFlowRecordLogResponses(interiorLogs)
setExternalWorkflowFlowRecordLogResponses(externalLogs)
}
}
}, [id])
......
......@@ -753,7 +753,7 @@ const bidPattern: ISchema = {
required: true,
enum: [
{
label: '{{help("公开招标", "招标发布至企业商城招标频道")}}',
label: '{{help("公开招标", "招标发布至采购门户")}}',
value: 1
},
// {
......
......@@ -21,8 +21,8 @@ export const publicBidModalSchema: ISchema = {
properties: {
publishShop: {
type: 'checkbox',
title: '{{help("发布商城", "已发布的商城为已勾选的商城,不可选择,只可以选择未勾选的商城。")}}',
enum: shopInfo.filter(item => item.type === 1).map(item => ({ label: item.name, value: item.id }))
title: '{{help("已发布的采购门户", "已发布的采购门户为已勾选的采购门户,不可选择,只可以选择未勾选的采购门户。")}}',
enum: shopInfo.filter(item => item.type === 6).map(item => ({ label: item.name, value: item.id }))
}
}
}
......
......@@ -3,6 +3,7 @@ import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { message } from 'antd'
import { processLogResponses } from '@/pages/procurement/constants'
interface DetailHookProps {
......@@ -55,8 +56,9 @@ export const useRemarkDetail = (options: DetailHookProps) => {
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
const { interiorLogs, externalLogs } = processLogResponses(processRes.data)
setInteriorWorkflowFlowRecordLogResponses(interiorLogs)
setExternalWorkflowFlowRecordLogResponses(externalLogs)
}
}
}, [id])
......
......@@ -3,6 +3,7 @@ import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { message } from 'antd'
import { processLogResponses } from '@/pages/procurement/constants'
interface DetailHookProps {
......@@ -57,8 +58,9 @@ export const useNoticeDetail = (options: DetailHookProps) => {
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
const { interiorLogs, externalLogs } = processLogResponses(processRes.data)
setInteriorWorkflowFlowRecordLogResponses(interiorLogs)
setExternalWorkflowFlowRecordLogResponses(externalLogs)
}
}
}, [id])
......
......@@ -3,6 +3,7 @@ import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { message } from 'antd'
import { processLogResponses } from '@/pages/procurement/constants'
interface DetailHookProps {
......@@ -59,8 +60,9 @@ export const useReportDetail = (options: DetailHookProps) => {
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
const { interiorLogs, externalLogs } = processLogResponses(processRes.data)
setInteriorWorkflowFlowRecordLogResponses(interiorLogs)
setExternalWorkflowFlowRecordLogResponses(externalLogs)
}
}
}, [id])
......
import React, { useEffect } from 'react'
import { findLastIndexFlowState } from '@/utils'
import { Skeleton } from 'antd';
import style from './index.less'
import TransferProcess from '../transferProcess'
import DescriptionsInfo from '../descriptionsInfo'
......@@ -136,11 +137,12 @@ const BidDetailSection:React.FC<BidDetailSectionProps> = ({
}
return (
formContext.data &&
<div className={[style.anchorContentWrap, "anchorContent"].join(' ')}>
<RenderDetailSection componentList={anchorList} />
</div>
// formContext.data &&
<Skeleton active loading={!(formContext.externalWorkflowFlowRecordLogResponses || formContext.interiorWorkflowFlowRecordLogResponses)}>
<div className={[style.anchorContentWrap, "anchorContent"].join(' ')}>
<RenderDetailSection componentList={anchorList} />
</div>
</Skeleton>
)
}
......
......@@ -19,6 +19,28 @@ import { CALLFORBID_TYPE, PURCHASE_TYPE } from '@/constants/procurement'
}, {});
}
/** 根据招投标流程api返回的字段 处理成组件需要的状态数据格式 */
export const processLogResponses = (resData) => {
const { currentInnerStep, currentOuterStep, externalTasks } = resData
const externalLogs = externalTasks.map(item => ({
id: item.taskStep,
name: item.taskName,
operationRole: item.userRoleName,
isActive: item.taskStep <= currentOuterStep
}))
const subTasks = externalTasks.filter(item => item.taskStep === currentOuterStep)
const interiorLogs = subTasks.length ? subTasks[0]['subTasks'].map(item => ({
id: item.taskStep,
name: item.taskName,
operationRole: item.userRoleName,
isActive: item.taskStep <= currentInnerStep
})) : null
return {
interiorLogs,
externalLogs
}
}
// 招投标内部状态
export const insideStatusText = [
"待提交审核",
......
......@@ -21,6 +21,12 @@ const LogisticsBillQuery = () => {
})
}
const handleSubmit = (id: number) => {
PublicApi.postLogisticsOrderWaitSubmitSubmit({ id: id }).then(res => {
reload.current.reload()
})
}
const columns: ColumnType<any>[] = [
{
title: '物流单号',
......@@ -76,8 +82,10 @@ const LogisticsBillQuery = () => {
key: 'submitOrUpdateOrDel',
dataIndex: 'submitOrUpdateOrDel',
render: (text, data) => text && <>
<Button type='link'>提交</Button>
<Button type='link' onClick={() => history.push(`/memberCenter/logisticsAbility/logisticsBillSubmit/waitSbumitLogisticsBill/edit?id=${data.id}`)}>编辑</Button>
<Popconfirm title="确定要提交吗?" okText="是" cancelText="否" onConfirm={() => handleSubmit(data.id)}>
<Button type='link'>提交</Button>
</Popconfirm>
<Popconfirm title="确定要删除吗?" okText="是" cancelText="否" onConfirm={() => handleDelete(data.id)}>
<Button type='link'>
删除
......
......@@ -116,7 +116,11 @@ const BidModal: React.FC<IProps> = (props: any) => {
urls: files,
priceParityInfos,
}
for(let i = 0; i < dataSource.length; i++) {
if (isEmpty(priceParityInfos)) {
message.warning('请核对比价信息授标是否勾选!');
return
}
for (let i = 0; i < dataSource.length; i++) {
const count = sumBy(dataSource[i].company, 'awardTaxProbability');
if (count > 100 || count < 100) {
message.warning(`${dataSource[i].number}授标百分比分配不准确,请核对!`);
......
......@@ -191,7 +191,7 @@ const ContrastPrice = () => {
link === 'preview' ? null :
<Button
type='primary'
disabled={disabled}
// disabled={disabled}
onClick={() => setVisible(true)}
>
<CheckCircleOutlined />
......
......@@ -7,7 +7,8 @@ import { observer } from 'mobx-react'
import { PublicApi } from '@/services/api';
import { priceFormat } from '@/utils/numberFomat';
import { formatTimeString } from '@/utils'
import { formatTimeString } from '@/utils';
import { toChatRoom } from '@/utils/im';
import { usePurchaseBidStore } from '@/store/purchaseBid';
import StatusBox from '../../../purchaseBid/readyBid/management/components/statusBox';
......@@ -98,7 +99,7 @@ const Detail = () => {
<div className={styles.warp}>
<div className={styles.header}>
<ArrowLeftOutlined className={styles.goBack} onClick={() => history.goBack()} />
<div className={styles.title}>{dataSource?.details}<span>{dataSource?.createMemberName}</span><IMBtn func={() => console.log('ok')} /></div>
<div className={styles.title}>{dataSource?.details}<span>{dataSource?.createMemberName}</span><IMBtn func={() => toChatRoom(dataSource.memberId)} /></div>
</div>
<div className={styles.layout}>
<Row gutter={[8, 8]}>
......
......@@ -5,6 +5,7 @@ import level1 from '@/assets/icons/the_first.png';
import level2 from '@/assets/icons/the_second.png';
import level3 from '@/assets/icons/the_third.png';
import { priceFormat } from '@/utils/numberFomat';
import { toChatRoom } from '@/utils/im';
import IMBtn from '../../../../../components/detail/components/iMBtn';
......@@ -55,7 +56,7 @@ const RankRow: React.FC<RankRowProps> = (props: any) => {
</div>
<div className={styles.rankRowRight}>
{detail.contacts}
<IMBtn func={() => console.log(1)} />
<IMBtn func={() => toChatRoom(detail.memberId)} />
</div>
</div>
)
......@@ -71,7 +72,7 @@ const RankRow: React.FC<RankRowProps> = (props: any) => {
<div>
<div className={styles.rankRowRight}>
{detail.contacts}
<IMBtn func={() => console.log(1)} />
<IMBtn func={() => toChatRoom(detail.memberId)} />
</div>
</div>
</div>
......
......@@ -262,7 +262,7 @@ const Demand: React.FC<Iprops> = (props: any) => {
rules={[{ required: true, message: '请选择对接方式' }]}
>
<Radio.Group onChange={changeRadio}>
<Radio value={1}><Tooltip placement="topLeft" title={<>需求发布至企业商城求购频道</>}>发布至平台<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip></Radio>
<Radio value={1}><Tooltip placement="topLeft" title={<>需求发布至采购门户</>}>发布至平台<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip></Radio>
<Radio value={2}><Tooltip placement="topLeft" title={<>系统通过需求单品类、商品属性、适用地市与平台会员发布的商品品类、商品属性、归属地区进行匹配,推荐满足条件的平台会员</>}>系统匹配<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip></Radio>
<Radio value={3}><Tooltip placement="topLeft" title={<>选择与当前会员有归属关系的会员且角色类型为服务提供的会员(供应商),需求只发送给指定会员</>}>邀请会员<QuestionCircleOutlined style={{ marginLeft: '5px' }} /></Tooltip></Radio>
</Radio.Group>
......
......@@ -146,7 +146,7 @@ export const useProductTableChangeForPay = (ctx: ISchemaFormActions | ISchemaFor
export const useOrderFormInitEffect = (ctx: ISchemaFormActions | ISchemaFormAsyncActions) => {
const { modelType = 0, spam_id } = history.location.query
const typeEnums = parseInt(modelType)
let auth = JSON.parse(localStorage.getItem('auth'))
let auth = JSON.parse(localStorage.getItem('auth') || localStorage.getItem('AUTH'))
FormEffectHooks.onFormMount$().subscribe(async () => {
ctx.setFieldState('orderModel', state => {
......
import React from 'react';
import { Button, notification, message } from 'antd';
import BASE_CONFIG from '../../config/base.config.json'
import { PublicApi } from '@/services/api';
import { SHOP_TYPE } from '@/constants';
import { getAuth } from '@/utils/auth';
const DOMAIN = {...BASE_CONFIG}.global.siteInfo.siteUrl.replace('www','');//document.domain
const CHATROOM_URL = `http://chatroom${DOMAIN}/chatRoom`;
const COOKIEPREFIX = 'CHATROOM_';
// 主动调起聊天室 mmeberId 为接收人的memberId
export const toChatRoom = (memberId: string = '', shopType: number = 1) => {
const _curUserInfo = getAuth();
if(!memberId){
document.cookie = `${COOKIEPREFIX}userInfo=${JSON.stringify(_curUserInfo)};path=/;domain=${DOMAIN}`;
document.cookie = `${COOKIEPREFIX}shopType=${shopType};path=/;domain=${DOMAIN}`;
window.open(CHATROOM_URL);
return;
}
PublicApi.getMessageImHistorySession({ memberId: memberId, currMemberId: String(_curUserInfo.memberId) }).then(res => {
if (res.code === 1000) {
const _userId = res.data.data?.[0]?.userList?.[0]?.userId
if (_userId) {
document.cookie = `${COOKIEPREFIX}curMemberId=${memberId};path=/;domain=${DOMAIN}`;
document.cookie = `${COOKIEPREFIX}curUserId=${_userId};path=/;domain=${DOMAIN}`;
document.cookie = `${COOKIEPREFIX}userInfo=${JSON.stringify(_curUserInfo)};path=/;domain=${DOMAIN}`;
document.cookie = `${COOKIEPREFIX}shopType=${shopType};path=/;domain=${DOMAIN}`;
window.open(CHATROOM_URL);
} else {
message.error('该会员底下没有客服!');
}
}
})
}
interface NotificationChatRoomProps {
//通知消息
detail: any
}
// 被动从websocket调起聊天室
export const notificationChatRoom = (props: NotificationChatRoomProps) => {
const { detail } = props
const _curUserInfo = getAuth();
const close = () => {
console.log(
'Notification was closed. Either the close button was clicked or duration time elapsed.',
);
};
const key = `open${Date.now()}`;
const btn = (
<Button type="primary" size="small" onClick={() => {
document.cookie = `${COOKIEPREFIX}userInfo=${JSON.stringify(_curUserInfo)};path=/;domain=${DOMAIN}`;
document.cookie = `${COOKIEPREFIX}shopType=${shopType};path=/;domain=${DOMAIN}`;
window.open(CHATROOM_URL);
notification.close(key)
}}>
查看
</Button>
);
notification.open({
message: '你收到一条消息',
description:
'A function will be be called after the notification is closed (automatically after the "duration" time of manually).',
btn,
key,
duration: 10,
onClose: close,
});
}
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