var _customState = {};
var APP_TYPE = 'APP_N9NPHVTQLPBPO8MR6WFG';
var CUSTOMER_FORM_UUID = 'FORM-NO966791YOK2XKW9DMSEGD5L1IN73UHW3ME6LR1';
var STORAGE_KEY = 'tyson.customer-info-query.selected-customer';
var requestSequence = 0;
var FIELDS = {
customerNumber: 'textField_l6em70k2',
customerName: 'textField_l6em70k4'
};
export function didMount() {
var cached = null;
try {
cached = JSON.parse(window.localStorage.getItem(STORAGE_KEY) || 'null');
} catch (e) {
cached = null;
}
this.setCustomState({
keyword: cached && cached.customerNumber ? cached.customerNumber + ' - ' + (cached.customerName || '') : '',
searching: false,
customers: [],
selectedCustomer: cached && cached.customerNumber ? cached : null,
queryType: 'balance',
querying: false,
result: null,
error: '',
searchVisible: false
});
}
export function didUnmount() {
if (this._customerSearchTimer) {
clearTimeout(this._customerSearchTimer);
}
}
export function setQueryType(queryType) {
this.setCustomState({
queryType: queryType,
result: null,
error: ''
});
this.forceUpdate();
}
export function updateKeyword(value) {
var self = this;
var keyword = value || '';
self.setCustomState({
keyword: keyword,
searchVisible: true,
error: ''
});
self.forceUpdate();
if (self._customerSearchTimer) {
clearTimeout(self._customerSearchTimer);
}
if (keyword.trim().length < 2) {
self.setCustomState({
customers: [],
searching: false
});
self.forceUpdate();
return;
}
self._customerSearchTimer = setTimeout(function () {
self.searchCustomers(keyword.trim());
}, 300);
}
export function searchCustomers(keyword) {
var self = this;
var base = {
formUuid: CUSTOMER_FORM_UUID,
appType: APP_TYPE,
currentPage: 1,
pageSize: 20
};
var codeCondition = [{
key: FIELDS.customerNumber,
value: keyword,
type: 'TEXT',
operator: 'contains',
componentName: 'TextField'
}];
var nameCondition = [{
key: FIELDS.customerName,
value: keyword,
type: 'TEXT',
operator: 'contains',
componentName: 'TextField'
}];
self.setCustomState({
searching: true
});
self.forceUpdate();
var codeParams = {};
var nameParams = {};
Object.keys(base).forEach(key => {
codeParams[key] = base[key];
nameParams[key] = base[key];
});
codeParams.searchFieldJson = JSON.stringify(codeCondition);
nameParams.searchFieldJson = JSON.stringify(nameCondition);
return Promise.all([self.utils.yida.searchFormDatas(codeParams), self.utils.yida.searchFormDatas(nameParams)]).then(function (responses) {
var seen = {};
var customers = [];
responses.forEach(response => {
var rows = response && response.data || response && response.content && response.content.data || [];
rows.forEach(row => {
var formData = row.formData || {};
var customerNumber = formData[FIELDS.customerNumber];
if (customerNumber && !seen[customerNumber]) {
seen[customerNumber] = true;
customers.push({
customerNumber: customerNumber,
customerName: formData[FIELDS.customerName] || ''
});
}
});
});
self.setCustomState({
customers: customers,
searching: false
});
self.forceUpdate();
}).catch(function (error) {
self.setCustomState({
searching: false,
customers: []
});
self.utils.toast({
title: error && error.message ? error.message : '客户查询失败',
type: 'error'
});
self.forceUpdate();
});
}
export function selectCustomer(customer) {
try {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(customer));
} catch (e) {
// The query remains usable when browser storage is unavailable.
}
this.setCustomState({
selectedCustomer: customer,
keyword: customer.customerNumber + ' - ' + customer.customerName,
searchVisible: false,
customers: [],
result: null,
error: ''
});
this.forceUpdate();
}
export function clearCustomer() {
try {
window.localStorage.removeItem(STORAGE_KEY);
} catch (e) {
// Ignore storage cleanup errors.
}
this.setCustomState({
keyword: '',
selectedCustomer: null,
customers: [],
result: null,
error: ''
});
this.forceUpdate();
}
export function queryCustomerInfo() {
var self = this;
var state = self.getCustomState();
var selected = state.selectedCustomer;
if (!selected) {
self.utils.toast({
title: '请先选择客户',
type: 'warning'
});
return;
}
var dataSourceName = state.queryType === 'balance' ? 'customerBalance' : 'customerUnlockOrders';
var dataSource = self.dataSourceMap && self.dataSourceMap[dataSourceName];
if (!dataSource || !dataSource.load) {
var availableDataSources = self.dataSourceMap ? Object.keys(self.dataSourceMap).join(', ') : '未初始化';
var message = '查询数据源不可用:' + dataSourceName + ';当前数据源:' + availableDataSources;
self.setCustomState({
error: message,
result: null
});
self.utils.toast({
title: message,
type: 'error'
});
self.forceUpdate();
return;
}
self.setCustomState({
querying: true,
error: '',
result: null
});
self.forceUpdate();
var request = {
inputs: JSON.stringify({
Headers: {
'Content-Type': 'application/json'
},
Query: {},
Body: {
requestID: self.createRequestId(),
CUSTOMER_NUMBER: selected.customerNumber,
CUSTOMER_NAME: selected.customerName
}
})
};
try {
return Promise.resolve(dataSource.load(request)).then(function (result) {
self.handleQueryResponse(result);
}).catch(function (error) {
self.setCustomState({
querying: false,
result: null,
error: error && error.message ? error.message : 'SAP查询失败'
});
self.utils.toast({
title: error && error.message ? error.message : 'SAP查询失败',
type: 'error'
});
self.forceUpdate();
});
} catch (error) {
self.setCustomState({
querying: false,
result: null,
error: error && error.message ? error.message : 'SAP查询初始化失败'
});
self.utils.toast({
title: error && error.message ? error.message : 'SAP查询初始化失败',
type: 'error'
});
self.forceUpdate();
}
}
export function handleQueryResponse(result) {
var response = result && result.Response !== undefined ? result.Response : result;
response = response && response.content !== undefined ? response.content : response;
response = response && response.serviceReturnValue !== undefined ? response.serviceReturnValue : response;
if (typeof response === 'string') {
try {
response = JSON.parse(response);
} catch (e) {
var responseText = response.toLowerCase();
var gatewayMessage = responseText.indexOf('502 bad gateway') >= 0 || responseText.indexOf('503 service unavailable') >= 0 || responseText.indexOf('= 0 || responseText.indexOf('
= 0 ? 'SAP查询服务暂时不可用,请稍后重试' : 'SAP查询服务返回格式异常';
this.setCustomState({
querying: false,
result: null,
error: gatewayMessage
});
this.utils.toast({
title: gatewayMessage,
type: 'error'
});
this.forceUpdate();
return;
}
}
if (response && response.success === false) {
var responseMessage = response.message || response.errorMsg || 'SAP查询失败';
this.setCustomState({
querying: false,
result: null,
error: responseMessage
});
this.utils.toast({
title: responseMessage,
type: 'error'
});
this.forceUpdate();
return;
}
if (response && response.STATUS && response.STATUS !== 'S') {
var sapMessage = response.MESSAGE || 'SAP查询失败,状态=' + response.STATUS;
this.setCustomState({
querying: false,
result: null,
error: sapMessage
});
this.utils.toast({
title: sapMessage,
type: 'error'
});
this.forceUpdate();
return;
}
var message = response && response.MESSAGE;
var errorItem = response && response.ITEM && response.ITEM.filter(item => item && item.ERRO_MESSAGE)[0];
if (message || errorItem) {
var errorMessage = message || errorItem.ERRO_MESSAGE;
this.setCustomState({
querying: false,
result: null,
error: errorMessage
});
this.utils.toast({
title: errorMessage,
type: 'error'
});
this.forceUpdate();
return;
}
this.setCustomState({
querying: false,
result: response || {}
});
this.forceUpdate();
}
export function createRequestId() {
requestSequence += 1;
if (window.crypto && window.crypto.randomUUID) {
return window.crypto.randomUUID();
}
if (window.crypto && window.crypto.getRandomValues) {
var values = new Uint32Array(4);
window.crypto.getRandomValues(values);
return values[0].toString(16) + '-' + values[1].toString(16) + '-' + values[2].toString(16) + '-' + values[3].toString(16);
}
return Date.now().toString(36) + '-' + requestSequence.toString(36) + '-' + Math.random().toString(36).slice(2);
}
export function formatAmount(value) {
var amount = Number(value || 0);
if (isNaN(amount)) {
return value || '-';
}
return amount.toLocaleString('zh-CN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
export function formatDate(value) {
if (!value) {
return value || '-';
}
var text = String(value);
if (text.length === 8) {
return text.slice(0, 4) + '-' + text.slice(4, 6) + '-' + text.slice(6, 8);
}
var matched = text.match(/^(\d{4}-\d{2}-\d{2})/);
return matched ? matched[1] : text;
}
export function formatTime(value) {
if (!value) {
return '-';
}
var matched = String(value).match(/T(\d{2}:\d{2}:\d{2})/);
return matched ? matched[1] : String(value);
}
export function renderBalanceSummary(result) {
return 客户组 {result.CUSTOMER_GROUP || '-'}
客户组描述 {result.CUSTOMER_GROUP_DESC || '-'}
总风险金额 {this.formatAmount(result.TOTAL_RISK_AMT)}
;
}
export function renderBalance(state, mobile) {
var result = state.result || {};
var items = result.ITEM || [];
if (!items.length) {
return 未查询到余额数据
;
}
return {this.renderBalanceSummary(result)}
公司代码 币种 未结金额 {items.map((item, index) => {item.COMPANY_CODE || '-'} {item.CURRENCY || '-'} {this.formatAmount(item.OUTSTAND_AMT)} )}
;
}
export function renderOrders(state, mobile) {
var items = state.result && state.result.ITEM || [];
if (!items.length) {
return 未查询到收款解锁订单
;
}
if (mobile) {
return {items.map((item, index) =>
{item.SALES_ORDER || '-'} {item.RELEASE_STATUS === 'S' ? '成功' : '失败'}
公司代码 {item.COMPANY_CODE || '-'}
销售组织 {item.SALES_ORG || '-'}
订单金额 {this.formatAmount(item.SALES_AMOUNT)} {item.CURRENCY || ''}
释放日期 {this.formatDate(item.RELEASE_DATE)}
释放时间 {this.formatTime(item.RELEASE_TIME)}
)}
;
}
return 公司代码 销售订单号 销售组织 订单金额 币种 释放日期 释放时间 状态 {items.map((item, index) => {item.COMPANY_CODE || '-'} {item.SALES_ORDER || '-'} {item.SALES_ORG || '-'} {this.formatAmount(item.SALES_AMOUNT)} {item.CURRENCY || '-'} {this.formatDate(item.RELEASE_DATE)} {this.formatTime(item.RELEASE_TIME)} {item.RELEASE_STATUS === 'S' ? '成功' : '失败'} )}
;
}
export function renderJsx() {
var self = this;
var state = self.getCustomState();
var mobile = self.utils.isMobile();
var selected = state.selectedCustomer;
var result = state.result;
return
CUSTOMER SERVICE
客户信息查询 查询客户余额与收款解锁订单
选择客户
{
self.updateKeyword(e.target.value);
}} onFocus={e => {
self.setCustomState({
searchVisible: true
});
self.forceUpdate();
}} style={styles.input} />
{selected &&
{
self.clearCustomer();
}} style={styles.clearButton}>清除 }
{state.searchVisible && (state.searching || state.customers && state.customers.length > 0) &&
{state.searching &&
正在搜索客户...
}
{!state.searching && state.customers.map(customer =>
{
self.selectCustomer(customer);
}} style={styles.customerOption}>{customer.customerNumber} {customer.customerName || '未维护名称'} )}
}
查询内容
客户余额
{
self.setQueryType(state.queryType === 'balance' ? 'unlockOrders' : 'balance');
}} style={state.queryType === 'balance' ? styles.switchTrack : styles.switchTrackActive}>
收款解锁订单
{!mobile &&
操作
}
{
if (!selected) {
self.setCustomState({
error: '请先选择客户后再查询',
result: null
});
self.forceUpdate();
return;
}
self.queryCustomerInfo();
}} style={state.querying || !selected ? mobile ? styles.queryDisabledMobile : styles.queryDisabled : mobile ? styles.queryButtonMobile : styles.queryButton}>{state.querying ? '查询中...' : '查询'}
{!selected && 请选择客户后再查询
}
{state.error &&
{state.error}
}
{result &&
{state.queryType === 'balance' ? 'BALANCE' : 'UNLOCKED ORDERS'}
{state.queryType === 'balance' ? '客户余额' : '收款解锁订单'} 客户编码:{result.CUSTOMER_NUMBER || selected && selected.customerNumber || '-'} 客户名称:{result.CUSTOMER_NAME || selected && selected.customerName || '-'}
{state.queryType === 'balance' ? self.renderBalance(state, mobile) : self.renderOrders(state, mobile)}
}
{!result && !state.error &&
选择客户和查询内容后,可查看对应的 SAP 信息。
}
{this.state && this.state.timestamp}
;
}
var styles = {
page: {
minHeight: '100vh',
background: '#F4F6F5',
color: '#17211E',
fontFamily: 'Microsoft YaHei, Arial, sans-serif',
padding: '20px 16px 40px'
},
shell: {
maxWidth: 1120,
margin: '0 auto'
},
header: {
padding: '12px 0 22px',
borderBottom: '1px solid #DCE3DF',
marginBottom: 20,
textAlign: 'center'
},
eyebrow: {
color: '#3B6C55',
fontSize: 11,
fontWeight: 700,
letterSpacing: 1.2,
marginBottom: 6
},
title: {
margin: 0,
fontSize: 28,
lineHeight: 1.2,
letterSpacing: '-0.5px'
},
subtitle: {
margin: '8px 0 0',
color: '#66746E',
fontSize: 14
},
panel: {
background: '#FFFFFF',
border: '1px solid #DCE3DF',
padding: 20,
boxShadow: '0 10px 28px rgba(25,48,38,.06)'
},
fieldLabel: {
color: '#405149',
fontSize: 13,
fontWeight: 700,
margin: '0 0 8px'
},
queryRow: {
display: 'flex',
alignItems: 'flex-end',
gap: 14
},
queryStack: {
display: 'flex',
flexDirection: 'column',
gap: 14
},
customerField: {
flex: 1,
minWidth: 260
},
queryTypeField: {
width: 280
},
queryActionField: {
width: 110
},
queryActionFieldMobile: {
width: '100%'
},
searchWrap: {
position: 'relative'
},
input: {
width: '100%',
boxSizing: 'border-box',
minHeight: 46,
border: '1px solid #B7C5BD',
borderRadius: 4,
padding: '0 72px 0 13px',
fontSize: 15,
outline: 'none',
background: '#fff'
},
clearButton: {
position: 'absolute',
right: 8,
top: 8,
border: 0,
background: '#EEF3F0',
color: '#466253',
minHeight: 30,
borderRadius: 3,
padding: '0 10px',
cursor: 'pointer'
},
searchMenu: {
position: 'absolute',
zIndex: 20,
top: 49,
left: 0,
right: 0,
maxHeight: 280,
overflowY: 'auto',
background: '#fff',
border: '1px solid #B7C5BD',
boxShadow: '0 12px 24px rgba(22,43,34,.14)'
},
searchHint: {
padding: 14,
color: '#66746E',
fontSize: 13
},
customerOption: {
display: 'flex',
width: '100%',
minHeight: 48,
padding: '10px 13px',
gap: 12,
alignItems: 'center',
border: 0,
borderBottom: '1px solid #EDF1EE',
background: '#fff',
textAlign: 'left',
cursor: 'pointer',
color: '#17211E'
},
switchRow: {
display: 'flex',
minHeight: 44,
alignItems: 'center',
justifyContent: 'space-between',
gap: 8
},
switchLabel: {
color: '#89958F',
fontSize: 13,
whiteSpace: 'nowrap'
},
switchLabelActive: {
color: '#24563E',
fontSize: 13,
fontWeight: 700,
whiteSpace: 'nowrap'
},
switchTrack: {
position: 'relative',
width: 46,
height: 24,
flex: '0 0 46px',
padding: 0,
border: 0,
borderRadius: 12,
background: '#24563E',
cursor: 'pointer'
},
switchTrackActive: {
position: 'relative',
width: 46,
height: 24,
flex: '0 0 46px',
padding: 0,
border: 0,
borderRadius: 12,
background: '#D76F2B',
cursor: 'pointer'
},
switchThumb: {
position: 'absolute',
top: 3,
left: 3,
width: 18,
height: 18,
borderRadius: '50%',
background: '#fff',
boxShadow: '0 1px 3px rgba(0,0,0,.22)'
},
switchThumbActive: {
position: 'absolute',
top: 3,
right: 3,
width: 18,
height: 18,
borderRadius: '50%',
background: '#fff',
boxShadow: '0 1px 3px rgba(0,0,0,.22)'
},
queryButton: {
width: '100%',
minHeight: 46,
border: 0,
borderRadius: 4,
background: '#D76F2B',
color: '#fff',
fontSize: 15,
fontWeight: 700,
cursor: 'pointer'
},
queryDisabled: {
width: '100%',
minHeight: 46,
border: 0,
borderRadius: 4,
background: '#C8D0CB',
color: '#FFFFFF',
fontSize: 15,
fontWeight: 700,
cursor: 'not-allowed'
},
queryButtonMobile: {
width: '100%',
minHeight: 42,
border: 0,
borderRadius: 4,
background: '#D76F2B',
color: '#fff',
fontSize: 14,
fontWeight: 700,
cursor: 'pointer'
},
queryDisabledMobile: {
width: '100%',
minHeight: 42,
border: 0,
borderRadius: 4,
background: '#C8D0CB',
color: '#FFFFFF',
fontSize: 14,
fontWeight: 700,
cursor: 'not-allowed'
},
validationHint: {
marginTop: 8,
color: '#9B3D15',
fontSize: 12
},
resultPanel: {
background: '#FFFFFF',
border: '1px solid #DCE3DF',
margin: '20px auto 0',
padding: 24,
maxWidth: 1120,
boxSizing: 'border-box'
},
resultHeader: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'column',
gap: 8,
borderBottom: '1px solid #E7ECE9',
paddingBottom: 16,
marginBottom: 18,
textAlign: 'center'
},
resultTitle: {
margin: 0,
fontSize: 22
},
customerSummary: {
display: 'flex',
justifyContent: 'center',
flexWrap: 'wrap',
gap: '4px 16px',
color: '#5D6B64',
fontSize: 13,
textAlign: 'center'
},
balanceSummary: {
display: 'flex',
justifyContent: 'center',
gap: 40,
marginBottom: 18,
padding: '14px 18px',
background: '#F6F9F7',
border: '1px solid #DDE6E0',
color: '#405149',
textAlign: 'center'
},
summaryLabel: {
display: 'block',
marginBottom: 5,
color: '#718078',
fontSize: 12,
fontWeight: 400
},
summaryAmount: {
color: '#1D6141',
fontVariantNumeric: 'tabular-nums'
},
empty: {
padding: '36px 18px',
marginTop: 20,
textAlign: 'center',
color: '#7A8881',
background: '#FFFFFF',
border: '1px dashed #C9D5CE',
fontSize: 14
},
error: {
marginTop: 20,
padding: '12px 14px',
background: '#FFF1EB',
border: '1px solid #F1B895',
color: '#9B3D15',
fontSize: 14
},
tableWrap: {
overflowX: 'auto',
border: '1px solid #DDE6E0',
borderRadius: 4,
background: '#FFFFFF'
},
table: {
width: '100%',
borderCollapse: 'collapse',
fontSize: 13,
minWidth: 620,
textAlign: 'center',
lineHeight: 1.35
},
balanceTableWrapMobile: {
overflowX: 'auto',
border: '1px solid #DDE6E0',
borderRadius: 4,
background: '#FFFFFF'
},
balanceTableMobile: {
width: '100%',
borderCollapse: 'collapse',
fontSize: 12,
minWidth: 300,
textAlign: 'center',
lineHeight: 1.2
},
amountCell: {
textAlign: 'right',
fontVariantNumeric: 'tabular-nums'
},
amountHighlight: {
textAlign: 'right',
color: '#1D6141',
fontWeight: 700,
fontVariantNumeric: 'tabular-nums'
},
nameCell: {
textAlign: 'left',
minWidth: 150
},
orderCell: {
fontFamily: 'Consolas, monospace',
fontWeight: 700
},
orderCard: {
marginBottom: 10,
padding: '13px 14px',
border: '1px solid #DDE6E0',
borderRadius: 4,
background: '#FFFFFF'
},
orderCardHeader: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
paddingBottom: 10,
marginBottom: 10,
borderBottom: '1px solid #E7ECE9'
},
orderCardNumber: {
fontFamily: 'Consolas, monospace',
color: '#17211E',
fontSize: 15
},
orderCardGrid: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '10px 14px',
color: '#64726B',
fontSize: 12
},
orderCardAmount: {
color: '#1D6141',
fontVariantNumeric: 'tabular-nums'
},
mobileCard: {
border: '1px solid #DFE7E2',
padding: 15,
marginBottom: 10,
background: '#FBFCFB'
},
cardTop: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 14
},
currency: {
color: '#5F6E66',
fontSize: 12
},
metric: {
display: 'flex',
justifyContent: 'space-between',
gap: 12,
padding: '8px 0',
borderTop: '1px solid #E7ECE9',
color: '#64726B',
fontSize: 13
},
highlight: {
color: '#1D6141',
fontWeight: 700
},
detailGrid: {
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '8px 12px',
fontSize: 13,
color: '#64726B'
},
statusSuccess: {
display: 'inline-block',
padding: '3px 8px',
borderRadius: 12,
color: '#1D6141',
background: '#E4F1E8',
fontSize: 12,
fontWeight: 700
},
statusError: {
display: 'inline-block',
padding: '3px 8px',
borderRadius: 12,
color: '#A83B27',
background: '#FCE9E4',
fontSize: 12,
fontWeight: 700
}
};
export function getCustomState(key) {
if (typeof _customState === "undefined") {
return key ? undefined : {};
}
if (key) {
return _customState[key];
}
return Object.assign({}, _customState);
}
export function setCustomState(newState) {
if (typeof _customState === "undefined") {
return;
}
Object.keys(newState || {}).forEach(function(key) {
_customState[key] = newState[key];
});
this.forceUpdate();
}
export function forceUpdate() {
this.setState({ timestamp: new Date().getTime() });
}