diff --git a/admin/src/views/finance/account_cost/edit.vue b/admin/src/views/finance/account_cost/edit.vue index 990bc581..f13ee1d5 100644 --- a/admin/src/views/finance/account_cost/edit.vue +++ b/admin/src/views/finance/account_cost/edit.vue @@ -22,16 +22,26 @@ - + + + + {{ ch.channel_name }} + + + @@ -78,9 +88,9 @@ import type { FormInstance } from 'element-plus' import { accountCostAdd, accountCostDetail, accountCostEdit } from '@/api/finance' import Popup from '@/components/popup/index.vue' -interface MediaChannelOption { - code: string - name: string +interface MediaChannelGroup { + group_name: string + channels: { channel_code: string; channel_name: string }[] } interface DeptOption { @@ -90,7 +100,7 @@ interface DeptOption { } const props = defineProps<{ - mediaChannelOptions: MediaChannelOption[] + mediaChannelGroups: MediaChannelGroup[] deptOptions: DeptOption[] defaultMediaChannelCode: string }>() @@ -197,3 +207,21 @@ defineExpose({ getDetail, }) + + diff --git a/admin/src/views/finance/account_cost/index.vue b/admin/src/views/finance/account_cost/index.vue index 8a65f680..1c7f21d7 100644 --- a/admin/src/views/finance/account_cost/index.vue +++ b/admin/src/views/finance/account_cost/index.vue @@ -27,14 +27,25 @@ placeholder="筛选全部渠道" clearable filterable - class="w-[220px]" + class="account-cost-channel-select w-[220px]" > - + + + + + {{ ch.channel_name }} + + + @@ -117,7 +128,7 @@ (() => { +const mediaChannelOptionsFlat = computed(() => { const options = pager.extend.media_channel_options if (!Array.isArray(options)) return [] @@ -170,6 +186,26 @@ const mediaChannelOptions = computed(() => { })) }) +const mediaChannelGroups = computed(() => { + const groups = pager.extend.media_channel_groups + if (Array.isArray(groups) && groups.length > 0) { + return groups as MediaChannelGroup[] + } + const flat = mediaChannelOptionsFlat.value + if (!flat.length) { + return [] + } + return [ + { + group_name: '渠道', + channels: flat.map(item => ({ + channel_code: item.code, + channel_name: item.name, + })), + }, + ] +}) + const deptOptions = computed(() => { const options = pager.extend.dept_options return Array.isArray(options) ? options : [] @@ -213,3 +249,21 @@ const handleReset = () => { getLists() + + diff --git a/server/app/adminapi/lists/finance/AccountCostLists.php b/server/app/adminapi/lists/finance/AccountCostLists.php index 52b5fd1a..060ac6e9 100644 --- a/server/app/adminapi/lists/finance/AccountCostLists.php +++ b/server/app/adminapi/lists/finance/AccountCostLists.php @@ -68,6 +68,7 @@ class AccountCostLists extends BaseAdminDataLists implements ListsSearchInterfac 'total_amount' => round((float) $this->baseQuery()->sum('amount'), 2), 'days_count' => (int) $this->baseQuery()->distinct(true)->count('cost_date'), 'media_channel_options' => MediaChannelService::getOptions(), + 'media_channel_groups' => MediaChannelService::getOptionGroups(), 'dept_options' => DeptLogic::getAllData(), 'supports_dept_binding' => AccountCost::supportsDeptBinding(), 'default_media_channel_code' => MediaChannelService::getDefaultCode(), diff --git a/server/app/common/service/qywx/MediaChannelService.php b/server/app/common/service/qywx/MediaChannelService.php index f1da44e7..a4782c0a 100644 --- a/server/app/common/service/qywx/MediaChannelService.php +++ b/server/app/common/service/qywx/MediaChannelService.php @@ -11,6 +11,50 @@ use think\db\Query; class MediaChannelService { + /** + * 与业绩看板「渠道来源」相同的分组(按 source_group_name),不含客户数统计。 + * + * @return array + * }> + */ + public static function getOptionGroups(): array + { + $rows = QywxMediaChannel::where('status', 1) + ->field('channel_code, channel_name, source_group_name') + ->order('source_group_name asc, id asc') + ->select() + ->toArray(); + + if ($rows === []) { + return []; + } + + $groups = []; + foreach ($rows as $r) { + $g = (string) (($r['source_group_name'] ?? '') !== '' ? $r['source_group_name'] : '其它'); + $groups[$g] ??= ['group_name' => $g, 'channels' => []]; + $groups[$g]['channels'][] = [ + 'channel_code' => (string) ($r['channel_code'] ?? ''), + 'channel_name' => (string) ($r['channel_name'] ?? ''), + ]; + } + + $sortedGroups = array_values($groups); + usort($sortedGroups, static function (array $a, array $b): int { + $aMedia = mb_strpos($a['group_name'], '自媒体') !== false ? 0 : 1; + $bMedia = mb_strpos($b['group_name'], '自媒体') !== false ? 0 : 1; + if ($aMedia !== $bMedia) { + return $aMedia <=> $bMedia; + } + + return strcmp($a['group_name'], $b['group_name']); + }); + + return $sortedGroups; + } + /** * @return array */