feat(ops): v4.0.7 HQ 活动图快链与勾选导出
HQ 指定一张活动图为勾选主合伙人合成 PNG/zip;城市合伙人页增加快链与单下/导出。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -30,7 +30,6 @@ import {
|
||||
PARTNER_STAFF_ROLE_LABELS,
|
||||
type PartnerPermissionKey,
|
||||
} from '@dukang/shared-types';
|
||||
import { request, type Paginated } from '../lib/api';
|
||||
import { omitNullFields } from '../lib/omit-null-fields';
|
||||
import { districtCodeLabel, formatDistrictLabels } from '../lib/china-region';
|
||||
import { ADMIN_OPTIONS_PAGE_SIZE, fmtTime } from '../lib/constants';
|
||||
@@ -38,9 +37,11 @@ import { useAdminList } from '../lib/useAdminList';
|
||||
import CityDistrictMultiSelect from '../components/CityDistrictMultiSelect';
|
||||
import PartnerSubAccountList, { type PartnerSubAccountRow } from '../components/PartnerSubAccountList';
|
||||
import PartnerAssocPanel from '../components/PartnerAssocPanel';
|
||||
import ActivityPosterDownloadModal from '../components/ActivityPosterDownloadModal';
|
||||
import { useAdminListColumns } from '../lib/useAdminListColumns';
|
||||
import { AdminListHeader } from '../components/AdminListHeader';
|
||||
import { AdminPrimaryLink } from '../components/AdminPrimaryLink';
|
||||
import { request, type HqProfile, type Paginated } from '../lib/api';
|
||||
|
||||
|
||||
type SubRow = PartnerSubAccountRow;
|
||||
@@ -159,6 +160,9 @@ export default function CityPartnersPage() {
|
||||
const [maxCommissionRate, setMaxCommissionRate] = useState(0.05);
|
||||
const [createMaxRate, setCreateMaxRate] = useState(0.05);
|
||||
const [createCityCode, setCreateCityCode] = useState<string | undefined>();
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
const [posterDownloadIds, setPosterDownloadIds] = useState<string[] | null>(null);
|
||||
const [canDownloadPosters, setCanDownloadPosters] = useState(false);
|
||||
|
||||
const loadCities = useCallback(async () => {
|
||||
const res = await request<Paginated<CityOption>>(`/admin/cities?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}`);
|
||||
@@ -169,6 +173,12 @@ export default function CityPartnersPage() {
|
||||
void loadCities();
|
||||
}, [loadCities]);
|
||||
|
||||
useEffect(() => {
|
||||
void request<HqProfile>('/admin/auth/me')
|
||||
.then((p) => setCanDownloadPosters((p.permissionKeys ?? []).includes('activity_posters')))
|
||||
.catch(() => setCanDownloadPosters(false));
|
||||
}, []);
|
||||
|
||||
const editCityCode = detail?.cityId
|
||||
? cities.find((c) => c.id === detail.cityId)?.code
|
||||
: undefined;
|
||||
@@ -373,17 +383,34 @@ export default function CityPartnersPage() {
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '活动图',
|
||||
width: 70,
|
||||
render: (_, row) => (
|
||||
<Link
|
||||
to={`/activity-posters?partnerId=${encodeURIComponent(row.id)}`}
|
||||
title={`为「${row.companyName || row.phone}」下载活动图`}
|
||||
>
|
||||
查看
|
||||
</Link>
|
||||
),
|
||||
},
|
||||
{ title: '子账号', dataIndex: 'accountCount', width: 70, render: (n) => Math.max(0, n - 1) },
|
||||
{ title: '创建', dataIndex: 'createdAt', width: 150, render: fmtTime },
|
||||
{
|
||||
title: '操作',
|
||||
width: 140,
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
render: (_, row) => (
|
||||
<Space size={0}>
|
||||
<Button type="link" size="small" onClick={() => void openPartner(row.id)}>
|
||||
管理
|
||||
</Button>
|
||||
{canDownloadPosters ? (
|
||||
<Button type="link" size="small" onClick={() => setPosterDownloadIds([row.id])}>
|
||||
下载活动图
|
||||
</Button>
|
||||
) : null}
|
||||
<Popconfirm
|
||||
title="确认删除该城市合伙人?"
|
||||
description="若有门店需先删除门店;账号下有订单或核销单将禁止删除。"
|
||||
@@ -410,7 +437,16 @@ export default function CityPartnersPage() {
|
||||
settings={settingsButton}
|
||||
actions={
|
||||
<>
|
||||
<Link to="/activity-posters">活动图</Link>
|
||||
<Link to="/users?assocPartnerAccountId=any">全部关联用户</Link>
|
||||
{canDownloadPosters ? (
|
||||
<Button
|
||||
disabled={!selectedRowKeys.length}
|
||||
onClick={() => setPosterDownloadIds(selectedRowKeys)}
|
||||
>
|
||||
导出活动图{selectedRowKeys.length ? `(${selectedRowKeys.length})` : ''}
|
||||
</Button>
|
||||
) : null}
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
@@ -498,6 +534,14 @@ export default function CityPartnersPage() {
|
||||
dataSource={toTableRows(data?.items ?? [])}
|
||||
scroll={{ x: 'max-content' }}
|
||||
childrenColumnName="__noTreeChildren__"
|
||||
rowSelection={
|
||||
canDownloadPosters
|
||||
? {
|
||||
selectedRowKeys,
|
||||
onChange: (keys) => setSelectedRowKeys(keys.map(String)),
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
expandable={{
|
||||
expandedRowRender: (record) => (
|
||||
<PartnerSubAccountList
|
||||
@@ -564,6 +608,21 @@ export default function CityPartnersPage() {
|
||||
{detail.assocUserCount ?? 0}
|
||||
</Link>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="活动图">
|
||||
<Space>
|
||||
<Link
|
||||
to={`/activity-posters?partnerId=${encodeURIComponent(detail.id)}`}
|
||||
title="查看活动图并下载该合伙人合成图"
|
||||
>
|
||||
查看
|
||||
</Link>
|
||||
{canDownloadPosters ? (
|
||||
<Button type="link" size="small" onClick={() => setPosterDownloadIds([detail.id])}>
|
||||
下载
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="管仓仓库" span={2}>
|
||||
{detail.managedWarehouseName ?? (
|
||||
<Typography.Text type="secondary">
|
||||
@@ -812,6 +871,12 @@ export default function CityPartnersPage() {
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
<ActivityPosterDownloadModal
|
||||
open={posterDownloadIds != null && posterDownloadIds.length > 0}
|
||||
partnerIds={posterDownloadIds ?? []}
|
||||
onClose={() => setPosterDownloadIds(null)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user