From 647eb065ec2890f278fa492b3a5411b90056e655 Mon Sep 17 00:00:00 2001 From: cuckooent Date: Mon, 14 Oct 2024 15:14:35 +0800 Subject: [PATCH] =?UTF-8?q?{"Message":"=E6=9B=B4=E6=96=B0=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E5=8F=B0","MessageType":2,"Modules":[{"State":1,"Type?= =?UTF-8?q?":1,"Name":"PCPage/=E5=B7=A5=E4=BD=9C=E5=8F=B0=E9=A6=96?= =?UTF-8?q?=E9=A1=B5"}],"Version":"v1"}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .collaboration | 12 +------ Pages/工作台/工作台首页.json | 65 ++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/.collaboration b/.collaboration index 86c5bf1a..03f7de7d 100644 --- a/.collaboration +++ b/.collaboration @@ -2282,17 +2282,7 @@ }, { "ModuleName": "PCPage/工作台首页", - "State": 1, - "LockedBy": { - "UserName": "cuckooent", - "Email": "phoben@qq.com" - }, - "LockDateTime": "2024-10-14T15:08:44.6875088+08:00", - "ModuleType": 1, - "ToRemoveFiles": [ - "Pages\\工作台\\工作台首页.json", - "Pages\\工作台\\工作台首页.rd" - ] + "ModuleType": 1 }, { "ModuleName": "PCPage/项目负荷 (2)", diff --git a/Pages/工作台/工作台首页.json b/Pages/工作台/工作台首页.json index 890f0b32..3465a8f6 100644 --- a/Pages/工作台/工作台首页.json +++ b/Pages/工作台/工作台首页.json @@ -348,13 +348,16 @@ ], "SqlCondition": { "$type": "ForguncyDataAccess.GeneralCESqlCondition, ForguncyDataAccess", - "CompareType": 2, + "CompareType": 3, "ColumnBindingInfo": { "TableName": "任务工时表", - "ColumnName": "ID", - "GUID": "402f4224-6093-478a-89b5-d0b583da473a" + "ColumnName": "工时日期", + "GUID": "6dd90d8a-2da5-49e3-802e-9598cd8ecb7d" }, - "Value": "0" + "Value": { + "$type": "Forguncy.Model.FormulaReferObject, ServerDesignerCommon", + "SerializeProperty": "=TODAY()-30" + } }, "NullFormulaValueQueryPolicy": 1, "OrderBySqlCondition": { @@ -375,7 +378,7 @@ ], "JSONDataSources": [], "ImageDataSource": [], - "Config": "{\"option\":\"let completeXAxisData = [];\\nlet completeYAxisData = []\\n\\n// 打印数据源以进行检查\\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]);\\n\\n// 拆分数据源\\nconst splitData = ForguncyEchartsHelper.splitDataSource(Context[\\\"工时表\\\"]);\\nconsole.log(\\\"拆分后的数据:\\\", splitData);\\n\\n// 使用正确的键名\\nconst { \\\"日期\\\": xData, \\\"总工时\\\": yAxisData } = splitData;\\nconsole.log(\\\"xData:\\\", xData);\\nconsole.log(\\\"yAxisData:\\\", yAxisData);\\n\\n// 生成完整的日期范围\\nfunction getDateRange(startDate, endDate) {\\n const dateList = [];\\n let currentDate = new Date(startDate);\\n\\n while (currentDate <= endDate) {\\n const year = currentDate.getFullYear();\\n const month = (\\\"0\\\" + (currentDate.getMonth() + 1)).slice(-2);\\n const day = (\\\"0\\\" + currentDate.getDate()).slice(-2);\\n\\n dateList.push(`${year}-${month}-${day}`);\\n\\n currentDate.setDate(currentDate.getDate() + 1);\\n }\\n return dateList;\\n}\\n\\n// 转换 Excel 日期数字为日期字符串\\nfunction getDateFormat(value) {\\n // 检查是否为数字类型\\n if (typeof value === \\\"number\\\") {\\n // Excel 日期格式的起始日期是 1899-12-30\\n const excelEpoch = new Date(Date.UTC(1899, 11, 30));\\n // 将整数日期转换为毫秒数\\n const date = new Date(\\n excelEpoch.getTime() + value * 24 * 60 * 60 * 1000,\\n );\\n const year = date.getUTCFullYear();\\n const month = (date.getUTCMonth() + 1).toString().padStart(2, \\\"0\\\");\\n const day = date.getUTCDate().toString().padStart(2, \\\"0\\\");\\n return `${year}-${month}-${day}`;\\n } else if (typeof value === \\\"string\\\") {\\n // 如果已经是字符串,则直接返回\\n return value;\\n } else {\\n // 其他情况返回空字符串\\n return \\\"\\\";\\n }\\n}\\n\\n// 检查 xData 和 yAxisData 是否存在并且是数组\\nif (Array.isArray(xData) && Array.isArray(yAxisData)) {\\n\\n // 批量处理日期\\n const xAxisData = xData.map((item) => getDateFormat(item));\\n\\n // 将日期字符串转换为 Date 对象\\n const dateObjects = xAxisData.map((dateStr) => new Date(dateStr));\\n\\n // 检查是否成功转换为有效的日期对象\\n if (dateObjects.some((date) => isNaN(date))) {\\n console.error(\\\"日期格式不正确,请检查日期数据。\\\");\\n return;\\n }\\n\\n // 获取最小和最大日期\\n const timestamps = dateObjects.map((date) => date.getTime());\\n const minTimestamp = Math.min(...timestamps);\\n const maxTimestamp = Math.max(...timestamps);\\n const minDate = new Date(minTimestamp);\\n const maxDate = new Date(maxTimestamp);\\n\\n // 生成完整的日期范围\\n const completeDateRange = getDateRange(minDate, maxDate);\\n\\n // 将原始数据映射为日期和值的键值对\\n const dataMap = {};\\n xAxisData.forEach((date, index) => {\\n dataMap[date] = yAxisData[index];\\n });\\n\\n // 补全缺失的数据\\n completeYAxisData = completeDateRange.map((date) => {\\n return dataMap[date] !== undefined ? dataMap[date] : 0;\\n });\\n\\n // 更新图表的数据\\n completeXAxisData = completeDateRange;\\n} else {\\n console.error(\\\"数据格式不正确,请检查数据源。\\\");\\n}\\n\\n// 配置 Echarts 图表\\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"报工趋势图\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n xAxis: {\\n type: \\\"category\\\",\\n data: completeXAxisData,\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n },\\n yAxis: {\\n type: \\\"value\\\",\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n splitLine: {\\n show: true,\\n lineStyle: {\\n color: \\\"#f8fafc\\\",\\n },\\n },\\n },\\n tooltip: {\\n trigger: \\\"axis\\\",\\n backgroundColor: \\\"#FFFFFF\\\",\\n textStyle: {\\n color: \\\"#000000\\\",\\n },\\n },\\n series: [\\n {\\n data: completeYAxisData,\\n type: \\\"line\\\",\\n lineStyle: {\\n width: 3,\\n shadowColor: \\\"rgba(0, 0, 0, 0.1)\\\",\\n shadowBlur: 10,\\n shadowOffsetX: 0,\\n shadowOffsetY: 4,\\n },\\n smooth: true,\\n symbolSize: 8,\\n symbol: \\\"none\\\",\\n itemStyle: {\\n color: \\\"#2196f3\\\",\\n },\\n areaStyle: {\\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\\n {\\n offset: 0,\\n color: \\\"rgba(33,150,243,0.3)\\\",\\n },\\n {\\n offset: 1,\\n color: \\\"rgba(33,150,243,0)\\\",\\n },\\n ]),\\n },\\n },\\n ],\\n};\\n\",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n let completeXAxisData = [];\\nlet completeYAxisData = [];\\n// 打印数据源以进行检查\\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]);\\n// 拆分数据源\\nconst splitData = ForguncyEchartsHelper.splitDataSource(Context[\\\"工时表\\\"]);\\nconsole.log(\\\"拆分后的数据:\\\", splitData);\\n// 使用正确的键名\\nconst { \\\"日期\\\": xData, \\\"总工时\\\": yAxisData } = splitData;\\nconsole.log(\\\"xData:\\\", xData);\\nconsole.log(\\\"yAxisData:\\\", yAxisData);\\n// 生成完整的日期范围\\nfunction getDateRange(startDate, endDate) {\\n const dateList = [];\\n let currentDate = new Date(startDate);\\n while (currentDate <= endDate) {\\n const year = currentDate.getFullYear();\\n const month = (\\\"0\\\" + (currentDate.getMonth() + 1)).slice(-2);\\n const day = (\\\"0\\\" + currentDate.getDate()).slice(-2);\\n dateList.push(`${year}-${month}-${day}`);\\n currentDate.setDate(currentDate.getDate() + 1);\\n }\\n return dateList;\\n}\\n// 转换 Excel 日期数字为日期字符串\\nfunction getDateFormat(value) {\\n // 检查是否为数字类型\\n if (typeof value === \\\"number\\\") {\\n // Excel 日期格式的起始日期是 1899-12-30\\n const excelEpoch = new Date(Date.UTC(1899, 11, 30));\\n // 将整数日期转换为毫秒数\\n const date = new Date(excelEpoch.getTime() + value * 24 * 60 * 60 * 1000);\\n const year = date.getUTCFullYear();\\n const month = (date.getUTCMonth() + 1).toString().padStart(2, \\\"0\\\");\\n const day = date.getUTCDate().toString().padStart(2, \\\"0\\\");\\n return `${year}-${month}-${day}`;\\n }\\n else if (typeof value === \\\"string\\\") {\\n // 如果已经是字符串,则直接返回\\n return value;\\n }\\n else {\\n // 其他情况返回空字符串\\n return \\\"\\\";\\n }\\n}\\n// 检查 xData 和 yAxisData 是否存在并且是数组\\nif (Array.isArray(xData) && Array.isArray(yAxisData)) {\\n // 批量处理日期\\n const xAxisData = xData.map((item) => getDateFormat(item));\\n // 将日期字符串转换为 Date 对象\\n const dateObjects = xAxisData.map((dateStr) => new Date(dateStr));\\n // 检查是否成功转换为有效的日期对象\\n if (dateObjects.some((date) => isNaN(date))) {\\n console.error(\\\"日期格式不正确,请检查日期数据。\\\");\\n return;\\n }\\n // 获取最小和最大日期\\n const timestamps = dateObjects.map((date) => date.getTime());\\n const minTimestamp = Math.min(...timestamps);\\n const maxTimestamp = Math.max(...timestamps);\\n const minDate = new Date(minTimestamp);\\n const maxDate = new Date(maxTimestamp);\\n // 生成完整的日期范围\\n const completeDateRange = getDateRange(minDate, maxDate);\\n // 将原始数据映射为日期和值的键值对\\n const dataMap = {};\\n xAxisData.forEach((date, index) => {\\n dataMap[date] = yAxisData[index];\\n });\\n // 补全缺失的数据\\n completeYAxisData = completeDateRange.map((date) => {\\n return dataMap[date] !== undefined ? dataMap[date] : 0;\\n });\\n // 更新图表的数据\\n completeXAxisData = completeDateRange;\\n}\\nelse {\\n console.error(\\\"数据格式不正确,请检查数据源。\\\");\\n}\\n// 配置 Echarts 图表\\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"报工趋势图\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n xAxis: {\\n type: \\\"category\\\",\\n data: completeXAxisData,\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n },\\n yAxis: {\\n type: \\\"value\\\",\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n splitLine: {\\n show: true,\\n lineStyle: {\\n color: \\\"#f8fafc\\\",\\n },\\n },\\n },\\n tooltip: {\\n trigger: \\\"axis\\\",\\n backgroundColor: \\\"#FFFFFF\\\",\\n textStyle: {\\n color: \\\"#000000\\\",\\n },\\n },\\n series: [\\n {\\n data: completeYAxisData,\\n type: \\\"line\\\",\\n lineStyle: {\\n width: 3,\\n shadowColor: \\\"rgba(0, 0, 0, 0.1)\\\",\\n shadowBlur: 10,\\n shadowOffsetX: 0,\\n shadowOffsetY: 4,\\n },\\n smooth: true,\\n symbolSize: 8,\\n symbol: \\\"none\\\",\\n itemStyle: {\\n color: \\\"#2196f3\\\",\\n },\\n areaStyle: {\\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\\n {\\n offset: 0,\\n color: \\\"rgba(33,150,243,0.3)\\\",\\n },\\n {\\n offset: 1,\\n color: \\\"rgba(33,150,243,0)\\\",\\n },\\n ]),\\n },\\n },\\n ],\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" + "Config": "{\"option\":\"let completeXAxisData = [];\\nlet completeYAxisData = []\\n\\n// 打印数据源以进行检查\\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]);\\n\\n// 拆分数据源\\nconst splitData = ForguncyEchartsHelper.splitDataSource(Context[\\\"工时表\\\"]);\\nconsole.log(\\\"拆分后的数据:\\\", splitData);\\n\\n// 使用正确的键名\\nconst { \\\"日期\\\": xData, \\\"总工时\\\": yAxisData } = splitData;\\nconsole.log(\\\"xData:\\\", xData);\\nconsole.log(\\\"yAxisData:\\\", yAxisData);\\n\\n// 生成完整的日期范围\\nfunction getDateRange(startDate, endDate) {\\n const dateList = [];\\n let currentDate = new Date(startDate);\\n\\n while (currentDate <= endDate) {\\n const year = currentDate.getFullYear();\\n const month = (\\\"0\\\" + (currentDate.getMonth() + 1)).slice(-2);\\n const day = (\\\"0\\\" + currentDate.getDate()).slice(-2);\\n\\n dateList.push(`${year}-${month}-${day}`);\\n\\n currentDate.setDate(currentDate.getDate() + 1);\\n }\\n return dateList;\\n}\\n\\n// 转换 Excel 日期数字为日期字符串\\nfunction getDateFormat(value) {\\n // 检查是否为数字类型\\n if (typeof value === \\\"number\\\") {\\n // Excel 日期格式的起始日期是 1899-12-30\\n const excelEpoch = new Date(Date.UTC(1899, 11, 30));\\n // 将整数日期转换为毫秒数\\n const date = new Date(\\n excelEpoch.getTime() + value * 24 * 60 * 60 * 1000,\\n );\\n const year = date.getUTCFullYear();\\n const month = (date.getUTCMonth() + 1).toString().padStart(2, \\\"0\\\");\\n const day = date.getUTCDate().toString().padStart(2, \\\"0\\\");\\n return `${year}-${month}-${day}`;\\n } else if (typeof value === \\\"string\\\") {\\n // 如果已经是字符串,则直接返回\\n return value;\\n } else {\\n // 其他情况返回空字符串\\n return \\\"\\\";\\n }\\n}\\n\\n// 检查 xData 和 yAxisData 是否存在并且是数组\\nif (Array.isArray(xData) && Array.isArray(yAxisData)) {\\n\\n // 批量处理日期\\n const xAxisData = xData.map((item) => getDateFormat(item));\\n\\n // 将日期字符串转换为 Date 对象\\n const dateObjects = xAxisData.map((dateStr) => new Date(dateStr));\\n\\n // 检查是否成功转换为有效的日期对象\\n if (dateObjects.some((date) => isNaN(date))) {\\n console.error(\\\"日期格式不正确,请检查日期数据。\\\");\\n return;\\n }\\n\\n // 获取最小和最大日期\\n const timestamps = dateObjects.map((date) => date.getTime());\\n const minTimestamp = Math.min(...timestamps);\\n const maxTimestamp = Math.max(...timestamps);\\n const minDate = new Date(minTimestamp);\\n const maxDate = new Date(maxTimestamp);\\n\\n // 生成完整的日期范围\\n const completeDateRange = getDateRange(minDate, maxDate);\\n\\n // 将原始数据映射为日期和值的键值对\\n const dataMap = {};\\n xAxisData.forEach((date, index) => {\\n dataMap[date] = yAxisData[index];\\n });\\n\\n // 补全缺失的数据\\n completeYAxisData = completeDateRange.map((date) => {\\n return dataMap[date] !== undefined ? dataMap[date] : 0;\\n });\\n\\n // 更新图表的数据\\n completeXAxisData = completeDateRange;\\n} else {\\n console.error(\\\"数据格式不正确,请检查数据源。\\\");\\n}\\n\\n// 配置 Echarts 图表\\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"报工趋势图 (近30天)\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n xAxis: {\\n type: \\\"category\\\",\\n data: completeXAxisData,\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n },\\n yAxis: {\\n type: \\\"value\\\",\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n splitLine: {\\n show: true,\\n lineStyle: {\\n color: \\\"#f8fafc\\\",\\n },\\n },\\n },\\n tooltip: {\\n trigger: \\\"axis\\\",\\n backgroundColor: \\\"#FFFFFF\\\",\\n textStyle: {\\n color: \\\"#000000\\\",\\n },\\n },\\n series: [\\n {\\n data: completeYAxisData,\\n type: \\\"line\\\",\\n lineStyle: {\\n width: 3,\\n shadowColor: \\\"rgba(0, 0, 0, 0.1)\\\",\\n shadowBlur: 10,\\n shadowOffsetX: 0,\\n shadowOffsetY: 4,\\n },\\n smooth: true,\\n symbolSize: 8,\\n symbol: \\\"none\\\",\\n itemStyle: {\\n color: \\\"#2196f3\\\",\\n },\\n areaStyle: {\\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\\n {\\n offset: 0,\\n color: \\\"rgba(33,150,243,0.3)\\\",\\n },\\n {\\n offset: 1,\\n color: \\\"rgba(33,150,243,0)\\\",\\n },\\n ]),\\n },\\n },\\n ],\\n};\\n\",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n let completeXAxisData = [];\\nlet completeYAxisData = [];\\n// 打印数据源以进行检查\\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]);\\n// 拆分数据源\\nconst splitData = ForguncyEchartsHelper.splitDataSource(Context[\\\"工时表\\\"]);\\nconsole.log(\\\"拆分后的数据:\\\", splitData);\\n// 使用正确的键名\\nconst { \\\"日期\\\": xData, \\\"总工时\\\": yAxisData } = splitData;\\nconsole.log(\\\"xData:\\\", xData);\\nconsole.log(\\\"yAxisData:\\\", yAxisData);\\n// 生成完整的日期范围\\nfunction getDateRange(startDate, endDate) {\\n const dateList = [];\\n let currentDate = new Date(startDate);\\n while (currentDate <= endDate) {\\n const year = currentDate.getFullYear();\\n const month = (\\\"0\\\" + (currentDate.getMonth() + 1)).slice(-2);\\n const day = (\\\"0\\\" + currentDate.getDate()).slice(-2);\\n dateList.push(`${year}-${month}-${day}`);\\n currentDate.setDate(currentDate.getDate() + 1);\\n }\\n return dateList;\\n}\\n// 转换 Excel 日期数字为日期字符串\\nfunction getDateFormat(value) {\\n // 检查是否为数字类型\\n if (typeof value === \\\"number\\\") {\\n // Excel 日期格式的起始日期是 1899-12-30\\n const excelEpoch = new Date(Date.UTC(1899, 11, 30));\\n // 将整数日期转换为毫秒数\\n const date = new Date(excelEpoch.getTime() + value * 24 * 60 * 60 * 1000);\\n const year = date.getUTCFullYear();\\n const month = (date.getUTCMonth() + 1).toString().padStart(2, \\\"0\\\");\\n const day = date.getUTCDate().toString().padStart(2, \\\"0\\\");\\n return `${year}-${month}-${day}`;\\n }\\n else if (typeof value === \\\"string\\\") {\\n // 如果已经是字符串,则直接返回\\n return value;\\n }\\n else {\\n // 其他情况返回空字符串\\n return \\\"\\\";\\n }\\n}\\n// 检查 xData 和 yAxisData 是否存在并且是数组\\nif (Array.isArray(xData) && Array.isArray(yAxisData)) {\\n // 批量处理日期\\n const xAxisData = xData.map((item) => getDateFormat(item));\\n // 将日期字符串转换为 Date 对象\\n const dateObjects = xAxisData.map((dateStr) => new Date(dateStr));\\n // 检查是否成功转换为有效的日期对象\\n if (dateObjects.some((date) => isNaN(date))) {\\n console.error(\\\"日期格式不正确,请检查日期数据。\\\");\\n return;\\n }\\n // 获取最小和最大日期\\n const timestamps = dateObjects.map((date) => date.getTime());\\n const minTimestamp = Math.min(...timestamps);\\n const maxTimestamp = Math.max(...timestamps);\\n const minDate = new Date(minTimestamp);\\n const maxDate = new Date(maxTimestamp);\\n // 生成完整的日期范围\\n const completeDateRange = getDateRange(minDate, maxDate);\\n // 将原始数据映射为日期和值的键值对\\n const dataMap = {};\\n xAxisData.forEach((date, index) => {\\n dataMap[date] = yAxisData[index];\\n });\\n // 补全缺失的数据\\n completeYAxisData = completeDateRange.map((date) => {\\n return dataMap[date] !== undefined ? dataMap[date] : 0;\\n });\\n // 更新图表的数据\\n completeXAxisData = completeDateRange;\\n}\\nelse {\\n console.error(\\\"数据格式不正确,请检查数据源。\\\");\\n}\\n// 配置 Echarts 图表\\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"报工趋势图 (近30天)\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n xAxis: {\\n type: \\\"category\\\",\\n data: completeXAxisData,\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n },\\n yAxis: {\\n type: \\\"value\\\",\\n axisLabel: {\\n color: \\\"#abacac\\\",\\n },\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n axisTick: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n },\\n splitLine: {\\n show: true,\\n lineStyle: {\\n color: \\\"#f8fafc\\\",\\n },\\n },\\n },\\n tooltip: {\\n trigger: \\\"axis\\\",\\n backgroundColor: \\\"#FFFFFF\\\",\\n textStyle: {\\n color: \\\"#000000\\\",\\n },\\n },\\n series: [\\n {\\n data: completeYAxisData,\\n type: \\\"line\\\",\\n lineStyle: {\\n width: 3,\\n shadowColor: \\\"rgba(0, 0, 0, 0.1)\\\",\\n shadowBlur: 10,\\n shadowOffsetX: 0,\\n shadowOffsetY: 4,\\n },\\n smooth: true,\\n symbolSize: 8,\\n symbol: \\\"none\\\",\\n itemStyle: {\\n color: \\\"#2196f3\\\",\\n },\\n areaStyle: {\\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\\n {\\n offset: 0,\\n color: \\\"rgba(33,150,243,0.3)\\\",\\n },\\n {\\n offset: 1,\\n color: \\\"rgba(33,150,243,0)\\\",\\n },\\n ]),\\n },\\n },\\n ],\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" } }, "7,1": { @@ -422,6 +425,54 @@ "ColumnName": "总核定工时" } ], + "SqlCondition": { + "$type": "ForguncyDataAccess.RelationSqlCondition, ForguncyDataAccess", + "SubConditions": [ + { + "$type": "ForguncyDataAccess.GeneralCESqlCondition, ForguncyDataAccess", + "CompareType": 1, + "ColumnBindingInfo": { + "TableName": "人员工时统计视图", + "ColumnName": "执行人", + "GUID": "0b34c9f5-aaee-4d74-9fea-09972a65f116" + }, + "Value": "%Null%" + }, + { + "$type": "ForguncyDataAccess.GeneralCESqlCondition, ForguncyDataAccess", + "ColumnBindingInfo": { + "TableName": "人员工时统计视图", + "ColumnName": "日期", + "GUID": "5d56155e-bbed-4c17-a938-53888dad630a", + "AttachType": { + "$type": "ForguncyDataAccess.DateColumnAttachObj, ForguncyDataAccess", + "ColumnAttachType": 1 + } + }, + "Value": { + "$type": "Forguncy.Model.FormulaReferObject, ServerDesignerCommon", + "SerializeProperty": "=YEAR(TODAY())" + } + }, + { + "$type": "ForguncyDataAccess.GeneralCESqlCondition, ForguncyDataAccess", + "ColumnBindingInfo": { + "TableName": "人员工时统计视图", + "ColumnName": "日期", + "GUID": "d4638e91-990f-415a-8a11-365f7a397486", + "AttachType": { + "$type": "ForguncyDataAccess.DateColumnAttachObj, ForguncyDataAccess", + "ColumnAttachType": 4 + } + }, + "Value": { + "$type": "Forguncy.Model.FormulaReferObject, ServerDesignerCommon", + "SerializeProperty": "=MONTH(TODAY())" + } + } + ] + }, + "NullFormulaValueQueryPolicy": 2, "OrderBySqlCondition": { "OrderByColumns": [ { @@ -440,7 +491,7 @@ ], "JSONDataSources": [], "ImageDataSource": [], - "Config": "{\"option\":\"// 获取数据源并拆分数据 \\nvar sourceData = Context[\\\"工时统计\\\"];\\nconsole.log(sourceData);\\nvar splitData = ForguncyEchartsHelper.splitDataSource(sourceData);\\n\\n// 将数据保留到1位小数 \\nfor (var key in splitData) {\\n if (key !== \\\"执行人\\\") {\\n splitData[key] = splitData[key].map(function (value) {\\n return parseFloat(value.toFixed(1));\\n });\\n }\\n}\\n\\n// 将数据按照「总上报工时」降序序 \\nvar indices = splitData[\\\"总上报工时\\\"]\\n .map(function (value, index) { return index; })\\n .sort(function (a, b) { return splitData[\\\"总上报工时\\\"][b] - splitData[\\\"总上报工时\\\"][a]; });\\n\\n// 根据排序后的索引重组数据 \\nvar xData = indices.map(function (index) { return splitData[\\\"执行人\\\"][index]; });\\nvar totalReported = indices.map(function (index) { return splitData[\\\"总上报工时\\\"][index]; });\\nvar totalApproved = indices.map(function (index) { return splitData[\\\"总核定工时\\\"][index]; });\\nvar difference = totalReported.map(function (value, index) {\\n return parseFloat((value - totalApproved[index]).toFixed(1));\\n});\\n\\n// 配置 Echarts 的 option \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"工时排行榜\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n tooltip: {\\n trigger: 'axis',\\n axisPointer: { type: 'shadow' },\\n formatter: function (params) {\\n return params[0].name + '
' + params[0].seriesName + ':' + params[0].value + '小时' + '
' +\\n params[1].seriesName + ':' + params[1].value;\\n }\\n },\\n legend: {\\n show: false\\n },\\n xAxis: {\\n type: 'category',\\n data: xData,\\n },\\n yAxis: {\\n type: 'value',\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n }\\n },\\n series: [\\n {\\n name: '已核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: totalApproved,\\n itemStyle: {\\n color: '#63b5f6',\\n borderRadius:\\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: '{c}小时',\\n color: '#fff',\\n fontSize: 16\\n }\\n },\\n {\\n name: '未核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: difference,\\n itemStyle: {\\n color: '#2196f3',\\n borderRadius:\\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: function (params) {\\n if (params.value > 0) {\\n return params.value + '小时';\\n } else {\\n return '';\\n }\\n },\\n color: '#fff',\\n fontSize: 16\\n }\\n }\\n ]\\n}; \",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n // 获取数据源并拆分数据 \\nvar sourceData = Context[\\\"工时统计\\\"];\\nconsole.log(sourceData);\\nvar splitData = ForguncyEchartsHelper.splitDataSource(sourceData);\\n// 将数据保留到1位小数 \\nfor (var key in splitData) {\\n if (key !== \\\"执行人\\\") {\\n splitData[key] = splitData[key].map(function (value) {\\n return parseFloat(value.toFixed(1));\\n });\\n }\\n}\\n// 将数据按照「总上报工时」降序序 \\nvar indices = splitData[\\\"总上报工时\\\"]\\n .map(function (value, index) { return index; })\\n .sort(function (a, b) { return splitData[\\\"总上报工时\\\"][b] - splitData[\\\"总上报工时\\\"][a]; });\\n// 根据排序后的索引重组数据 \\nvar xData = indices.map(function (index) { return splitData[\\\"执行人\\\"][index]; });\\nvar totalReported = indices.map(function (index) { return splitData[\\\"总上报工时\\\"][index]; });\\nvar totalApproved = indices.map(function (index) { return splitData[\\\"总核定工时\\\"][index]; });\\nvar difference = totalReported.map(function (value, index) {\\n return parseFloat((value - totalApproved[index]).toFixed(1));\\n});\\n// 配置 Echarts 的 option \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"工时排行榜\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n tooltip: {\\n trigger: 'axis',\\n axisPointer: { type: 'shadow' },\\n formatter: function (params) {\\n return params[0].name + '
' + params[0].seriesName + ':' + params[0].value + '小时' + '
' +\\n params[1].seriesName + ':' + params[1].value;\\n }\\n },\\n legend: {\\n show: false\\n },\\n xAxis: {\\n type: 'category',\\n data: xData,\\n },\\n yAxis: {\\n type: 'value',\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n }\\n },\\n series: [\\n {\\n name: '已核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: totalApproved,\\n itemStyle: {\\n color: '#63b5f6',\\n borderRadius: \\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: '{c}小时',\\n color: '#fff',\\n fontSize: 16\\n }\\n },\\n {\\n name: '未核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: difference,\\n itemStyle: {\\n color: '#2196f3',\\n borderRadius: \\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: function (params) {\\n if (params.value > 0) {\\n return params.value + '小时';\\n }\\n else {\\n return '';\\n }\\n },\\n color: '#fff',\\n fontSize: 16\\n }\\n }\\n ]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" + "Config": "{\"option\":\"// 获取数据源并拆分数据 \\nvar sourceData = Context[\\\"工时统计\\\"];\\nconsole.log(sourceData);\\nvar splitData = ForguncyEchartsHelper.splitDataSource(sourceData);\\n\\n// 将数据保留到1位小数 \\nfor (var key in splitData) {\\n if (key !== \\\"执行人\\\") {\\n splitData[key] = splitData[key].map(function (value) {\\n return parseFloat(value.toFixed(1));\\n });\\n }\\n}\\n\\n// 将数据按照「总上报工时」降序序 \\nvar indices = splitData[\\\"总上报工时\\\"]\\n .map(function (value, index) { return index; })\\n .sort(function (a, b) { return splitData[\\\"总上报工时\\\"][b] - splitData[\\\"总上报工时\\\"][a]; });\\n\\n// 根据排序后的索引重组数据 \\nvar xData = indices.map(function (index) { return splitData[\\\"执行人\\\"][index]; });\\nvar totalReported = indices.map(function (index) { return splitData[\\\"总上报工时\\\"][index]; });\\nvar totalApproved = indices.map(function (index) { return splitData[\\\"总核定工时\\\"][index]; });\\nvar difference = totalReported.map(function (value, index) {\\n return parseFloat((value - totalApproved[index]).toFixed(1));\\n});\\n\\n// 配置 Echarts 的 option \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"工时排行榜(本月)\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n tooltip: {\\n trigger: 'axis',\\n axisPointer: { type: 'shadow' },\\n formatter: function (params) {\\n return params[0].name + '
' + params[0].seriesName + ':' + params[0].value + '小时' + '
' +\\n params[1].seriesName + ':' + params[1].value;\\n }\\n },\\n legend: {\\n show: false\\n },\\n xAxis: {\\n type: 'category',\\n data: xData,\\n },\\n yAxis: {\\n type: 'value',\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n }\\n },\\n series: [\\n {\\n name: '已核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: totalApproved,\\n itemStyle: {\\n color: '#63b5f6',\\n borderRadius:\\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: '{c}小时',\\n color: '#fff',\\n fontSize: 12\\n }\\n },\\n {\\n name: '未核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: difference,\\n itemStyle: {\\n color: '#2196f3',\\n borderRadius:\\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: function (params) {\\n if (params.value > 0) {\\n return params.value + '小时';\\n } else {\\n return '';\\n }\\n },\\n color: '#fff',\\n fontSize: 12\\n }\\n }\\n ]\\n}; \",\"graphTheme\":null,\"displayMode\":\"canvas\",\"jsCode\":\"\\n async ({Context,JSONContext,ImageContext,echarts,myChart,dat,Forguncy,d3,setInterval,setTimeout,ForguncyEchartsHelper,PublicResource})=>{\\n var datGUI=undefined;\\n var option={};\\n // 获取数据源并拆分数据 \\nvar sourceData = Context[\\\"工时统计\\\"];\\nconsole.log(sourceData);\\nvar splitData = ForguncyEchartsHelper.splitDataSource(sourceData);\\n// 将数据保留到1位小数 \\nfor (var key in splitData) {\\n if (key !== \\\"执行人\\\") {\\n splitData[key] = splitData[key].map(function (value) {\\n return parseFloat(value.toFixed(1));\\n });\\n }\\n}\\n// 将数据按照「总上报工时」降序序 \\nvar indices = splitData[\\\"总上报工时\\\"]\\n .map(function (value, index) { return index; })\\n .sort(function (a, b) { return splitData[\\\"总上报工时\\\"][b] - splitData[\\\"总上报工时\\\"][a]; });\\n// 根据排序后的索引重组数据 \\nvar xData = indices.map(function (index) { return splitData[\\\"执行人\\\"][index]; });\\nvar totalReported = indices.map(function (index) { return splitData[\\\"总上报工时\\\"][index]; });\\nvar totalApproved = indices.map(function (index) { return splitData[\\\"总核定工时\\\"][index]; });\\nvar difference = totalReported.map(function (value, index) {\\n return parseFloat((value - totalApproved[index]).toFixed(1));\\n});\\n// 配置 Echarts 的 option \\noption = {\\n backgroundColor: \\\"rgba(0, 0, 0, 0)\\\",\\n title: {\\n text: \\\"工时排行榜(本月)\\\",\\n left: \\\"center\\\",\\n top: 24,\\n textStyle: {\\n fontSize: 16,\\n fontWeight: \\\"bold\\\",\\n },\\n },\\n grid: {\\n top: 72,\\n left: \\\"24px\\\",\\n right: \\\"24px\\\",\\n bottom: \\\"24px\\\",\\n containLabel: true,\\n },\\n tooltip: {\\n trigger: 'axis',\\n axisPointer: { type: 'shadow' },\\n formatter: function (params) {\\n return params[0].name + '
' + params[0].seriesName + ':' + params[0].value + '小时' + '
' +\\n params[1].seriesName + ':' + params[1].value;\\n }\\n },\\n legend: {\\n show: false\\n },\\n xAxis: {\\n type: 'category',\\n data: xData,\\n },\\n yAxis: {\\n type: 'value',\\n axisLine: {\\n lineStyle: {\\n color: \\\"#f5f6f6\\\",\\n },\\n }\\n },\\n series: [\\n {\\n name: '已核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: totalApproved,\\n itemStyle: {\\n color: '#63b5f6',\\n borderRadius: \\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: '{c}小时',\\n color: '#fff',\\n fontSize: 12\\n }\\n },\\n {\\n name: '未核定工时',\\n type: 'bar',\\n stack: '总量',\\n data: difference,\\n itemStyle: {\\n color: '#2196f3',\\n borderRadius: \\\"8px\\\"\\n },\\n label: {\\n show: true,\\n position: 'inside',\\n formatter: function (params) {\\n if (params.value > 0) {\\n return params.value + '小时';\\n }\\n else {\\n return '';\\n }\\n },\\n color: '#fff',\\n fontSize: 12\\n }\\n }\\n ]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}" } } }, @@ -578,4 +629,4 @@ "Size": "1152,254" } ] -}//BtfImtg5onZ4MZasX9AwVSiQqyeVGjrbAhQe5i2DWVMCep/k2RZxtFvOdDFUr5uxFuZtOwZYEYa/ZBmiNbG5g2JGuDDo42KNA/W8odb+L/A5Af75x6gkA6qFRo40DqjK+LNjUe+w6jm9/vwo23kd6XLAHApWJQ7waOpZPfWxflEIMIqjQs0fW/bvm7HsQq36OUNSvVeb/eiwoHWY72pP9x5pLXwksIfMGn4TwLnrq0PUOXLnEojTVIyFXgohsv3+hm3p8+hg8oqhDzCZ5IXlZO5VhZzRDq/lMDCSn0/h9T7x2ZK2WyK/6fk20yjutXWBLeJIS9Llm8a4SY2drT3hi1W1SAQCZxOizUlwxi8jx6m4AxaImnEJLon1sT9HDLUI5Tz448qgqIp/VGmmfA5KlTCoqjah0VlujedRkIOxnh01tn79SMoeT31J3JHYjpHdKOciY7/pcNoHDVarfyz7o6Qdr4x5sWp7oOkNgJh3HMiy14SAfdD9I4LvzGBVXYuUq2uTPSITUsJgvIby8XCyJVQeIqxdwVq13APOJEwtFPmjpfeSlsIWMxQCrI0fT+X5WFhCBVGZG4nlQbrksP1PfOXJ6kLmS4Hzim2cGJtvrYInSe6/L0bhxSgsS+vvofjJAqU8zgq4ISXolzPB5bQnpuQVWIG1Ihsox4UPOCouL1LODczBp+fI70coE+xtcjkto5YVEzvuJKLk7xqT5+wdS0INVrNMc/qA/unTijXhQ1PLA4cGY85rN/YMT5I4oS9Wf11ieLHMdoGo1z42NTzHC0qUUIfeutb6C+fq/HfAN8WL4LB/IlTRc4HeoN/hJrN2qYaEUkkAYuXiJCMEegdhB05tYis0MLjpEPoIZiKpG82ccGXnI6XWVHvLwEnoc/oLTGpjAoHcQAKUe2gXNWlrjQ==|920 \ No newline at end of file +}//4C/zbKQY4FYd+Q2u24Iny4u4IaPGTuxgOMGsVAvj9szhhvo2lLoBCb7CYdqal+VTP9EN1ec+YI7akqeYOiQGXfOblRN4xrpmNHQZc2bz6mCMWBiNdmgOZ3P3HFgs9Yh8wLlESMoRu8YYkq4UbFjY5DOM240Bn4Q+C0B60JLPcSDQBivYl73DfGqGuKxKX6sd+rDS42gRt9NfGuRMAZSBri+XY8B4YBhM5orafvpnN70dBvURY7wGhkV7pWzCgkaUkUqqe1IpNHRXY7S9MxJnhpkJ7+fmrWCDe4c/cQW1QXOHXhOZtTeh95qvcfmKm5AqB/cvjiUu6WYZ0Hxx0vDujuU45e4v+Rj0/HoFqD11ZdvI8AcBdll42D4Bn4EpIfqu/ckYzWSfqZk2UWaKEtlo0Zsj45iI3tGkYRB/HUYIlD0tHiS90renRCuIQo+IUICZEFh697jYrQhobvos7YNTx+Iu79rTt7Nj81knI2pykNYnk9uVBSrUDyRPssVm+QFfCJtTNxfO2V2m4mYTyo7+lqf0iwI2rahzkmavAlnr08YRicmP0rkL7NM/J9pTu0C+3u6x2+22nPXb7UHCl81G1o9efkb/ApzKnJbr3M8itv6uI2AEAdCCVormMLXvPyKwP9GMIPIg5dM/07gcJidM38RJvfZQFmk8ypeAVUSyvazy5yMMEqmyKbaKkPebjknJgAVGbSIQCy/k2hk0KjsHpYCp/J7RHL5Fi+hissRoBzNzo7ONzkCimI/g3xMm7MhZ3WhiQARz727CflWWKOjeLMSClkp3h8va3n+gvgmT8AW2tGvsmOHHor0wsU+Db4Q2U2bqQF74+IAZ/jMiqBEVNl9erzqjY4ISSZYTa0GT3GW9Z+0OpRSMWmJqSCnBThvG4+xFLPLkoBRCp/0JSpdv9w==|920 \ No newline at end of file