// 基礎組件類(lèi)模板
class BaseComponent extends Component {
constructor(props) {
super(props);
// 初始化狀態(tài)
this.state = {
loading: false,
error: null,
data: null
};
// 綁定方法
this.handleError = this.handleError.bind(this);
this.setLoading = this.setLoading.bind(this);
}
// 生命周期方法
componentDidMount() {
this.initialize();
}
componentDidUpdate(prevProps, prevState) {
// 屬性變化處理
if (this.props.id !== prevProps.id) {
this.reloadData();
}
}
componentWillUnmount() {
// 清理操作
this.cancelRequests();
}
// 初始化方法
initialize = () => {
this.loadData();
}
// 數據加載方法
loadData = async () => {
this.setLoading(true);
try {
const data = await this.fetchData();
this.setState({ data, error: null });
} catch (error) {
this.handleError(error);
} finally {
this.setLoading(false);
}
}
// 抽象方法,由子類(lèi)實(shí)現
fetchData = () => {
throw new Error('fetchData method must be implemented');
}
// 錯誤處理
handleError = (error) => {
console.error('Component error:', error);
this.setState({ error: error.message });
// 可以在這里添加錯誤上報邏輯
this.reportError(error);
}
// 設置加載狀態(tài)
setLoading = (loading) => {
this.setState({ loading });
}
// 重新加載數據
reloadData = () => {
this.loadData();
}
// 取消請求
cancelRequests = () => {
// 取消進(jìn)行中的請求
}
// 錯誤上報
reportError = (error) => {
// 錯誤上報邏輯
}
render() {
const { loading, error, data } = this.state;
if (loading) {
return this.renderLoading();
}
if (error) {
return this.renderError();
}
if (!data) {
return this.renderEmpty();
}
return this.renderContent();
}
// 渲染方法
renderLoading = () => {
return <div>加載中...</div>;
}
renderError = () => {
return <div>錯誤: {this.state.error}</div>;
}
renderEmpty = () => {
return <div>暫無(wú)數據</div>;
}
renderContent = () => {
return <div>內容</div>;
}
}
// 報關(guān)單詳情組件類(lèi)
class CkgdDetail extends BaseComponent {
constructor(props) {
super(props);
this.state = {
...this.state,
basicInfo: {},
goodsList: [],
attachments: [],
activeTab: 'basic'
};
}
// 實(shí)現抽象方法
fetchData = async () => {
const { entryId } = this.props;
if (!entryId) {
throw new Error('報關(guān)單號不能為空');
}
// 并行請求所有數據
const [basicRes, goodsRes, attachRes] = await Promise.all([
this.fetchBasicInfo(entryId),
this.fetchGoodsList(entryId),
this.fetchAttachments(entryId)
]);
return {
basicInfo: basicRes.result,
goodsList: goodsRes.result,
attachments: attachRes.result
};
}
// 獲取基礎信息
fetchBasicInfo = async (entryId) => {
return await post(allUrl.ckfpCkgd.relDatails, {}, {
header: allUrl.header,
condition: { entryId }
});
}
// 獲取商品列表
fetchGoodsList = async (entryId) => {
return await post(allUrl.ckfpCkgd.goodsList, {}, {
header: allUrl.header,
condition: { entryId }
});
}
// 獲取附件列表
fetchAttachments = async (entryId) => {
return await post(allUrl.ckfpCkgd.attachmentList, {}, {
header: allUrl.header,
condition: { entryId }
});
}
// 處理數據加載完成
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
if (this.state.data && !prevState.data) {
this.initializeTabs();
}
}
// 初始化標簽頁(yè)
initializeTabs = () => {
const { data } = this.state;
const tabs = [];
if (data.basicInfo) {
tabs.push({ key: 'basic', label: '基礎信息' });
}
if (data.goodsList && data.goodsList.length > 0) {
tabs.push({ key: 'goods', label: `商品明細(${data.goodsList.length})` });
}
if (data.attachments && data.attachments.length > 0) {
tabs.push({ key: 'attachment', label: `附件(${data.attachments.length})` });
}
this.setState({ tabs });
}
// 處理標簽切換
handleTabChange = (activeTab) => {
this.setState({ activeTab });
}
// 重寫(xiě)渲染內容方法
renderContent = () => {
const { data, activeTab, tabs } = this.state;
return (
<div className="ckgd-detail">
<Tabs activeKey={activeTab} onChange={this.handleTabChange}>
{tabs.map(tab => (
<TabPane key={tab.key} tab={tab.label}>
{this.renderTabContent(tab.key)}
</TabPane>
))}
</Tabs>
</div>
);
}
// 渲染標簽頁(yè)內容
renderTabContent = (tabKey) => {
const { data } = this.state;
switch (tabKey) {
case 'basic':
return <BasicInfoPanel data={data.basicInfo} />;
case 'goods':
return <GoodsListPanel data={data.goodsList} />;
case 'attachment':
return <AttachmentPanel data={data.attachments} />;
default:
return null;
}
}
}
// 表格工具類(lèi)
class TableUtils {
// 計算列寬度
static calculateColumnWidth(col, dataSource) {
if (!col || !dataSource) return 100;
const { title, dataIndex, fixedWidth } = col;
// 如果有固定寬度,直接返回
if (fixedWidth) return fixedWidth;
// 計算標題寬度
const titleWidth = (title || '').length * 10 + 20;
// 計算內容最大寬度
let maxContentWidth = 0;
if (dataSource && Array.isArray(dataSource)) {
for (const item of dataSource) {
if (item && dataIndex in item) {
const content = String(item[dataIndex] || '');
const contentWidth = content.length * 8 + 16;
maxContentWidth = Math.max(maxContentWidth, contentWidth);
}
}
}
// 取標題寬度和內容寬度的最大值
let finalWidth = Math.max(titleWidth, maxContentWidth, 80);
// 限制最大寬度
finalWidth = Math.min(finalWidth, 350);
return finalWidth;
}
// 批量計算所有列寬度
static calculateAllColumnsWidth(columns, dataSource) {
if (!columns || !Array.isArray(columns)) return [];
return columns.map(column => ({
...column,
width: this.calculateColumnWidth(column, dataSource)
}));
}
// 初始化表格列
static initializeColumns(columns, fixedColumns, dataSource) {
return columns
.filter(col => !col.unShow)
.map(col => {
let width = this.calculateColumnWidth(col, dataSource);
width = width < 350 ? width : 350;
if (fixedColumns && fixedColumns.includes(col.key)) {
return { ...col, ellipsis: true, fixed: 'left', width };
}
return { ...col, ellipsis: true, width };
});
}
// 獲取可見(jiàn)列
static getVisibleColumns(columns) {
return columns.filter(col => !col.unShow);
}
// 獲取固定列
static getFixedColumns(columns, fixedColumns) {
return columns.filter(col => fixedColumns && fixedColumns.includes(col.key));
}
}
// 表單工具類(lèi)
class FormUtils {
// 表單驗證規則
static validationRules = {
required: (message = '該字段為必填項') => ({
required: true,
message
}),
email: (message = '請輸入有效的郵箱地址') => ({
type: 'email',
message
}),
phone: (message = '請輸入有效的手機號碼') => ({
pattern: /^1[3-9]\d{9}$/,
message
}),
number: (message = '請輸入數字') => ({
pattern: /^\d+$/,
message
}),
minLength: (min, message) => ({
min,
message: message || `長(cháng)度不能少于${min}個(gè)字符`
}),
maxLength: (max, message) => ({
max,
message: message || `長(cháng)度不能超過(guò)${max}個(gè)字符`
})
};
// 獲取表單字段值
static getFieldValue(form, fieldName) {
return form.getFieldValue(fieldName);
}
// 設置表單字段值
static setFieldValue(form, fieldName, value) {
form.setFieldsValue({ [fieldName]: value });
}
// 重置表單
static resetForm(form) {
form.resetFields();
}
// 驗證表單
static validateForm(form) {
return new Promise((resolve, reject) => {
form.validateFields((errors, values) => {
if (errors) {
reject(errors);
} else {
resolve(values);
}
});
});
}
// 創(chuàng )建表單配置
static createFormConfig(fields, layout = 'horizontal') {
return {
layout,
fields: fields.map(field => ({
...field,
rules: this.getFieldRules(field)
}))
};
}
// 獲取字段驗證規則
static getFieldRules(field) {
const rules = [];
if (field.required) {
rules.push(this.validationRules.required(field.requiredMessage));
}
if (field.type === 'email') {
rules.push(this.validationRules.email());
}
if (field.type === 'phone') {
rules.push(this.validationRules.phone());
}
if (field.minLength) {
rules.push(this.validationRules.minLength(field.minLength));
}
if (field.maxLength) {
rules.push(this.validationRules.maxLength(field.maxLength));
}
// 自定義規則
if (field.rules) {
rules.push(...field.rules);
}
return rules;
}
}
// API服務(wù)基類(lèi)
class ApiService {
constructor(baseUrl = '') {
this.baseUrl = baseUrl;
this.requestInterceptors = [];
this.responseInterceptors = [];
}
// 添加請求攔截器
addRequestInterceptor(interceptor) {
this.requestInterceptors.push(interceptor);
}
// 添加響應攔截器
addResponseInterceptor(interceptor) {
this.responseInterceptors.push(interceptor);
}
// 發(fā)送請求
async request(config) {
// 應用請求攔截器
let finalConfig = config;
for (const interceptor of this.requestInterceptors) {
finalConfig = await interceptor(finalConfig);
}
try {
const response = await this.send(finalConfig);
// 應用響應攔截器
let finalResponse = response;
for (const interceptor of this.responseInterceptors) {
finalResponse = await interceptor(finalResponse);
}
return finalResponse;
} catch (error) {
// 錯誤處理
throw this.handleError(error);
}
}
// 發(fā)送HTTP請求(抽象方法)
async send(config) {
throw new Error('send method must be implemented');
}
// GET請求
async get(url, params = {}, config = {}) {
return this.request({
method: 'GET',
url: this.buildUrl(url),
params,
...config
});
}
// POST請求
async post(url, data = {}, config = {}) {
return this.request({
method: 'POST',
url: this.buildUrl(url),
data,
...config
});
}
// PUT請求
async put(url, data = {}, config = {}) {
return this.request({
method: 'PUT',
url: this.buildUrl(url),
data,
...config
});
}
// DELETE請求
async delete(url, config = {}) {
return this.request({
method: 'DELETE',
url: this.buildUrl(url),
...config
});
}
// 構建完整URL
buildUrl(path) {
return `${this.baseUrl}${path}`;
}
// 錯誤處理
handleError(error) {
if (error.response) {
// 服務(wù)器返回錯誤
return new Error(`服務(wù)器錯誤: ${error.response.status}`);
} else if (error.request) {
// 網(wǎng)絡(luò )錯誤
return new Error('網(wǎng)絡(luò )連接失敗');
} else {
// 其他錯誤
return error;
}
}
}
// 報關(guān)單服務(wù)類(lèi)
class CkgdService extends ApiService {
constructor() {
super(allUrl.systemUrl);
}
// 獲取報關(guān)單列表
async getCkgdList(params = {}) {
return this.post('tms/gg/jk/ckfpCkgd/list.do', {
header: allUrl.header,
condition: params
});
}
// 獲取報關(guān)單詳情
async getCkgdDetail(entryId) {
return this.post('tms/gg/jk/ckfpCkgd/relDatails.do', {
header: allUrl.header,
condition: { entryId }
});
}
// 更新報關(guān)單
async updateCkgd(data) {
return this.post('tms/gg/jk/ckfpCkgd/update.do', {
header: allUrl.header,
body: data
});
}
// 獲取商品列表
async getGoodsList(entryId) {
return this.post('tms/gg/jk/ckfpCkgd/goodsList.do', {
header: allUrl.header,
condition: { entryId }
});
}
// 獲取附件列表
async getAttachments(entryId) {
return this.post('tms/gg/jk/ckfpCkgd/attachmentList.do', {
header: allUrl.header,
condition: { entryId }
});
}
// 數據檢查
async checkData(entryId) {
return this.post('tms/gg/jk/ckfpCkgd/checkData.do', {
header: allUrl.header,
condition: { entryId }
});
}
// 生成退稅數據
async generateTaxRefund(entryId) {
return this.post('tms/gg/jk/ckfpCkgd/genTaxrefund.do', {
header: allUrl.header,
condition: { entryId }
});
}
}
這些類(lèi)函數開(kāi)發(fā)模式為應用提供了清晰的代碼組織和強大的功能封裝,支持代碼復用和維護。