1.调试ai

This commit is contained in:
2026-04-01 08:59:38 +08:00
parent e762188322
commit cddd7a1a1b
9 changed files with 106 additions and 25 deletions

View File

@@ -110,7 +110,7 @@ export interface AiDailyReportSaveReqVO {
/** 执行表查询参数(季节 jijie、大类 dalei 等下拉选项) */ /** 执行表查询参数(季节 jijie、大类 dalei 等下拉选项) */
export interface ExecuteTableParams { export interface ExecuteTableParams {
reportId: number reportId: number
tableName: string // 表名jijie-季节归属dalei-大类 tableName: string // 表名jijie-季节归属dalei-大类kehu-客户pinpai 等
} }
/** 品类表现/品类诊断查询参数(与统一查询参数一致,存储过程 YDY_AI_GET_SPDP2 */ /** 品类表现/品类诊断查询参数(与统一查询参数一致,存储过程 YDY_AI_GET_SPDP2 */

View File

@@ -762,9 +762,21 @@ const remainingRouter: AppRouteRecordRaw[] = [
component: Layout, component: Layout,
name: 'Reports', name: 'Reports',
meta: { meta: {
hidden: true hidden: false,
title: '数据报表'
}, },
children: [ children: [
{
path: 'sales-daily',
name: 'SalesDailyAI',
meta: {
title: '销售日报',
icon: 'ep:calendar',
noCache: true,
hidden: false
},
component: () => import('@/views/ydoyun/report/salesdaily/index.vue')
},
{ {
path: 'lijun/category-diagnostic', path: 'lijun/category-diagnostic',
name: 'CategoryDiagnostic', name: 'CategoryDiagnostic',

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="middle-class-ranking-page"> <div ref="reportPageRootRef" class="middle-class-ranking-page">
<!-- 查询条件区域与报表页一致支持携带条件进入 --> <!-- 查询条件区域与报表页一致支持携带条件进入 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-header"> <div class="query-header">
@@ -162,7 +162,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue' import { ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ReportApi } from '@/api/ydoyun/report/reportpage' import { ReportApi } from '@/api/ydoyun/report/reportpage'
@@ -191,10 +191,16 @@ interface MiddleClassItem {
defineOptions({ name: 'MiddleClassRanking' }) defineOptions({ name: 'MiddleClassRanking' })
const route = useRoute() const route = useRoute()
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
const loading = ref(false) const loading = ref(false)
watch(loading, (v) => setPageLoading(v), { immediate: true }) watch(loading, (v) => setPageLoading(v), { immediate: true })
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
const dateRange = ref<[string, string] | null>([ const dateRange = ref<[string, string] | null>([
dayjs().subtract(6, 'day').format('YYYY-MM-DD'), dayjs().subtract(6, 'day').format('YYYY-MM-DD'),
dayjs().format('YYYY-MM-DD') dayjs().format('YYYY-MM-DD')
@@ -315,6 +321,10 @@ function formatNumber(n: number): string {
} }
onMounted(async () => { onMounted(async () => {
setPageModuleName('中类销售排名')
setPageModuleCode('MiddleClassRanking:main')
await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
applyQueryFromRoute() applyQueryFromRoute()
await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchStoreOptions()]) await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchStoreOptions()])
}) })

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="product-cards-page"> <div ref="reportPageRootRef" class="product-cards-page">
<!-- 查询条件区域与主页/详情页一致首行时间+快捷+查询/重置/更多条件其余折叠 --> <!-- 查询条件区域与主页/详情页一致首行时间+快捷+查询/重置/更多条件其余折叠 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-form"> <div class="query-form">
@@ -520,7 +520,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue' import { ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { Picture, Grid, List, Search } from '@element-plus/icons-vue' import { Picture, Grid, List, Search } from '@element-plus/icons-vue'
@@ -586,10 +586,16 @@ defineOptions({ name: 'ProductCardsPage' })
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
const loading = ref(false) const loading = ref(false)
watch(loading, (v) => setPageLoading(v), { immediate: true }) watch(loading, (v) => setPageLoading(v), { immediate: true })
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
const userStore = useUserStore() const userStore = useUserStore()
const username = computed(() => userStore.user?.username || '') const username = computed(() => userStore.user?.username || '')
@@ -1130,6 +1136,10 @@ async function fetchStoreOptions() {
} }
onMounted(async () => { onMounted(async () => {
setPageModuleName('产品卡片')
setPageModuleCode('ProductCards:main')
await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
applyQueryFromRoute() applyQueryFromRoute()
await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchLineOptions(), fetchStoreOptions()]) await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchLineOptions(), fetchStoreOptions()])
// 门店默认全选 // 门店默认全选

View File

@@ -213,7 +213,13 @@
</el-radio-group> </el-radio-group>
</div> </div>
<div class="view-toolbar-right"> <div class="view-toolbar-right">
<el-button link type="primary" size="small" @click="openPromptEdit"> <el-button
v-if="canEditAiModulePrompt"
link
type="primary"
size="small"
@click="openPromptEdit"
>
<Icon icon="ep:edit" /> 编辑提示词 <Icon icon="ep:edit" /> 编辑提示词
</el-button> </el-button>
</div> </div>
@@ -376,6 +382,7 @@
</el-card> </el-card>
<AiPromptEditDialog <AiPromptEditDialog
v-if="canEditAiModulePrompt"
v-model="promptEditVisible" v-model="promptEditVisible"
:module-key="SUPPLIER_PERFORMANCE_MODULE_KEY" :module-key="SUPPLIER_PERFORMANCE_MODULE_KEY"
module-name="供应商表现" module-name="供应商表现"
@@ -397,6 +404,7 @@ import { Icon } from '@/components/Icon'
import { ReportApi } from '@/api/ydoyun/report/reportpage' import { ReportApi } from '@/api/ydoyun/report/reportpage'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { useAiAssistant } from '@/components/AiAssistant/useAiAssistant' import { useAiAssistant } from '@/components/AiAssistant/useAiAssistant'
import { useAiModulePromptEditor } from '@/hooks/web/useAiModulePromptEditor'
import { AiModulePromptApi } from '@/api/ydoyun/aiModulePrompt' import { AiModulePromptApi } from '@/api/ydoyun/aiModulePrompt'
import AiPromptEditDialog from './AiPromptEditDialog.vue' import AiPromptEditDialog from './AiPromptEditDialog.vue'
@@ -414,6 +422,7 @@ const SUPPLIER_PERFORMANCE_MODULE_KEY = `${SUPPLIER_PERFORMANCE_COMPONENT}:main`
const REPORT_ID = 6 const REPORT_ID = 6
const route = useRoute() const route = useRoute()
const userStore = useUserStore() const userStore = useUserStore()
const { canEditAiModulePrompt } = useAiModulePromptEditor()
const { openWithScreenshot, setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = const { openWithScreenshot, setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } =
useAiAssistant() useAiAssistant()
const pageRootRef = ref<HTMLElement | null>(null) const pageRootRef = ref<HTMLElement | null>(null)
@@ -437,6 +446,7 @@ const promptMap = ref<Record<string, string>>({})
const promptEditVisible = ref(false) const promptEditVisible = ref(false)
const openPromptEdit = () => { const openPromptEdit = () => {
if (!canEditAiModulePrompt.value) return
promptEditVisible.value = true promptEditVisible.value = true
} }

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="supplier-ranking-page"> <div ref="reportPageRootRef" class="supplier-ranking-page">
<!-- 查询条件区域与报表页一致支持携带条件进入 --> <!-- 查询条件区域与报表页一致支持携带条件进入 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-header"> <div class="query-header">
@@ -168,7 +168,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue' import { ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { ReportApi } from '@/api/ydoyun/report/reportpage' import { ReportApi } from '@/api/ydoyun/report/reportpage'
@@ -196,10 +196,16 @@ interface SupplierContributionData {
defineOptions({ name: 'SupplierRanking' }) defineOptions({ name: 'SupplierRanking' })
const route = useRoute() const route = useRoute()
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
const loading = ref(false) const loading = ref(false)
watch(loading, (v) => setPageLoading(v), { immediate: true }) watch(loading, (v) => setPageLoading(v), { immediate: true })
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
const dateRange = ref<[string, string] | null>([ const dateRange = ref<[string, string] | null>([
dayjs().subtract(6, 'day').format('YYYY-MM-DD'), dayjs().subtract(6, 'day').format('YYYY-MM-DD'),
dayjs().format('YYYY-MM-DD') dayjs().format('YYYY-MM-DD')
@@ -328,6 +334,10 @@ function getRankClass(index: number): string {
} }
onMounted(async () => { onMounted(async () => {
setPageModuleName('供货商销售排行')
setPageModuleCode('SupplierRanking:main')
await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
applyQueryFromRoute() applyQueryFromRoute()
await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchStoreOptions()]) await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchStoreOptions()])
}) })

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="category-diagnostic-dashboard"> <div ref="reportPageRootRef" class="category-diagnostic-dashboard">
<!-- 查询条件区域与供应商详情页一致 --> <!-- 查询条件区域与供应商详情页一致 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-form"> <div class="query-form">
@@ -473,10 +473,16 @@ const getTimeRange = (range: string) => {
return { rq: start.format('YYYY-MM-DD'), rq2: end.format('YYYY-MM-DD') } return { rq: start.format('YYYY-MM-DD'), rq2: end.format('YYYY-MM-DD') }
} }
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
const loading = ref(false) const loading = ref(false)
watch(loading, (v) => setPageLoading(v), { immediate: true }) watch(loading, (v) => setPageLoading(v), { immediate: true })
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
/** 展示形式:卡片 | 列表 */ /** 展示形式:卡片 | 列表 */
const displayMode = ref<'card' | 'table'>('card') const displayMode = ref<'card' | 'table'>('card')
const columns = ref<{ title: string; key: string; order?: number; labelKey?: string; colorKey?: string }[]>([]) const columns = ref<{ title: string; key: string; order?: number; labelKey?: string; colorKey?: string }[]>([])
@@ -938,7 +944,10 @@ const handleReset = () => {
// 初始化:从路由读取参数并查询 // 初始化:从路由读取参数并查询
onMounted(async () => { onMounted(async () => {
setPageModuleName('品类诊断')
setPageModuleCode('CategoryCardListComponents:main')
await nextTick() await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
initQueryParamsFromRoute() initQueryParamsFromRoute()
await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchLineOptions(), fetchStoreOptions()]) await Promise.all([fetchBrandOptions(), fetchSeasonOptions(), fetchCategoryOptions(), fetchLineOptions(), fetchStoreOptions()])
applyQueryDefaults() applyQueryDefaults()

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="product-detail-page"> <div ref="reportPageRootRef" class="product-detail-page">
<!-- 查询条件区域与主页一致 --> <!-- 查询条件区域与主页一致 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-form"> <div class="query-form">
@@ -434,7 +434,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue' import { computed, onMounted, onUnmounted, reactive, ref, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import dayjs from 'dayjs' import dayjs from 'dayjs'
@@ -450,10 +450,16 @@ const REPORT_ID = 6
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const userStore = useUserStore() const userStore = useUserStore()
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
const loading = ref(false) const loading = ref(false)
watch(loading, (v) => setPageLoading(v), { immediate: true }) watch(loading, (v) => setPageLoading(v), { immediate: true })
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
const productList = ref<ProductDetailData[]>([]) const productList = ref<ProductDetailData[]>([])
/** 标签分类筛选 */ /** 标签分类筛选 */
const labelFilter = ref<string>('all') const labelFilter = ref<string>('all')
@@ -1204,6 +1210,10 @@ function handleReset() {
// 初始化 // 初始化
onMounted(async () => { onMounted(async () => {
setPageModuleName('商品明细详情')
setPageModuleCode('ProductDetailPage:main')
await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
initQueryParamsFromRoute() initQueryParamsFromRoute()
await Promise.all([ await Promise.all([
fetchBrandOptions(), fetchBrandOptions(),

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="product-dashboard"> <div ref="reportPageRootRef" class="product-dashboard">
<!-- 查询条件区域 --> <!-- 查询条件区域 -->
<el-card class="query-card" shadow="never"> <el-card class="query-card" shadow="never">
<div class="query-form"> <div class="query-form">
@@ -1264,13 +1264,19 @@ const loadingPie = ref(false)
/** 商品明细列表加载状态 */ /** 商品明细列表加载状态 */
const loadingProductList = ref(false) const loadingProductList = ref(false)
const { setPageLoading } = useAiAssistant() const { setPageLoading, setPageModuleName, setPageModuleCode, setScreenshotTarget } = useAiAssistant()
const reportPageRootRef = ref<HTMLElement | null>(null)
watch( watch(
[loadingKpi, loadingCategory, loadingPie, loadingProductList], [loadingKpi, loadingCategory, loadingPie, loadingProductList],
([a, b, c, d]) => setPageLoading(!!(a || b || c || d)), ([a, b, c, d]) => setPageLoading(!!(a || b || c || d)),
{ immediate: true } { immediate: true }
) )
onUnmounted(() => setPageLoading(false)) onUnmounted(() => {
setPageModuleName(null)
setPageModuleCode(null)
setScreenshotTarget(null)
setPageLoading(false)
})
const searchKeyword = ref('') const searchKeyword = ref('')
const hoverDetail = ref<ProductDetailData | null>(null) const hoverDetail = ref<ProductDetailData | null>(null)
@@ -2630,6 +2636,10 @@ function applyQueryDefaults() {
} }
onMounted(async () => { onMounted(async () => {
setPageModuleName('商品驾驶舱')
setPageModuleCode('ProductDashboard:main')
await nextTick()
if (reportPageRootRef.value) setScreenshotTarget(reportPageRootRef.value)
activeTimeRange.value = 'week7' activeTimeRange.value = 'week7'
const timeRange = getTimeRange('week7') const timeRange = getTimeRange('week7')
queryParams.rq = timeRange.rq queryParams.rq = timeRange.rq