添加系统物流公司配置组件

This commit is contained in:
lxy 2025-01-21 13:39:56 +08:00
parent 2db3698e3c
commit e6c2b44822
15 changed files with 746 additions and 0 deletions

View File

@ -0,0 +1,6 @@
import { EntityDict } from "../../../oak-app-domain";
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<EntityDict, "shipCompanySystem", true, {
addOpen: boolean;
setAddOpen: (newAddOpen: boolean) => void;
}>) => React.ReactElement;
export default _default;

View File

@ -0,0 +1,162 @@
import { isEqual } from "oak-domain/lib/utils/lodash";
export default OakComponent({
entity: 'shipCompanySystem',
isList: true,
actions: ['create', 'remove'],
projection: {
id: 1,
systemId: 1,
shipCompanyId: 1,
shipCompany: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
},
formData({ data, legalActions }) {
const canCreate = legalActions?.includes('create');
return {
systemShipCompanies: data,
canCreate,
};
},
filters: [
{
filter() {
const systemId = this.features.application.getApplication()?.systemId;
return {
systemId,
};
}
}
],
sorters: [
{
sorter: {
$attr: {
$$createAt$$: 1,
},
$direction: 'desc',
}
}
],
getTotal: 100,
features: ['application'],
properties: {
addOpen: false,
setAddOpen: (newAddOpen) => undefined,
},
data: {
allShipCompanies: [],
shipCompanyOptions: [],
searchLoading: false,
},
lifetimes: {
async ready() {
await this.refreshShipCompanies();
}
},
listeners: {
async systemShipCompanies(prev, next) {
if (!this.arraysAreEqual(prev.systemShipCompanies, next.systemShipCompanies) && next.systemShipCompanies) {
await this.refreshShipCompanies();
}
}
},
methods: {
async refreshShipCompanies() {
const { systemShipCompanies } = this.state;
const { data: shipCompanys } = await this.features.cache.refresh('shipCompany', {
data: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
}, {});
const allShipCompanies = shipCompanys;
const systemShipCompanyIds = systemShipCompanies?.map((ele) => ele?.shipCompanyId) || [];
const shipCompanyOptions = systemShipCompanyIds && systemShipCompanyIds?.length > 0 ? allShipCompanies.filter((ele) => !systemShipCompanyIds.includes(ele.id)) : allShipCompanies;
this.setState({
allShipCompanies,
shipCompanyOptions,
});
},
async myAddItems(shipCompanyIds) {
const systemId = this.features.application.getApplication()?.systemId;
const addItemsData = shipCompanyIds?.map((ele) => ({
shipCompanyId: ele,
systemId,
}));
this.addItems(addItemsData);
await this.execute();
const { shipCompanyOptions } = this.state;
const newShipCompanyOptions = shipCompanyOptions.filter((ele) => !shipCompanyIds.includes(ele.id));
this.setState({
shipCompanyOptions: newShipCompanyOptions,
});
},
searchShipCompany(searchValue) {
this.setState({
searchLoading: true,
});
const { shipCompanyOptions, systemShipCompanies, allShipCompanies } = this.state;
const systemShipCompanyIds = systemShipCompanies?.map((ele) => ele.shipCompanyId);
let newShipCompanyOptions = shipCompanyOptions;
if (searchValue.trim() !== '') {
const shipCompaies = this.features.cache.get('shipCompany', {
data: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
filter: {
$or: [
{
name: {
$includes: searchValue.trim(),
}
},
{
abbr: {
$includes: searchValue.trim(),
}
}
]
}
}, {});
if (systemShipCompanyIds && systemShipCompanyIds.length > 0) {
newShipCompanyOptions = shipCompaies.filter((ele) => !systemShipCompanyIds.includes(ele.id));
}
else {
newShipCompanyOptions = shipCompaies;
}
}
else {
if (systemShipCompanyIds && systemShipCompanyIds.length > 0) {
newShipCompanyOptions = allShipCompanies.filter((ele) => !systemShipCompanyIds.includes(ele.id));
}
else {
newShipCompanyOptions = allShipCompanies;
}
}
this.setState({
shipCompanyOptions: newShipCompanyOptions,
searchLoading: false,
});
},
arraysAreEqual(first, second) {
if (first?.length !== second?.length) {
return false;
}
for (let i = 0; i < first?.length; ++i) {
if (!isEqual(first[i], second[i])) {
return false;
}
}
return true;
},
},
});

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,14 @@
import React from 'react';
import { EntityDict } from "../../../oak-app-domain";
import { RowWithActions, WebComponentProps } from "oak-frontend-base";
export default function render(props: WebComponentProps<EntityDict, 'shipCompanySystem', false, {
systemShipCompanies: RowWithActions<EntityDict, 'shipCompanySystem'>[];
shipCompanyOptions: EntityDict['shipCompany']['Schema'][];
canCreate: boolean;
searchLoading: boolean;
addOpen: boolean;
setAddOpen: (newAddOpen: boolean) => void;
}, {
myAddItems: (shipCompanyIds: string[]) => Promise<void>;
searchShipCompany: (searchValue: string) => void;
}>): React.JSX.Element;

