feat: 物品规则页左右布局,接单平台统计条精简

- 物品规则改为左右布局:左侧编辑/新建表单(加宽、一屏展示无滚动条),右侧可滚动规则列表
- 列表顶部新增搜索(规则标识/商品/SKU/店铺),点击行快速载入编辑,当前行高亮
- 接单平台顶部统计改为单行紧凑统计条,减少页面高度
This commit is contained in:
yml2213
2026-08-15 11:28:52 +08:00
parent 1131780186
commit d44c6039ea
3 changed files with 414 additions and 300 deletions
@@ -21,7 +21,6 @@ import {
Modal, Modal,
Select, Select,
Space, Space,
Statistic,
Switch, Switch,
Table, Table,
Tabs, Tabs,
@@ -141,26 +140,23 @@ function SummaryCards() {
}) })
const summary = summaryQuery.data?.data const summary = summaryQuery.data?.data
const items = [
{ label: '待审核打手', value: summary?.pendingWorkerCount || 0 },
{ label: '待完善订单', value: summary?.pendingMaterialCount || 0 },
{ label: '大厅订单', value: summary?.openOrderCount || 0 },
{ label: '代练中', value: summary?.inProgressOrderCount || 0 },
]
return ( return (
<div className="metric-grid four"> <Card size="small" bordered={false} className="platform-summary-strip-card">
<Card> <Space size={32} wrap>
<Statistic {items.map((item) => (
title="待审核打手" <span key={item.label} className="platform-summary-strip-item">
value={summary?.pendingWorkerCount || 0} {item.label}
/> <strong>{item.value}</strong>
</span>
))}
</Space>
</Card> </Card>
<Card>
<Statistic
title="待完善订单"
value={summary?.pendingMaterialCount || 0}
/>
</Card>
<Card>
<Statistic title="大厅订单" value={summary?.openOrderCount || 0} />
</Card>
<Card>
<Statistic title="代练中" value={summary?.inProgressOrderCount || 0} />
</Card>
</div>
) )
} }
@@ -201,6 +201,21 @@ export default function ProductRulesPanel() {
} }
} }
const [keyword, setKeyword] = useState('')
const filteredRules = (rulesQuery.data?.data.items || []).filter((rule) => {
const keywordText = keyword.trim().toLowerCase()
if (!keywordText) return true
return [
rule.ruleKey,
rule.productName,
rule.skuCode,
rule.provider,
rule.shopId,
rule.categoryName,
].some((value) => String(value || '').toLowerCase().includes(keywordText))
})
function syncSharingRuleForm(next: { function syncSharingRuleForm(next: {
sharingTotalQuantity?: number sharingTotalQuantity?: number
sharingUnitReward?: number sharingUnitReward?: number
@@ -304,7 +319,7 @@ export default function ProductRulesPanel() {
width: 104, width: 104,
fixed: 'right', fixed: 'right',
render: (_, row) => ( render: (_, row) => (
<Space size={0}> <Space size={0} onClick={(event) => event.stopPropagation()}>
<Button <Button
type="text" type="text"
icon={<EditOutlined />} icon={<EditOutlined />}
@@ -335,16 +350,30 @@ export default function ProductRulesPanel() {
return ( return (
<section className="platform-panel-stack"> <section className="platform-panel-stack">
<div className="product-rules-layout">
<Card <Card
className="product-rules-form-card"
title={editingRule ? `编辑物品规则 · ${editingRule.ruleKey}` : '新建物品规则'} title={editingRule ? `编辑物品规则 · ${editingRule.ruleKey}` : '新建物品规则'}
extra={ extra={
editingRule ? ( <Space>
<Button onClick={resetRuleForm}></Button> {editingRule ? (
) : null <Button type="link" onClick={resetRuleForm}>
</Button>
) : null}
<Button
type="primary"
htmlType="submit"
form="product-rule-form"
>
{editingRule ? '保存修改' : '创建规则'}
</Button>
</Space>
} }
bordered={false} bordered={false}
> >
<Form <Form
id="product-rule-form"
form={form} form={form}
layout="vertical" layout="vertical"
className="worker-rule-form" className="worker-rule-form"
@@ -506,6 +535,26 @@ export default function ProductRulesPanel() {
> >
<Switch /> <Switch />
</Form.Item> </Form.Item>
<Form.Item
label="默认任务时限"
name="timeoutMinutes"
tooltip="自动创建的工单继承该时限,打手抢单后开始计时;0 表示不限时"
>
<InputNumber min={0} step={5} addonAfter="分钟" />
</Form.Item>
<Form.Item
label="默认超时策略"
name="timeoutPolicy"
tooltip="reopen:释放押金退回大厅;cancel_release:取消退押金;cancel_deduct:取消扣押金"
>
<Select
options={[
{ value: 'reopen', label: '释放押金退回大厅' },
{ value: 'cancel_release', label: '取消订单并退还押金' },
{ value: 'cancel_deduct', label: '取消订单并扣除押金' },
]}
/>
</Form.Item>
</div> </div>
<Form.Item noStyle shouldUpdate> <Form.Item noStyle shouldUpdate>
{({ getFieldValue }) => {({ getFieldValue }) =>
@@ -570,40 +619,22 @@ export default function ProductRulesPanel() {
name="fieldsText" name="fieldsText"
extra="每行一个字段:key:名称,下拉项用 # 分隔(如 system:系统#安卓,苹果)" extra="每行一个字段:key:名称,下拉项用 # 分隔(如 system:系统#安卓,苹果)"
> >
<Input.TextArea rows={4} /> <Input.TextArea rows={2} />
</Form.Item> </Form.Item>
<Form.Item
label="默认任务时限"
name="timeoutMinutes"
tooltip="自动创建的工单继承该时限,打手抢单后开始计时;0 表示不限时"
>
<InputNumber min={0} step={5} addonAfter="分钟" />
</Form.Item>
<Form.Item
label="默认超时策略"
name="timeoutPolicy"
tooltip="reopen:释放押金退回大厅;cancel_release:取消退押金;cancel_deduct:取消扣押金"
>
<Select
style={{ width: 260 }}
options={[
{ value: 'reopen', label: '释放押金退回大厅' },
{ value: 'cancel_release', label: '取消订单并退还押金' },
{ value: 'cancel_deduct', label: '取消订单并扣除押金' },
]}
/>
</Form.Item>
<Space>
<Button type="primary" htmlType="submit">
{editingRule ? '保存修改' : '创建规则'}
</Button>
{!editingRule ? null : <Button onClick={resetRuleForm}></Button>}
</Space>
</Form> </Form>
</Card> </Card>
<Card <Card
className="product-rules-list-card"
title="物品规则" title="物品规则"
extra={ extra={
<Space>
<Input.Search
allowClear
placeholder="搜索规则标识/商品/SKU/店铺"
style={{ width: 240 }}
value={keyword}
onChange={(event) => setKeyword(event.target.value)}
/>
<Button <Button
icon={<ReloadOutlined />} icon={<ReloadOutlined />}
loading={rulesQuery.isFetching} loading={rulesQuery.isFetching}
@@ -611,18 +642,27 @@ export default function ProductRulesPanel() {
> >
</Button> </Button>
</Space>
} }
bordered={false} bordered={false}
> >
<Table<WorkProductRule> <Table<WorkProductRule>
rowKey="ruleId" rowKey="ruleId"
loading={rulesQuery.isLoading} loading={rulesQuery.isLoading}
dataSource={rulesQuery.data?.data.items || []} dataSource={filteredRules}
columns={columns} columns={columns}
pagination={false} pagination={false}
scroll={{ x: 1200 }} scroll={{ x: 1000, y: 'calc(100vh - 300px)' }}
rowClassName={(row) =>
editingRule?.ruleId === row.ruleId ? 'product-rule-row-active' : ''
}
onRow={(row) => ({
onClick: () => editRule(row),
title: '点击快速编辑',
})}
/> />
</Card> </Card>
</div>
</section> </section>
) )
} }
+79 -1
View File
@@ -1556,6 +1556,27 @@ select {
gap: 5px; gap: 5px;
} }
/* 接单平台顶部紧凑统计条 */
.platform-summary-strip-card {
width: 100%;
}
.platform-summary-strip-card .ant-card-body {
padding: 8px 16px !important;
}
.platform-summary-strip-item {
font-size: 13px;
color: rgba(0, 0, 0, 0.65);
white-space: nowrap;
}
.platform-summary-strip-item strong {
font-size: 16px;
margin-left: 6px;
color: rgba(0, 0, 0, 0.88);
}
.metric-card span, .metric-card span,
.metric-card small { .metric-card small {
color: #6b7280; color: #6b7280;
@@ -2373,9 +2394,66 @@ select {
width: 100%; width: 100%;
} }
/* 物品规则:左侧编辑表单 + 右侧可滚动列表 */
.product-rules-layout {
display: flex;
gap: 16px;
align-items: flex-start;
}
.product-rules-form-card {
width: 560px;
flex-shrink: 0;
}
/* 左侧表单一屏展示,不出现滚动条 */
.product-rules-form-card .ant-card-body {
overflow: visible;
}
.product-rules-form-card .worker-rule-form .ant-form-item {
margin-bottom: 14px;
}
.product-rules-form-card .worker-rule-form .ant-form-item-label {
padding-bottom: 2px;
}
.product-rules-form-card .worker-rule-form .ant-input-textarea textarea {
min-height: 56px !important;
}
.product-rules-list-card {
flex: 1;
min-width: 0;
}
.product-rules-list-card .ant-card-body {
max-height: calc(100vh - 150px);
overflow-y: auto;
}
.product-rules-list-card .ant-table-wrapper {
max-height: calc(100vh - 230px);
}
.product-rule-row-active > td {
background: #e6f4ff !important;
}
@media (max-width: 1024px) {
.product-rules-layout {
flex-direction: column;
}
.product-rules-form-card {
width: 100%;
}
}
.worker-rule-grid { .worker-rule-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 0 14px; gap: 0 14px;
} }