feat(admin): gate user/order/city delete behind assignable HQ permissions
CI / verify (pull_request) Has been cancelled
CI / verify (pull_request) Has been cancelled
Add users_delete, orders_delete, cities_delete; default HQ (incl. super admin) has none until explicitly granted. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import {
|
||||
} from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { WAREHOUSE_MANAGER_LABELS, WarehouseManagerType } from '@dukang/shared-types';
|
||||
import { request, type Paginated } from '../lib/api';
|
||||
import { request, type HqProfile, type Paginated } from '../lib/api';
|
||||
import { parseProvinceCityCodes, type ParsedProvinceCity } from '../lib/china-region';
|
||||
import { ADMIN_OPTIONS_PAGE_SIZE, CITY_STATUS_LABELS, fmtTime } from '../lib/constants';
|
||||
import { useAdminList } from '../lib/useAdminList';
|
||||
@@ -122,6 +122,12 @@ export default function CitiesPage() {
|
||||
const [deleteTarget, setDeleteTarget] = useState<Row | null>(null);
|
||||
const [deletePreview, setDeletePreview] = useState<CityDeletePreview | null>(null);
|
||||
const [confirmName, setConfirmName] = useState('');
|
||||
const [profile, setProfile] = useState<HqProfile | null>(null);
|
||||
const canDeleteCities = (profile?.permissionKeys ?? []).includes('cities_delete');
|
||||
|
||||
useEffect(() => {
|
||||
request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
|
||||
}, []);
|
||||
|
||||
const loadPartners = useCallback(async (cityId: string) => {
|
||||
const res = await request<Paginated<PartnerOption>>(`/admin/partners?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}&cityId=${cityId}`);
|
||||
@@ -233,9 +239,11 @@ export default function CitiesPage() {
|
||||
<Button type="link" size="small" onClick={() => void openDetail(row)}>
|
||||
管理
|
||||
</Button>
|
||||
<Button type="link" size="small" danger onClick={() => void openDelete(row)}>
|
||||
删除
|
||||
</Button>
|
||||
{canDeleteCities ? (
|
||||
<Button type="link" size="small" danger onClick={() => void openDelete(row)}>
|
||||
删除
|
||||
</Button>
|
||||
) : null}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
@@ -356,24 +364,26 @@ export default function CitiesPage() {
|
||||
setDetail(refreshed);
|
||||
void reload();
|
||||
}}>保存</Button>
|
||||
<Button
|
||||
danger
|
||||
style={{ marginLeft: 8 }}
|
||||
onClick={() =>
|
||||
void openDelete({
|
||||
id: String(detail.id),
|
||||
code: String(detail.code),
|
||||
name: String(detail.name),
|
||||
province: String(detail.province),
|
||||
status: String(detail.status),
|
||||
storeCount: Number(detail.storeCount ?? 0),
|
||||
orderCount: Number(detail.orderCount ?? 0),
|
||||
createdAt: String(detail.createdAt ?? ''),
|
||||
})
|
||||
}
|
||||
>
|
||||
删除城市
|
||||
</Button>
|
||||
{canDeleteCities ? (
|
||||
<Button
|
||||
danger
|
||||
style={{ marginLeft: 8 }}
|
||||
onClick={() =>
|
||||
void openDelete({
|
||||
id: String(detail.id),
|
||||
code: String(detail.code),
|
||||
name: String(detail.name),
|
||||
province: String(detail.province),
|
||||
status: String(detail.status),
|
||||
storeCount: Number(detail.storeCount ?? 0),
|
||||
orderCount: Number(detail.orderCount ?? 0),
|
||||
createdAt: String(detail.createdAt ?? ''),
|
||||
})
|
||||
}
|
||||
>
|
||||
删除城市
|
||||
</Button>
|
||||
) : null}
|
||||
</Form>
|
||||
</>
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user