View File

@ -0,0 +1,149 @@
import React, { useState } from 'react';
import { FilterPanel } from '../../../components/AbstractComponents';
import ListPro from 'oak-frontend-base/es/components/listPro';
import { Modal, Table, Button, Input } from 'antd';
import Styles from './web.pc.module.less';
import { pull } from 'oak-domain/lib/utils/lodash';
export default function render(props) {
const { systemShipCompanies, shipCompanyOptions, canCreate, addOpen, setAddOpen, oakFullpath, oakEntity, oakLoading, oakExecuting, searchLoading, } = props.data;
const { t, clean, setMessage, myAddItems, searchShipCompany, removeItem, execute } = props.methods;
// const [addOpen, setAddOpen] = useState(false);
const [selectedIds, setSelectedIds] = useState([]);
const [searchValue, setSearcheValue] = useState('');
const filerColumns = [
{
attr: 'shipCompany.name',
op: '$includes',
transformFilter: (column, value) => {
return {
shipCompany: {
name: {
$includes: value
}
}
};
},
colSpan: 2
}
];
const shipCompanyColumns = [
{
path: 'name',
dataIndex: 'name',
title: t('shipCompany:attr.name'),
},
{
path: 'abbr',
dataIndex: 'abbr',
title: t('shipCompany:attr.abbr'),
},
Table.SELECTION_COLUMN,
];
return (<>
<FilterPanel oakPath={oakFullpath} entity={oakEntity} columns={filerColumns}/>
{systemShipCompanies && <ListPro data={systemShipCompanies} entity={oakEntity} attributes={[
{
path: 'shipCompany.name',
label: t('shipCompany:attr.name'),
},
{
path: 'shipCompany.abbr',
label: t('shipCompany:attr.abbr'),
},
]}
// buttonGroup={[
// {
// label: t('common::action.add'),
// show: canCreate,
// type: 'primary',
// onClick: () => {
// setAddOpen(true);
// }
// }
// ]}
onAction={async (row, action) => {
if (action === 'remove') {
removeItem(row.id);
await execute();
}
}} oakPath={oakFullpath}/>}
<Modal title={'物流公司'} width={800} destroyOnClose maskClosable={false} open={addOpen} onCancel={() => {
clean();
setSelectedIds([]);
setAddOpen(false);
}} footer={() => (<>
<Button onClick={() => {
clean();
setSelectedIds([]);
setAddOpen(false);
}}>
取消
</Button>
<Button type="primary" disabled={oakLoading || oakExecuting || !(selectedIds && selectedIds.length > 0)} onClick={async () => {
await myAddItems(selectedIds);
setSelectedIds([]);
setAddOpen(false);
}}>
添加
</Button>
</>)}>
<>
<div className={Styles.searchBox}>
<Input placeholder='请输入名称或缩写' value={searchValue} allowClear={true} onChange={(e) => {
if (e.target.value.trim() === '') {
setSearcheValue('');
searchShipCompany('');
}
else {
setSearcheValue(e.target.value.trim());
}
}} onPressEnter={() => {
if (searchValue !== '') {
searchShipCompany(searchValue);
}
else {
setMessage({
type: 'warning',
content: '请输入物流公司的名称或缩写',
});
}
}}/>
<Button type='primary' onClick={() => {
if (searchValue !== '') {
searchShipCompany(searchValue);
}
else {
setMessage({
type: 'warning',
content: '请输入物流公司的名称或缩写',
});
}
}}>
搜索
</Button>
</div>
{shipCompanyOptions &&
<Table columns={shipCompanyColumns} dataSource={shipCompanyOptions} rowKey={(record) => { return record.id; }} loading={oakLoading || searchLoading} rowSelection={{
selectedRowKeys: selectedIds,
onChange: (selectedRowKeys) => {
setSelectedIds(selectedRowKeys);
},
}} onRow={(record) => {
return {
onClick: (event) => {
let newSelectedIds = [...selectedIds];
if (selectedIds.includes(record.id)) {
const newSelectedIds2 = pull(newSelectedIds, record.id);
setSelectedIds([...newSelectedIds2]);
}
else {
newSelectedIds.push(record.id);
setSelectedIds(newSelectedIds);
}
},
};
}} style={{ minHeight: 560 }}/>}
</>
</Modal>
</>);
}

