总部后端,开发计划-任务列表-来源工单支持链接 总部端-开发计划-任务列表-编辑任务-增加“开发中”状态 账单日期修正
This commit is contained in:
@@ -220,6 +220,10 @@ body.admin-col-resizing * {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.admin-primary-link {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.admin-primary-link:hover {
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
@@ -46,6 +47,7 @@ const STATUS_OPTIONS = (Object.keys(DEV_PLAN_TASK_STATUS_LABELS) as DevPlanTaskS
|
||||
|
||||
const STATUS_COLOR: Record<DevPlanTaskStatusDto, string> = {
|
||||
TODO: 'default',
|
||||
IN_PROGRESS: 'orange',
|
||||
DEVELOPED: 'blue',
|
||||
RELEASED: 'green',
|
||||
};
|
||||
@@ -289,7 +291,19 @@ export default function DevPlanTasksPage() {
|
||||
'—'
|
||||
),
|
||||
},
|
||||
{ title: '来源工单', dataIndex: 'supportTicketNo', width: 140, render: (v) => v || '—' },
|
||||
{
|
||||
title: '来源工单',
|
||||
dataIndex: 'supportTicketNo',
|
||||
width: 140,
|
||||
render: (v, row) =>
|
||||
row.supportTicketId && v ? (
|
||||
<Link className="admin-primary-link" to={`/tickets/support?id=${row.supportTicketId}`}>
|
||||
{v}
|
||||
</Link>
|
||||
) : (
|
||||
v || '—'
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '关联版本',
|
||||
dataIndex: 'versions',
|
||||
@@ -377,7 +391,7 @@ export default function DevPlanTasksPage() {
|
||||
<Select allowClear style={{ width: 100 }} options={TYPE_OPTIONS} />
|
||||
</Form.Item>
|
||||
<Form.Item name="status" label="状态">
|
||||
<Select allowClear style={{ width: 100 }} options={STATUS_OPTIONS} />
|
||||
<Select allowClear style={{ width: 110 }} options={STATUS_OPTIONS} />
|
||||
</Form.Item>
|
||||
<Form.Item name="keyword" label="关键词">
|
||||
<Input allowClear placeholder="任务号/内容" style={{ width: 160 }} />
|
||||
|
||||
@@ -282,7 +282,7 @@ export default function PartnerBillsPage() {
|
||||
title: '账期',
|
||||
width: 200,
|
||||
render: (_, r) =>
|
||||
`${fmtTime(r.periodStart).slice(0, 10)} ~ ${fmtTime(r.periodEnd).slice(0, 10)}`,
|
||||
`${String(r.periodStart || '').slice(0, 10)} ~ ${String(r.periodEnd || '').slice(0, 10)}`,
|
||||
},
|
||||
{
|
||||
title: '酒单佣金',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
} from '@ant-design/icons';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import {
|
||||
DEV_PLAN_TASK_STATUS_LABELS,
|
||||
DEV_PLAN_TASK_TYPE_LABELS,
|
||||
SUPPORT_TICKET_STATUS_LABELS,
|
||||
SUPPORT_TICKET_TYPE_LABELS,
|
||||
@@ -89,6 +91,8 @@ const TASK_TYPE_OPTIONS = (Object.keys(DEV_PLAN_TASK_TYPE_LABELS) as DevPlanTask
|
||||
type TicketRow = SupportTicketDto & { linkedTasks?: SupportTicketLinkedTaskDto[] };
|
||||
|
||||
export default function SupportTicketsPage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const deepLinkId = searchParams.get('id')?.trim() || searchParams.get('ticketId')?.trim() || '';
|
||||
const [profile, setProfile] = useState<HqProfile | null>(null);
|
||||
const [filters, setFilters] = useState<Record<string, string>>({});
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
|
||||
@@ -162,6 +166,11 @@ export default function SupportTicketsPage() {
|
||||
setDrawerOpen(true);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!deepLinkId) return;
|
||||
void openDetail(deepLinkId).catch(() => message.error('工单不存在或已删除'));
|
||||
}, [deepLinkId]);
|
||||
|
||||
async function submitCreate() {
|
||||
const values = await createForm.validateFields();
|
||||
setCreating(true);
|
||||
@@ -914,7 +923,9 @@ export default function SupportTicketsPage() {
|
||||
>
|
||||
{t.content}
|
||||
</Typography.Text>
|
||||
<Tag style={{ margin: 0, flexShrink: 0 }}>{t.status}</Tag>
|
||||
<Tag style={{ margin: 0, flexShrink: 0 }}>
|
||||
{DEV_PLAN_TASK_STATUS_LABELS[t.status] ?? t.status}
|
||||
</Tag>
|
||||
</div>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Statistic,
|
||||
Table,
|
||||
Tag,
|
||||
Tooltip,
|
||||
Typography,
|
||||
message,
|
||||
} from 'antd';
|
||||
@@ -249,7 +250,11 @@ export default function WineryBillsPage() {
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '账单日',
|
||||
title: (
|
||||
<Tooltip title="出账当天的北京日历日;T+3 只决定纳入哪天完成的订单">
|
||||
账单日
|
||||
</Tooltip>
|
||||
),
|
||||
dataIndex: 'billDate',
|
||||
width: 110,
|
||||
render: (v) => String(v || '').slice(0, 10),
|
||||
|
||||
@@ -83,7 +83,7 @@ function formatBenefitCorner(p: Product): string {
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
const [showSplash, setShowSplash] = useState(() => !hasHomeSplashPlayed());
|
||||
const [showSplash, setShowSplash] = useState(() => false); // !hasHomeSplashPlayed()
|
||||
const [activeAroma, setActiveAroma] = useState<AromaKey>('QINGXIANG');
|
||||
const [products, setProducts] = useState<Product[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -35,8 +35,15 @@ import {
|
||||
toWeappShareTimeline,
|
||||
} from '../../lib/wechat-share';
|
||||
import iconHome from '../../assets/tabbar/home.png';
|
||||
import iconStoreBenefit from '../../assets/icons/store-benefit-y.png';
|
||||
import { usePageView } from '../../lib/usePageView';
|
||||
|
||||
/** 封面斜角权益额:SKU benefitAmount ?? 商品 benefitDisplay ?? 售价 */
|
||||
function formatBenefitCorner(amount: number): string {
|
||||
if (!Number.isFinite(amount) || amount <= 0) return '';
|
||||
return String(Math.round(amount));
|
||||
}
|
||||
|
||||
type Product = ProductImageSource & {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -157,6 +164,14 @@ export default function ProductDetailPage() {
|
||||
}, [product, specEnabled, skus, selected, attrs]);
|
||||
|
||||
const displayPrice = activeSku ? Number(activeSku.price) : Number(product?.price ?? 0);
|
||||
const benefitCorner = formatBenefitCorner(
|
||||
Number(
|
||||
activeSku?.benefitAmount ??
|
||||
product?.benefitDisplay ??
|
||||
product?.benefitAmount ??
|
||||
displayPrice,
|
||||
),
|
||||
);
|
||||
const fulfillment = activeSku
|
||||
? {
|
||||
allowOnlinePurchase: activeSku.allowOnlinePurchase,
|
||||
@@ -271,6 +286,20 @@ export default function ProductDetailPage() {
|
||||
<View className="product-detail-main">
|
||||
<View className="product-detail-hero full-bleed">
|
||||
<ProductCarousel images={carouselImages} alt={product.name} variant="detail" previewable />
|
||||
{benefitCorner ? (
|
||||
<View className="product-detail-benefit-ribbon-clip">
|
||||
<View className="product-detail-benefit-ribbon">
|
||||
<View className="product-detail-benefit-ribbon-dk">
|
||||
<Image
|
||||
className="product-detail-benefit-ribbon-dk-icon"
|
||||
src={iconStoreBenefit}
|
||||
mode="aspectFit"
|
||||
/>
|
||||
</View>
|
||||
<Text className="product-detail-benefit-ribbon-num">{benefitCorner}</Text>
|
||||
</View>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
<View className="product-detail-info">
|
||||
@@ -288,6 +317,21 @@ export default function ProductDetailPage() {
|
||||
<Text className="product-detail-subtitle">{activeSku.specText}</Text>
|
||||
) : null}
|
||||
|
||||
{allowOnline || allowOnSite ? (
|
||||
<View className="product-detail-fulfill-tags">
|
||||
{allowOnline ? (
|
||||
<Text className="product-detail-fulfill-tag product-detail-fulfill-tag--local">
|
||||
同城订单24小时内送达
|
||||
</Text>
|
||||
) : null}
|
||||
{allowOnSite ? (
|
||||
<Text className="product-detail-fulfill-tag product-detail-fulfill-tag--pickup">
|
||||
支持现场取货
|
||||
</Text>
|
||||
) : null}
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{specEnabled ? (
|
||||
<View className="product-detail-specs">
|
||||
{attrs.map((attr) => (
|
||||
|
||||
@@ -8,9 +8,64 @@
|
||||
}
|
||||
|
||||
.product-detail-hero {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--color-card);
|
||||
}
|
||||
|
||||
.product-detail-benefit-ribbon-clip {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.product-detail-benefit-ribbon {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
left: -52px;
|
||||
width: 256px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
overflow: hidden;
|
||||
background: #8b1a20;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.product-detail-benefit-ribbon-dk {
|
||||
flex-shrink: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 1px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.product-detail-benefit-ribbon-dk-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.product-detail-benefit-ribbon-num {
|
||||
flex-shrink: 0;
|
||||
color: #dcb46f;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
line-height: 48px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.detail-carousel-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@@ -129,7 +184,35 @@
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: var(--color-on-surface-variant);
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.product-detail-fulfill-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 8px 0 16px;
|
||||
}
|
||||
|
||||
.product-detail-fulfill-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 3px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.product-detail-fulfill-tag--local {
|
||||
background: #f5d56a;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.product-detail-fulfill-tag--pickup {
|
||||
background: #f8e4e4;
|
||||
color: #a61d24;
|
||||
}
|
||||
|
||||
.product-detail-promo {
|
||||
|
||||
Reference in New Issue
Block a user