提交
This commit is contained in:
1 parent
b45ce2c32c
commit
a5210a6a9e
30 files changed
+11989
-5917
No files matched your search
@@ -358,6 +358,7 @@
|
||||
v-for="pick in selectedInvoicePicks"
|
||||
:key="pick.key"
|
||||
class="invoice-selected-card"
|
||||
:style="{ '--invoice-group-color': invoiceGroupColor(pick.invoiceId) }"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@@ -388,7 +389,7 @@
|
||||
</span>
|
||||
<div class="invoice-selected-card__footer">
|
||||
<span class="invoice-selected-card__amount">
|
||||
{{ formatMoneyYuan(pick.amount) }} 元
|
||||
整票 {{ formatMoneyYuan(pick.amount) }} 元
|
||||
</span>
|
||||
<el-icon
|
||||
class="invoice-selected-card__download"
|
||||
@@ -761,6 +762,25 @@ const walletBalance = ref(0)
|
||||
const editingId = ref<number | null>(null)
|
||||
const titleAutoLinked = ref(true)
|
||||
|
||||
/** 同一发票共用边框色(与 BxInvoiceSelectDialog / bx-mobile 一致) */
|
||||
const INVOICE_GROUP_COLORS = [
|
||||
'#0891b2',
|
||||
'#7c3aed',
|
||||
'#d97706',
|
||||
'#db2777',
|
||||
'#2563eb',
|
||||
'#059669',
|
||||
'#ea580c',
|
||||
'#4f46e5'
|
||||
]
|
||||
|
||||
function invoiceGroupColor(invoiceId: string | number) {
|
||||
const s = String(invoiceId || '')
|
||||
let hash = 0
|
||||
for (let i = 0; i < s.length; i++) hash = (hash * 31 + s.charCodeAt(i)) >>> 0
|
||||
return INVOICE_GROUP_COLORS[hash % INVOICE_GROUP_COLORS.length]
|
||||
}
|
||||
|
||||
/** 关联发票固定展示顺序:上传/创建时间从新到旧,同时间按附件 ID */
|
||||
function sortInvoicePicksByFixedOrder<T extends { createTime?: string; attachmentId?: string | number; id?: string | number; key?: string }>(
|
||||
items: T[]
|
||||
@@ -1384,7 +1404,7 @@ function viewDetailSummary({ columns, data }: { columns: any[]; data: any[] }) {
|
||||
.invoice-selected-card {
|
||||
position: relative;
|
||||
width: 96px;
|
||||
border: 1px solid var(--border, #d9e8e2);
|
||||
border: 2px solid var(--invoice-group-color, var(--border, #d9e8e2));
|
||||
border-radius: 6px;
|
||||
background: var(--surface, #fff);
|
||||
overflow: hidden;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
const detailDrawerRef = ref<InstanceType<typeof DetailDrawer>>()
|
||||
|
||||
function goBack() {
|
||||
router.push({ path: '/system/clue' })
|
||||
router.push({ path: '/system/temp/clue' })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -2236,7 +2236,7 @@ const handleViewCustomer = () => {
|
||||
/** 查看商机 */
|
||||
const handleViewOpportunity = () => {
|
||||
router.push({
|
||||
path: '/system/opportunity/detail',
|
||||
path: '/system/temp/opportunity/detail',
|
||||
query: { id: contract.value?.opportunityId }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
const opportunityId = ref<string>('')
|
||||
|
||||
function goBack() {
|
||||
router.push({ path: '/system/opportunity' })
|
||||
router.push({ path: '/system/temp/opportunity' })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1029,7 +1029,7 @@
|
||||
/** 切换视图模式 */
|
||||
const switchView = (mode: 'list' | 'kanban') => {
|
||||
if (mode === 'kanban') {
|
||||
router.push('/system/opportunity/kanban')
|
||||
router.push('/system/temp/opportunity/kanban')
|
||||
} else {
|
||||
viewMode.value = mode
|
||||
}
|
||||
@@ -1037,7 +1037,7 @@
|
||||
|
||||
/** 跳转到漏斗分析 */
|
||||
const goToFunnel = () => {
|
||||
router.push('/system/opportunity/funnel')
|
||||
router.push('/system/temp/opportunity/funnel')
|
||||
}
|
||||
|
||||
watchDebounced(
|
||||
|
||||
@@ -185,13 +185,13 @@ const resetQuery = () => {
|
||||
}
|
||||
|
||||
const handleViewDetail = (id: number) => {
|
||||
router.push({ path: '/system/opportunity/detail', query: { id } })
|
||||
router.push({ path: '/system/temp/opportunity/detail', query: { id } })
|
||||
}
|
||||
|
||||
const handleCardAction = (command: string, opp: OpportunityVO) => {
|
||||
switch (command) {
|
||||
case 'edit':
|
||||
router.push({ path: '/system/opportunity', query: { id: opp.id, action: 'edit' } })
|
||||
router.push({ path: '/system/temp/opportunity', query: { id: opp.id, action: 'edit' } })
|
||||
break
|
||||
case 'stage':
|
||||
changeStageDialogRef.value?.open(opp.id)
|
||||
|
||||
@@ -239,7 +239,7 @@ let winRateChart: echarts.ECharts | null = null
|
||||
let ownerChart: echarts.ECharts | null = null
|
||||
|
||||
const goBack = () => {
|
||||
router.push('/system/opportunity')
|
||||
router.push('/system/temp/opportunity')
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
|
||||
@@ -78,49 +78,62 @@
|
||||
<p v-else class="portal-home-empty">暂无收藏,可在各模块菜单卡片上点星标添加</p>
|
||||
</section>
|
||||
|
||||
<section v-else class="portal-home-block">
|
||||
<div class="portal-home-grid">
|
||||
<button
|
||||
v-for="card in activeCards"
|
||||
:key="card.path"
|
||||
type="button"
|
||||
class="portal-home-card"
|
||||
@click="openCard(card.path)"
|
||||
>
|
||||
<span
|
||||
v-if="pendingCountFor(card) > 0"
|
||||
class="portal-home-card__pending"
|
||||
:aria-label="`${pendingCountFor(card)} 条待审批`"
|
||||
>
|
||||
{{ formatPendingCount(pendingCountFor(card)) }}
|
||||
</span>
|
||||
<span
|
||||
class="portal-home-card__badge"
|
||||
:data-tone="toneIndex(activeModule)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{{ titleAbbr(card.title) }}
|
||||
</span>
|
||||
<span class="portal-home-card__body">
|
||||
<span class="portal-home-card__title">{{ card.title }}</span>
|
||||
<span class="portal-home-card__sub">{{ panelTitle }}</span>
|
||||
</span>
|
||||
<template v-else>
|
||||
<section
|
||||
v-for="(group, gIdx) in activeGroups"
|
||||
:key="group.groupPath || `flat-${gIdx}`"
|
||||
class="portal-home-block"
|
||||
:class="{ 'portal-home-block--flat': group.hideTitle }"
|
||||
>
|
||||
<div v-if="!group.hideTitle && group.groupTitle" class="portal-home-block__head">
|
||||
<h3 class="title-bar-heading">{{ group.groupTitle }}</h3>
|
||||
<span class="portal-home-block__tip">{{ group.cards.length }} 项</span>
|
||||
</div>
|
||||
<div class="portal-home-grid">
|
||||
<button
|
||||
v-for="card in group.cards"
|
||||
:key="card.path"
|
||||
type="button"
|
||||
class="portal-home-card__star"
|
||||
:class="{ 'is-on': favoritePathSet.has(card.path) }"
|
||||
:aria-label="favoritePathSet.has(card.path) ? '取消收藏' : '加入收藏'"
|
||||
@click.stop="onToggleStar(card.path)"
|
||||
class="portal-home-card"
|
||||
@click="openCard(card.path)"
|
||||
>
|
||||
<ElIcon>
|
||||
<StarFilled v-if="favoritePathSet.has(card.path)" />
|
||||
<Star v-else />
|
||||
</ElIcon>
|
||||
<span
|
||||
v-if="pendingCountFor(card) > 0"
|
||||
class="portal-home-card__pending"
|
||||
:aria-label="`${pendingCountFor(card)} 条待审批`"
|
||||
>
|
||||
{{ formatPendingCount(pendingCountFor(card)) }}
|
||||
</span>
|
||||
<span
|
||||
class="portal-home-card__badge"
|
||||
:data-tone="toneIndex(group.groupPath || activeModule)"
|
||||
aria-hidden="true"
|
||||
>
|
||||
{{ titleAbbr(card.title) }}
|
||||
</span>
|
||||
<span class="portal-home-card__body">
|
||||
<span class="portal-home-card__title">{{ card.title }}</span>
|
||||
<span class="portal-home-card__sub">{{
|
||||
group.hideTitle || !group.groupTitle ? panelTitle : group.groupTitle
|
||||
}}</span>
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
class="portal-home-card__star"
|
||||
:class="{ 'is-on': favoritePathSet.has(card.path) }"
|
||||
:aria-label="favoritePathSet.has(card.path) ? '取消收藏' : '加入收藏'"
|
||||
@click.stop="onToggleStar(card.path)"
|
||||
>
|
||||
<ElIcon>
|
||||
<StarFilled v-if="favoritePathSet.has(card.path)" />
|
||||
<Star v-else />
|
||||
</ElIcon>
|
||||
</button>
|
||||
</button>
|
||||
</button>
|
||||
</div>
|
||||
<p v-if="!activeCards.length" class="portal-home-empty">该模块暂无可用菜单</p>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
<p v-if="!activeGroups.length" class="portal-home-empty">该模块暂无可用菜单</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -190,19 +203,22 @@
|
||||
|
||||
const isFavView = computed(() => activeModule.value === FAV_KEY)
|
||||
|
||||
const activeCards = computed(() => {
|
||||
if (isFavView.value) return []
|
||||
const sec = modules.value.find((m) => m.modulePath === activeModule.value)
|
||||
return sec?.cards || []
|
||||
const activeSection = computed(() => {
|
||||
if (isFavView.value) return undefined
|
||||
return modules.value.find((m) => m.modulePath === activeModule.value)
|
||||
})
|
||||
|
||||
const activeGroups = computed(() => activeSection.value?.groups || [])
|
||||
|
||||
const activeCards = computed(() => activeSection.value?.cards || [])
|
||||
|
||||
const panelTitle = computed(() => {
|
||||
if (isFavView.value) return '收藏'
|
||||
return modules.value.find((m) => m.modulePath === activeModule.value)?.moduleTitle || ''
|
||||
return activeSection.value?.moduleTitle || ''
|
||||
})
|
||||
|
||||
const panelDesc = computed(() =>
|
||||
isFavView.value ? '可拖拽调整顺序,星标取消收藏' : '点击卡片进入功能,星标加入收藏'
|
||||
isFavView.value ? '可拖拽调整顺序,星标取消收藏' : '按二级菜单分组展示,点击卡片进入功能'
|
||||
)
|
||||
|
||||
const panelCount = computed(() =>
|
||||
@@ -217,6 +233,11 @@
|
||||
|
||||
const favSubTitle = (path: string) => {
|
||||
for (const sec of modules.value) {
|
||||
for (const group of sec.groups || []) {
|
||||
if (!group.cards.some((c) => c.path === path)) continue
|
||||
if (group.hideTitle || !group.groupTitle) return sec.moduleTitle
|
||||
return `${sec.moduleTitle} / ${group.groupTitle}`
|
||||
}
|
||||
if (sec.cards.some((c) => c.path === path)) return sec.moduleTitle
|
||||
}
|
||||
return '收藏入口'
|
||||
@@ -494,15 +515,23 @@
|
||||
}
|
||||
|
||||
.portal-home-block {
|
||||
margin: 0 18px 18px;
|
||||
margin: 14px 18px 8px;
|
||||
|
||||
&:last-child {
|
||||
&:last-of-type {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
&--fav {
|
||||
margin-top: 14px;
|
||||
}
|
||||
|
||||
&--flat {
|
||||
margin-top: 14px;
|
||||
|
||||
.portal-home-grid {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.portal-home-block__head {
|
||||
@@ -510,11 +539,13 @@
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.portal-home-block__tip {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
font-weight: 500;
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--mint-text-muted, #94a3b8);
|
||||
}
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@
|
||||
|
||||
// 返回列表
|
||||
const goBack = () => {
|
||||
router.push('/system/user')
|
||||
router.push('/system/info/user')
|
||||
}
|
||||
|
||||
// 加载数据
|
||||
|
||||
Reference in new issue
Block a user