feat: 物品规则页左右布局,接单平台统计条精简
- 物品规则改为左右布局:左侧编辑/新建表单(加宽、一屏展示无滚动条),右侧可滚动规则列表 - 列表顶部新增搜索(规则标识/商品/SKU/店铺),点击行快速载入编辑,当前行高亮 - 接单平台顶部统计改为单行紧凑统计条,减少页面高度
This commit is contained in:
@@ -21,7 +21,6 @@ import {
|
||||
Modal,
|
||||
Select,
|
||||
Space,
|
||||
Statistic,
|
||||
Switch,
|
||||
Table,
|
||||
Tabs,
|
||||
@@ -141,26 +140,23 @@ function SummaryCards() {
|
||||
})
|
||||
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 (
|
||||
<div className="metric-grid four">
|
||||
<Card>
|
||||
<Statistic
|
||||
title="待审核打手"
|
||||
value={summary?.pendingWorkerCount || 0}
|
||||
/>
|
||||
<Card size="small" bordered={false} className="platform-summary-strip-card">
|
||||
<Space size={32} wrap>
|
||||
{items.map((item) => (
|
||||
<span key={item.label} className="platform-summary-strip-item">
|
||||
{item.label}
|
||||
<strong>{item.value}</strong>
|
||||
</span>
|
||||
))}
|
||||
</Space>
|
||||
</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: {
|
||||
sharingTotalQuantity?: number
|
||||
sharingUnitReward?: number
|
||||
@@ -304,7 +319,7 @@ export default function ProductRulesPanel() {
|
||||
width: 104,
|
||||
fixed: 'right',
|
||||
render: (_, row) => (
|
||||
<Space size={0}>
|
||||
<Space size={0} onClick={(event) => event.stopPropagation()}>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<EditOutlined />}
|
||||
@@ -335,16 +350,30 @@ export default function ProductRulesPanel() {
|
||||
|
||||
return (
|
||||
<section className="platform-panel-stack">
|
||||
<div className="product-rules-layout">
|
||||
<Card
|
||||
className="product-rules-form-card"
|
||||
title={editingRule ? `编辑物品规则 · ${editingRule.ruleKey}` : '新建物品规则'}
|
||||
extra={
|
||||
editingRule ? (
|
||||
<Button onClick={resetRuleForm}>取消编辑</Button>
|
||||
) : null
|
||||
<Space>
|
||||
{editingRule ? (
|
||||
<Button type="link" onClick={resetRuleForm}>
|
||||
取消编辑
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
form="product-rule-form"
|
||||
>
|
||||
{editingRule ? '保存修改' : '创建规则'}
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
bordered={false}
|
||||
>
|
||||
<Form
|
||||
id="product-rule-form"
|
||||
form={form}
|
||||
layout="vertical"
|
||||
className="worker-rule-form"
|
||||
@@ -506,6 +535,26 @@ export default function ProductRulesPanel() {
|
||||
>
|
||||
<Switch />
|
||||
</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>
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{({ getFieldValue }) =>
|
||||
@@ -570,40 +619,22 @@ export default function ProductRulesPanel() {
|
||||
name="fieldsText"
|
||||
extra="每行一个字段:key:名称,下拉项用 # 分隔(如 system:系统#安卓,苹果)"
|
||||
>
|
||||
<Input.TextArea rows={4} />
|
||||
<Input.TextArea rows={2} />
|
||||
</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>
|
||||
</Card>
|
||||
<Card
|
||||
className="product-rules-list-card"
|
||||
title="物品规则"
|
||||
extra={
|
||||
<Space>
|
||||
<Input.Search
|
||||
allowClear
|
||||
placeholder="搜索规则标识/商品/SKU/店铺"
|
||||
style={{ width: 240 }}
|
||||
value={keyword}
|
||||
onChange={(event) => setKeyword(event.target.value)}
|
||||
/>
|
||||
<Button
|
||||
icon={<ReloadOutlined />}
|
||||
loading={rulesQuery.isFetching}
|
||||
@@ -611,18 +642,27 @@ export default function ProductRulesPanel() {
|
||||
>
|
||||
刷新
|
||||
</Button>
|
||||
</Space>
|
||||
}
|
||||
bordered={false}
|
||||
>
|
||||
<Table<WorkProductRule>
|
||||
rowKey="ruleId"
|
||||
loading={rulesQuery.isLoading}
|
||||
dataSource={rulesQuery.data?.data.items || []}
|
||||
dataSource={filteredRules}
|
||||
columns={columns}
|
||||
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>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1556,6 +1556,27 @@ select {
|
||||
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 small {
|
||||
color: #6b7280;
|
||||
@@ -2373,9 +2394,66 @@ select {
|
||||
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 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 0 14px;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user