View File

@ -0,0 +1,6 @@
.searchBox {
display: flex;
justify-content: space-between;
gap: 8px;
margin-bottom: 12px;
}

View File

@ -5,6 +5,7 @@ export const selectFreeEntities = [
'wpProduct',
'withdrawChannel',
'wpAccount',
'shipCompany',
];
export const updateFreeDict = {};
export default {

View File

@ -8,6 +8,7 @@ exports.selectFreeEntities = [
'wpProduct',
'withdrawChannel',
'wpAccount',
'shipCompany',
];
exports.updateFreeDict = {};
exports.default = {

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,164 @@
import { EntityDict } from "@project/oak-app-domain";
import { isEqual } from "oak-domain/lib/utils/lodash";
export default OakComponent({
entity: 'shipCompanySystem',
isList: true,
actions: ['create', 'remove'],
projection: {
id: 1,
systemId: 1,
shipCompanyId: 1,
shipCompany: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
},
formData({ data, legalActions }) {
const canCreate = legalActions?.includes('create');
return {
systemShipCompanies: data,
canCreate,
};
},
filters: [
{
filter() {
const systemId = this.features.application.getApplication()?.systemId;
return {
systemId,
};
}
}
],
sorters: [
{
sorter: {
$attr: {
$$createAt$$: 1,
},
$direction: 'desc',
}
}
],
getTotal: 100,
features: ['application'],
properties: {
addOpen: false, //控制添加modal的显示
setAddOpen: (newAddOpen: boolean) => undefined as void,
},
data: {
allShipCompanies: [] as EntityDict['shipCompany']['Schema'][],
shipCompanyOptions: [] as EntityDict['shipCompany']['Schema'][],
searchLoading: false,
},
lifetimes: {
async ready() {
await this.refreshShipCompanies();
}
},
listeners: {
async systemShipCompanies(prev, next) {
if (!this.arraysAreEqual(prev.systemShipCompanies, next.systemShipCompanies) && next.systemShipCompanies) {
await this.refreshShipCompanies();
}
}
},
methods: {
async refreshShipCompanies() {
const { systemShipCompanies } = this.state;
const { data: shipCompanys } = await this.features.cache.refresh('shipCompany', {
data: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
}, {});
const allShipCompanies = shipCompanys as EntityDict['shipCompany']['Schema'][];
const systemShipCompanyIds = systemShipCompanies?.map((ele) => ele?.shipCompanyId) || [];
const shipCompanyOptions = systemShipCompanyIds && systemShipCompanyIds?.length > 0 ? allShipCompanies.filter((ele) => !systemShipCompanyIds.includes(ele.id)) : allShipCompanies;
this.setState({
allShipCompanies,
shipCompanyOptions,
})
},
async myAddItems(shipCompanyIds: string[]) {
const systemId = this.features.application.getApplication()?.systemId;
const addItemsData = shipCompanyIds?.map((ele) => ({
shipCompanyId: ele,
systemId,
}))
this.addItems(addItemsData);
await this.execute();
const { shipCompanyOptions } = this.state;
const newShipCompanyOptions = shipCompanyOptions.filter((ele) => !shipCompanyIds.includes(ele.id));
this.setState({
shipCompanyOptions: newShipCompanyOptions,
})
},
searchShipCompany(searchValue: string) {
this.setState({
searchLoading: true,
})
const { shipCompanyOptions, systemShipCompanies, allShipCompanies } = this.state;
const systemShipCompanyIds = systemShipCompanies?.map((ele) => ele.shipCompanyId);
let newShipCompanyOptions = shipCompanyOptions;
if (searchValue.trim() !== '') {
const shipCompaies = this.features.cache.get('shipCompany', {
data: {
id: 1,
name: 1,
abbr: 1,
wechatMpName: 1,
},
filter: {
$or: [
{
name: {
$includes: searchValue.trim(),
}
},
{
abbr: {
$includes: searchValue.trim(),
}
}
]
}
}, {});
if (systemShipCompanyIds && systemShipCompanyIds.length > 0) {
newShipCompanyOptions = (shipCompaies as EntityDict['shipCompany']['Schema'][]).filter((ele) => !systemShipCompanyIds.includes(ele.id));
} else {
newShipCompanyOptions = shipCompaies as EntityDict['shipCompany']['Schema'][];
}
} else {
if (systemShipCompanyIds && systemShipCompanyIds.length > 0) {
newShipCompanyOptions = allShipCompanies.filter((ele) => !systemShipCompanyIds.includes(ele.id));
} else {
newShipCompanyOptions = allShipCompanies;
}
}
this.setState({
shipCompanyOptions: newShipCompanyOptions,
searchLoading: false,
})
},
arraysAreEqual(first: Object[], second: Object[]) {
if (first?.length !== second?.length) {
return false;
}
for (let i = 0; i < first?.length; ++i) {
if (!isEqual(first[i], second[i])) {
return false;
}
}
return true;
},
},
})

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1,6 @@
.searchBox {
display: flex;
justify-content: space-between;
gap: 8px;
margin-bottom: 12px;
}

View File

@ -0,0 +1,232 @@
import React, { useState } from 'react';
import { EntityDict } from "../../../oak-app-domain";
import { ColumnProps, RowWithActions, WebComponentProps } from "oak-frontend-base";
import { FilterPanel } from '../../../components/AbstractComponents';
import ListPro from 'oak-frontend-base/es/components/listPro';
import { Modal, Table, Button, Input } from 'antd';
import Styles from './web.pc.module.less';
import { pull, union } from 'oak-domain/lib/utils/lodash';
export default function render(props: WebComponentProps<EntityDict,
'shipCompanySystem',
false,
{
systemShipCompanies: RowWithActions<EntityDict, 'shipCompanySystem'>[];
shipCompanyOptions: EntityDict['shipCompany']['Schema'][];
canCreate: boolean;
searchLoading: boolean;
addOpen: boolean;
setAddOpen: (newAddOpen: boolean) => void;
},
{
myAddItems: (shipCompanyIds: string[]) => Promise<void>;
searchShipCompany: (searchValue: string) => void;
}
>) {
const { systemShipCompanies, shipCompanyOptions, canCreate, addOpen, setAddOpen, oakFullpath, oakEntity, oakLoading, oakExecuting, searchLoading, } = props.data;
const { t, clean, setMessage, myAddItems, searchShipCompany, removeItem, execute } = props.methods;
// const [addOpen, setAddOpen] = useState(false);
const [selectedIds, setSelectedIds] = useState<string[]>([]);
const [searchValue, setSearcheValue] = useState('');
const filerColumns: ColumnProps<EntityDict, 'shipCompanySystem'>[] = [
{
attr: 'shipCompany.name',
op: '$includes',
transformFilter: (column, value) => {
return {
shipCompany: {
name: {
$includes: value
}
}
} as EntityDict['shipCompanySystem']['Selection']['filter']
},
colSpan: 2
}
]
const shipCompanyColumns = [
{
path: 'name',
dataIndex: 'name',
title: t('shipCompany:attr.name'),
},
{
path: 'abbr',
dataIndex: 'abbr',
title: t('shipCompany:attr.abbr'),
},
Table.SELECTION_COLUMN,
]
return (
<>
<FilterPanel
oakPath={oakFullpath}
entity={oakEntity}
columns={filerColumns}
/>
{systemShipCompanies && <ListPro
data={systemShipCompanies}
entity={oakEntity}
attributes={[
{
path: 'shipCompany.name',
label: t('shipCompany:attr.name'),
},
{
path: 'shipCompany.abbr',
label: t('shipCompany:attr.abbr'),
},
]}
// buttonGroup={[
// {
// label: t('common::action.add'),
// show: canCreate,
// type: 'primary',
// onClick: () => {
// setAddOpen(true);
// }
// }
// ]}
onAction={async (row, action) => {
if (action === 'remove') {
removeItem(row.id!);
await execute();
}
}}
oakPath={oakFullpath}
/>}
<Modal
title={'物流公司'}
width={800}
destroyOnClose
maskClosable={false}
open={addOpen}
onCancel={() => {
clean();
setSelectedIds([]);
setAddOpen(false);
}}
footer={() => (
<>
<Button
onClick={() => {
clean();
setSearcheValue('');
searchShipCompany('');
setSelectedIds([]);
setAddOpen(false);
}}
>
</Button>
<Button
type="primary"
disabled={oakLoading || oakExecuting || !(selectedIds && selectedIds.length > 0)}
onClick={async () => {
await myAddItems(selectedIds);
setSearcheValue('');
searchShipCompany('');
setSelectedIds([]);
setAddOpen(false);
}}
>
</Button>
</>
)}
>
<>
<div className={Styles.searchBox}>
<Input
placeholder='请输入名称或缩写'
value={searchValue}
allowClear={true}
onChange={(e) => {
if (e.target.value.trim() === '') {
setSearcheValue('');
searchShipCompany('');
} else {
setSearcheValue(e.target.value.trim());
}
}}
onPressEnter={() => {
if (searchValue !== '') {
searchShipCompany(searchValue);
} else {
setMessage({
type: 'warning',
content: '请输入物流公司的名称或缩写',
})
}
}}
/>
<Button type='primary' onClick={() => {
if (searchValue !== '') {
searchShipCompany(searchValue);
} else {
setMessage({
type: 'warning',
content: '请输入物流公司的名称或缩写',
})
}
}}>
</Button>
</div>
{shipCompanyOptions &&
<Table
columns={shipCompanyColumns}
dataSource={shipCompanyOptions}
rowKey={(record) => { return record.id! }}
loading={oakLoading || searchLoading}
rowSelection={{
selectedRowKeys: selectedIds,
onSelect: (record, selected) => {
let newSelectedIds = [...selectedIds];
if (selected) {
newSelectedIds.push(record.id);
setSelectedIds(newSelectedIds);
} else {
const newSelectedIds2 = pull(newSelectedIds, record.id);
setSelectedIds([...newSelectedIds2]);
}
},
onSelectAll: (selected, selectedRows, changeRows) => {
const changeIds = changeRows.map((ele) => ele.id);
let newSelectedIds = [...selectedIds];
if (selected) {
newSelectedIds.push(...changeIds);
setSelectedIds(newSelectedIds);
} else {
const newSelectedIds2 = pull(newSelectedIds, ...changeIds);
setSelectedIds([...newSelectedIds2]);
}
}
}}
onRow={(record) => {
return {
onClick: (event) => {
let newSelectedIds = [...selectedIds];
if (selectedIds.includes(record.id)) {
const newSelectedIds2 = pull(newSelectedIds, record.id);
setSelectedIds([...newSelectedIds2]);
} else {
newSelectedIds.push(record.id);
setSelectedIds(newSelectedIds);
}
},
};
}}
style={{ minHeight: 560 }}
/>
}
</>
</Modal >
</>
);
}

View File

@ -10,6 +10,7 @@ export const selectFreeEntities = [
'wpProduct',
'withdrawChannel',
'wpAccount',
'shipCompany',
];
export const updateFreeDict: UpdateFreeDict<EntityDict> = {