diff --git a/.collaboration b/.collaboration
index 765f9227..c048255e 100644
--- a/.collaboration
+++ b/.collaboration
@@ -1566,16 +1566,7 @@
},
{
"ModuleName": "ServerCommand/新增或修改项目",
- "State": 1,
- "LockedBy": {
- "UserName": "cuckooent",
- "Email": "phoben@qq.com"
- },
- "LockDateTime": "2024-11-05T10:51:06.7059812+08:00",
- "ModuleType": 15,
- "ToRemoveFiles": [
- "ServerCommands\\项目\\新增或修改项目.json"
- ]
+ "ModuleType": 15
},
{
"ModuleName": "ServerCommand/删除项目分组",
@@ -2279,17 +2270,7 @@
},
{
"ModuleName": "PCPage/工作台首页",
- "State": 1,
- "LockedBy": {
- "UserName": "cuckooent",
- "Email": "phoben@qq.com"
- },
- "LockDateTime": "2024-11-05T10:57:22.9760295+08:00",
- "ModuleType": 1,
- "ToRemoveFiles": [
- "Pages\\工作台\\工作台首页.json",
- "Pages\\工作台\\工作台首页.rd"
- ]
+ "ModuleType": 1
},
{
"ModuleName": "PCPage/项目负荷 (2)",
diff --git a/Pages/3868fc7f40b841649f14b5adba61954.json b/Pages/3868fc7f40b841649f14b5adba61954.json
new file mode 100644
index 00000000..d1c67ddc
--- /dev/null
+++ b/Pages/3868fc7f40b841649f14b5adba61954.json
@@ -0,0 +1,268 @@
+{
+ "Rows": {
+ "RowColumnAttachedInfos": {
+ "0": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "2": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "4": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 5.0
+ }
+ },
+ "5": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 25.0,
+ "Mode": 1
+ }
+ },
+ "6": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 5.0
+ }
+ },
+ "8": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "1": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 20.0
+ }
+ },
+ "3": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 20.0
+ }
+ },
+ "7": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 20.0
+ }
+ }
+ },
+ "Count": 9,
+ "DefaultSize": 10.0
+ },
+ "Cols": {
+ "RowColumnAttachedInfos": {
+ "0": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 5.0
+ }
+ },
+ "3": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 196.0,
+ "Mode": 2,
+ "MinLength": {
+ "Unit": 1
+ },
+ "MaxLength": {
+ "Value": 1.0
+ }
+ }
+ },
+ "6": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "4": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 20.0
+ }
+ },
+ "5": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 57.0
+ }
+ }
+ },
+ "Count": 7,
+ "DefaultSize": 10.0
+ },
+ "Values": {
+ "1,3": 0,
+ "1,5": "类型",
+ "3,3": "项目名称",
+ "5,3": "xxxxxxxxx...",
+ "7,3": "username"
+ },
+ "AttachInfos": {
+ "1,1": {
+ "CellType": {
+ "$type": "Forguncy.ImageCellType, ServerDesignerCommon",
+ "Size": 14,
+ "ImagePath": "Application/139_time_1.svg",
+ "BuiltIn": true,
+ "UseCellForeColor": true
+ }
+ },
+ "1,3": {
+ "TemplateCellSource": "创建日期"
+ },
+ "1,5": {
+ "CellType": {
+ "$type": "ElementUI.Tag, ElementUI",
+ "CommandList": [],
+ "UIPermissions": [
+ {
+ "Scope": 2,
+ "AllowRoles": [
+ "FGC_Anonymous"
+ ]
+ },
+ {
+ "Scope": 1,
+ "AllowRoles": [
+ "FGC_Anonymous"
+ ]
+ },
+ {
+ "Scope": 4,
+ "AllowRoles": [
+ "FGC_Anonymous"
+ ]
+ }
+ ],
+ "ColorList": [
+ {
+ "color": "Accent 2 0"
+ }
+ ],
+ "DefaultValue": "类型",
+ "separator": ",",
+ "size": "small",
+ "effect": "light",
+ "allowAdd": false,
+ "addButtonSettings": {
+ "width": 100,
+ "text": "添加标签"
+ },
+ "distinct": false,
+ "ReadOnly": true
+ },
+ "TemplateCellSource": "类型"
+ },
+ "3,3": {
+ "TemplateCellSource": "项目名称"
+ },
+ "5,3": {
+ "TemplateCellSource": "项目动态"
+ },
+ "7,3": {
+ "TemplateCellSource": "执行人_全名"
+ }
+ },
+ "StyleDatas": {
+ "Styles": [
+ {
+ "BorderRight": 0
+ },
+ {
+ "FontSize": 13.333333333333332,
+ "Foreground": 1
+ },
+ {
+ "FontFamily": 2,
+ "FontSize": 12.0,
+ "Foreground": 1,
+ "Formatter": 3,
+ "HorizontalAlignment": 4
+ },
+ {
+ "FontFamily": 2,
+ "FontSize": 13.333333333333332,
+ "Foreground": 5,
+ "HorizontalAlignment": 6
+ },
+ {
+ "FontFamily": 2
+ },
+ {
+ "FontSize": 13.333333333333332,
+ "FontWeight": 7,
+ "Foreground": 8
+ },
+ {
+ "FontFamily": 2,
+ "BorderRight": 0
+ },
+ {
+ "FontSize": 13.333333333333332,
+ "Foreground": 9,
+ "HorizontalAlignment": 4,
+ "VerticalAlignment": 10,
+ "WordWrap": true
+ },
+ {
+ "FontSize": 12.0,
+ "Foreground": 1,
+ "HorizontalAlignment": 6
+ }
+ ],
+ "Types": {
+ "Strs": [
+ "Background 2 0",
+ "Text 1 50",
+ "Body",
+ "yyyy/m/d",
+ "Left",
+ "black",
+ "Right",
+ "Bold",
+ "Text 1 35",
+ "Background 2 -90",
+ "Top"
+ ],
+ "Borders": [
+ {
+ "Color": 0
+ }
+ ]
+ },
+ "CellStyles": {
+ "0,1": 0,
+ "1,1": 1,
+ "1,2": 1,
+ "1,3": 2,
+ "1,5": 3,
+ "2,1": 0,
+ "2,3": 4,
+ "3,1": 0,
+ "3,3": 5,
+ "4,1": 6,
+ "5,1": 6,
+ "5,3": 7,
+ "6,1": 6,
+ "7,1": 6,
+ "7,3": 8,
+ "8,1": 6
+ },
+ "SheetStyle": {
+ "FontFamily": 2
+ }
+ },
+ "Spans": [
+ "1,1,1,2",
+ "5,3,1,3",
+ "3,3,1,3",
+ "7,3,1,3"
+ ],
+ "PageInfo": {
+ "$type": "Forguncy.Model.Pages.TemplatePage, ServerDesignerCommon",
+ "ParentPageName": "工作台首页"
+ },
+ "PrintInfo": {
+ "PaperSize": {},
+ "Margin": {}
+ }
+}//BrbLFkReqFa34ornoz+14zGvNWTxRl/zGsbvkDkLK/Xf+HR/Tecp1XdsZSc0dhv+xQg6hGODqy9ZHMQbBVZc0ryvuJUbtPjn58cuXutjsS5WFLsHk76GkaON4CHpymwCe6+bhm3ajrUMaSzqpBHel6USL3AfgruRSQUfiy0dhmU9hMXY9I7XQTWfSERuqhQl3+PWLPWny2JoGsQ8dftRha2X7d6gebLsG4bLLlOeBW9lCQVBxc4FUfTQ9tWgd8ekjxKVGRUHHGrtl3n2CUJNOVOarLcJB3akRViJMMmtbfIeCFNBv9vp6oj040LYdXThYWtiAQ3fRVaM8GfcJeOwUyy8ab3Kv3tzn84up6pyUVoV/MFZTJtHzPAX/PAapTCjJUQf+TbyURsyDYoNuj0JyFSQeL+XnYFBPKOFR1KlbXtfpldHou2JI1Xte/GjAxG/zSqgGpIkysRVLfOY6YQ5vGwL4He6D/N76V5OMdTKB8+E+BETLPxY6CXptjXbaQx4ZhNEsMye8KZezGUU2kzdUovo63dx3FvEG1Na7PHrmUH6PkWiEsxvTGAGJQfts2LsPkUqd9jTcpLUU4PXmX6CWzyAsrXvPpN7fPnoQIwG2Qi6fiJ7S+yMjK/ESV0B5Fe2Xeulx4pLBSZ0/JkmljTwX8efbM3OJnJ2tg+fzBppeS9znB/qZD8pxoPRcmvksy1DdYQB8lmj2um/LOKHHsAfNtsphxBlpq+LD0gXcQfeO818g13xrGNIbhQLm6rgQvvkkSC8Mlqw8i183ptxX67mSwqH9MwN6MZiM6YryF199dDan6zYPdrvEr/8acI8zLNBv5YNp0gTk+5MRgL7WqttJWkqg1wwUYWjJlGMf9lBI91ASgxdwHHa1CJXwKjjlbwc39WT4JUT6Wq9eNkbp+vClw==|920
\ No newline at end of file
diff --git a/Pages/3868fc7f40b841649f14b5adba61954.rd b/Pages/3868fc7f40b841649f14b5adba61954.rd
new file mode 100644
index 00000000..87520ab1
--- /dev/null
+++ b/Pages/3868fc7f40b841649f14b5adba61954.rd
@@ -0,0 +1,5 @@
+{
+ "PageType": 2,
+ "ColumnCount": 7,
+ "RowCount": 9
+}
\ No newline at end of file
diff --git a/Pages/工作台/工作台首页.json b/Pages/工作台/工作台首页.json
index dfae2351..f970d3dd 100644
--- a/Pages/工作台/工作台首页.json
+++ b/Pages/工作台/工作台首页.json
@@ -19,7 +19,7 @@
},
"3": {
"GridRowColumnDefinition": {
- "DesignLengthInPixel": 83.0,
+ "DesignLengthInPixel": 97.0,
"Mode": 1
}
},
@@ -30,29 +30,35 @@
},
"5": {
"GridRowColumnDefinition": {
- "DesignLengthInPixel": 300.0
- }
- },
- "6": {
- "GridRowColumnDefinition": {
- "DesignLengthInPixel": 10.0
+ "DesignLengthInPixel": 15.0
}
},
"7": {
- "GridRowColumnDefinition": {
- "DesignLengthInPixel": 383.0
- }
- },
- "8": {
"GridRowColumnDefinition": {
"DesignLengthInPixel": 10.0
}
},
"9": {
"GridRowColumnDefinition": {
- "DesignLengthInPixel": 254.0,
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "10": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 383.0
+ }
+ },
+ "11": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 10.0
+ }
+ },
+ "12": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 246.0,
"Mode": 2,
"MinLength": {
+ "Value": 400.0,
"Unit": 1
},
"MaxLength": {
@@ -60,22 +66,37 @@
}
}
},
- "10": {
+ "13": {
"GridRowColumnDefinition": {
"DesignLengthInPixel": 15.0
}
},
- "11": {
+ "14": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 15.0
+ }
+ },
+ "15": {
"GridRowColumnDefinition": {
"DesignLengthInPixel": 32.0,
"IsHidden": true
}
+ },
+ "6": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 32.0
+ }
+ },
+ "8": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 243.0
+ }
}
},
"InLogicalVisibleIndexes": [
- 11
+ 15
],
- "Count": 12,
+ "Count": 16,
"DefaultSize": 10.0
},
"Cols": {
@@ -279,16 +300,26 @@
},
"38": {
"GridRowColumnDefinition": {
- "DesignLengthInPixel": 320.0
+ "DesignLengthInPixel": 15.0
+ }
+ },
+ "40": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 15.0
+ }
+ },
+ "41": {
+ "GridRowColumnDefinition": {
+ "DesignLengthInPixel": 24.0
}
},
"39": {
"GridRowColumnDefinition": {
- "DesignLengthInPixel": 24.0
+ "DesignLengthInPixel": 313.0
}
}
},
- "Count": 40,
+ "Count": 42,
"DefaultSize": 32.0
},
"Values": {
@@ -296,9 +327,10 @@
"1,38": "公告栏",
"3,1": "工作台_快捷入口",
"5,1": "工时折线图",
- "5,38": "项目动态",
- "7,1": "工时排行榜(柱形图)",
- "9,1": "反馈统计(饼图+表格)"
+ "6,39": "项目动态",
+ "8,39": "项目动态",
+ "10,1": "工时排行榜(柱形图)",
+ "12,1": "反馈统计(饼图+表格)"
},
"AttachInfos": {
"1,1": {
@@ -390,7 +422,97 @@
"Config": "{\"option\":\"let completeXAxisData = []; \\nlet completePlanData = []; // 计划工时数据 \\nlet completeActualData = []; // 实际工时数据 \\n\\n// 打印数据源以进行检查 \\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]); \\n\\n// 按工时类型分组数据 \\nconst groupedData = {}; \\nContext[\\\"工时表\\\"].forEach(item => { \\n if (!groupedData[item[\\\"工时类型\\\"]]) { \\n groupedData[item[\\\"工时类型\\\"]] = { \\n dates: [], \\n hours: [] \\n }; \\n } \\n groupedData[item[\\\"工时类型\\\"]].dates.push(item[\\\"日期\\\"]); \\n groupedData[item[\\\"工时类型\\\"]].hours.push(item[\\\"总工时\\\"]); \\n}); \\n\\n// 日期格式化函数保持不变 \\nfunction getDateFormat(value) { \\n if (typeof value === \\\"number\\\") { \\n const excelEpoch = new Date(Date.UTC(1899, 11, 30)); \\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 } else if (typeof value === \\\"string\\\") { \\n return value; \\n } \\n return \\\"\\\"; \\n} \\n\\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\\n// 获取所有日期并找出最大最小日期 \\nconst allDates = []; \\nObject.values(groupedData).forEach(data => { \\n data.dates.forEach(date => { \\n allDates.push(new Date(getDateFormat(date))); \\n }); \\n}); \\n\\nif (allDates.length > 0) { \\n const minDate = new Date(Math.min(...allDates)); \\n const maxDate = new Date(Math.max(...allDates)); \\n completeXAxisData = getDateRange(minDate, maxDate); \\n\\n // 处理每种类型的数据 \\n Object.entries(groupedData).forEach(([type, data]) => { \\n // 格式化日期 \\n const formattedDates = data.dates.map(date => getDateFormat(date)); \\n \\n // 创建日期-工时映射 \\n const dataMap = {}; \\n formattedDates.forEach((date, index) => { \\n dataMap[date] = data.hours[index]; \\n }); \\n\\n // 补全数据 \\n const completeData = completeXAxisData.map(date => { \\n return dataMap[date] !== undefined ? dataMap[date] : 0; \\n }); \\n\\n // 根据类型存储数据 \\n if (type === \\\"计划\\\") { \\n completePlanData = completeData; \\n } else if (type === \\\"实际\\\") { \\n completeActualData = completeData; \\n } \\n }); \\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 legend: { \\n data: ['计划工时', '实际工时'], \\n top: 60, \\n textStyle: { \\n color: '#666' \\n } \\n }, \\n grid: { \\n top: 100, // 增加top值以适应legend \\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 name: '计划工时', \\n data: completePlanData, \\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 name: '实际工时', \\n data: completeActualData, \\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: \\\"#ff5722\\\", // 橙色 \\n }, \\n areaStyle: { \\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ \\n { \\n offset: 0, \\n color: \\\"rgba(255,87,34,0.3)\\\", \\n }, \\n { \\n offset: 1, \\n color: \\\"rgba(255,87,34,0)\\\", \\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 completePlanData = []; // 计划工时数据 \\nlet completeActualData = []; // 实际工时数据 \\n// 打印数据源以进行检查 \\nconsole.log(\\\"Context['工时表']:\\\", Context[\\\"工时表\\\"]);\\n// 按工时类型分组数据 \\nconst groupedData = {};\\nContext[\\\"工时表\\\"].forEach(item => {\\n if (!groupedData[item[\\\"工时类型\\\"]]) {\\n groupedData[item[\\\"工时类型\\\"]] = {\\n dates: [],\\n hours: []\\n };\\n }\\n groupedData[item[\\\"工时类型\\\"]].dates.push(item[\\\"日期\\\"]);\\n groupedData[item[\\\"工时类型\\\"]].hours.push(item[\\\"总工时\\\"]);\\n});\\n// 日期格式化函数保持不变 \\nfunction getDateFormat(value) {\\n if (typeof value === \\\"number\\\") {\\n const excelEpoch = new Date(Date.UTC(1899, 11, 30));\\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 return value;\\n }\\n return \\\"\\\";\\n}\\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// 获取所有日期并找出最大最小日期 \\nconst allDates = [];\\nObject.values(groupedData).forEach(data => {\\n data.dates.forEach(date => {\\n allDates.push(new Date(getDateFormat(date)));\\n });\\n});\\nif (allDates.length > 0) {\\n const minDate = new Date(Math.min(...allDates));\\n const maxDate = new Date(Math.max(...allDates));\\n completeXAxisData = getDateRange(minDate, maxDate);\\n // 处理每种类型的数据 \\n Object.entries(groupedData).forEach(([type, data]) => {\\n // 格式化日期 \\n const formattedDates = data.dates.map(date => getDateFormat(date));\\n // 创建日期-工时映射 \\n const dataMap = {};\\n formattedDates.forEach((date, index) => {\\n dataMap[date] = data.hours[index];\\n });\\n // 补全数据 \\n const completeData = completeXAxisData.map(date => {\\n return dataMap[date] !== undefined ? dataMap[date] : 0;\\n });\\n // 根据类型存储数据 \\n if (type === \\\"计划\\\") {\\n completePlanData = completeData;\\n }\\n else if (type === \\\"实际\\\") {\\n completeActualData = completeData;\\n }\\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 legend: {\\n data: ['计划工时', '实际工时'],\\n top: 60,\\n textStyle: {\\n color: '#666'\\n }\\n },\\n grid: {\\n top: 100,\\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 name: '计划工时',\\n data: completePlanData,\\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 name: '实际工时',\\n data: completeActualData,\\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: \\\"#ff5722\\\", // 橙色 \\n },\\n areaStyle: {\\n color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [\\n {\\n offset: 0,\\n color: \\\"rgba(255,87,34,0.3)\\\",\\n },\\n {\\n offset: 1,\\n color: \\\"rgba(255,87,34,0)\\\",\\n },\\n ]),\\n },\\n }\\n ],\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}"
}
},
- "7,1": {
+ "8,39": {
+ "CellType": {
+ "$type": "Forguncy.RepeaterCellType, ServerDesignerCommon",
+ "TemplatePageName": "3868fc7f40b841649f14b5adba61954",
+ "DataSourceType": 1,
+ "DataSource": {
+ "$type": "ServerDesignerCommon.Model.BindingDataSourceModel, ServerDesignerCommon",
+ "TableName": "项目动态",
+ "BindingInfos": [
+ {
+ "GUID": "b3f78435-9660-4abe-882b-c49e646e5f0c",
+ "BindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "项目ID",
+ "GUID": "92efd49e-0be5-4429-85e0-11fc43ac401b",
+ "RelationBinding": {
+ "RelatedTable": "项目表",
+ "RelatedColumn": "ID",
+ "DisplayColumn": "项目名称"
+ }
+ },
+ "ColumnName": "项目名称"
+ },
+ {
+ "GUID": "f88b9218-ba69-4c3d-b07b-cdaf08124e05",
+ "BindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "项目动态",
+ "GUID": "748d15fc-d5f0-408a-a4b3-c21b44126093"
+ },
+ "ColumnName": "项目动态"
+ },
+ {
+ "GUID": "89bd6358-3520-4e9e-91c6-6e68af024915",
+ "BindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "执行人",
+ "GUID": "6eae3b71-c332-4ac4-9d39-f0dac2ca6bc5",
+ "AttachType": {
+ "$type": "ForguncyDataAccess.UserColumnAttachObj, ForguncyDataAccess",
+ "UserColumnAttachType": 1
+ }
+ },
+ "ColumnName": "执行人_全名"
+ },
+ {
+ "GUID": "923d170f-b12e-4d76-9297-348a302bdc40",
+ "BindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "类型",
+ "GUID": "50543609-aa2c-43c0-a6ca-74269c242dcb",
+ "RelationBinding": {
+ "RelatedTable": "项目动态类型",
+ "RelatedColumn": "类型码",
+ "DisplayColumn": "类型"
+ }
+ },
+ "ColumnName": "类型"
+ },
+ {
+ "GUID": "e92f7984-ecce-4ea7-beab-51eb5b9a055a",
+ "BindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "FGC_CreateDate",
+ "GUID": "e75f3c02-ac4d-4deb-a52f-881065832673"
+ },
+ "ColumnName": "创建日期"
+ }
+ ],
+ "OrderBySqlCondition": {
+ "OrderByColumns": [
+ {
+ "ColumnBindingInfo": {
+ "TableName": "项目动态",
+ "ColumnName": "FGC_CreateDate",
+ "GUID": "f75648fb-423f-4f0a-b09c-c7394a91d84b"
+ },
+ "Order": 1
+ }
+ ]
+ },
+ "IsListviewDataSource": true,
+ "CustomColumns": []
+ },
+ "DataSourceListviewName": "图文列表表格1",
+ "IsLoadOnDemand": true,
+ "LoadOnDemandCount": 30,
+ "TemplateKey": "竖排无样式"
+ }
+ },
+ "10,1": {
"CellType": {
"$type": "EchartsCustomCellType.EchartsCustomCellTypeCellType, EchartsCustomCellType",
"EChartTitle": "工时排行榜",
@@ -503,14 +625,14 @@
"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 \"}"
}
},
- "9,1": {
+ "12,1": {
"CellType": {
"$type": "EchartsCustomCellType.EchartsCustomCellTypeCellType, EchartsCustomCellType",
"EChartTitle": "Echarts图表",
"DataSourceBinding": "DataSources",
"DataSources": [
{
- "Name": "反馈表",
+ "Name": "recommands",
"BindingTableOptions": {
"$type": "ServerDesignerCommon.Model.BindingDataSourceModel, ServerDesignerCommon",
"TableName": "需求反馈登记表",
@@ -617,7 +739,7 @@
],
"JSONDataSources": [],
"ImageDataSource": [],
- "Config": "{\"option\":\"// 处理数据,生成节点和链接 \\nconst processData = (data) => { \\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型)); \\n const projectSet = new Set(data.map(item => item.项目)); \\n const taskSet = new Set(data.map(item => item.任务)); \\n\\n // 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [ \\n // 类型节点 \\n ...Array.from(typeSet).map((name, index) => ({ \\n name: name, \\n depth: 0, // 明确指定深度 \\n itemStyle: { \\n color: '#2196f3' \\n } \\n })), \\n // 项目节点 \\n ...Array.from(projectSet).map((name, index) => ({ \\n name: name, \\n depth: 1, // 明确指定深度 \\n itemStyle: { \\n color: '#ff5722' \\n } \\n })), \\n // 任务节点 \\n ...Array.from(taskSet).map((name, index) => ({ \\n name: name, \\n depth: 2, // 明确指定深度 \\n itemStyle: { \\n color: '#4caf50' \\n } \\n })) \\n ]; \\n\\n // 生成连接数组 \\n const links = []; \\n \\n // 类型 -> 项目的链接 \\n data.forEach(item => { \\n const existingLink = links.find( \\n link => link.source === item.类型 && link.target === item.项目 \\n ); \\n if (existingLink) { \\n existingLink.value += item.数量; \\n } else { \\n links.push({ \\n source: item.类型, \\n target: item.项目, \\n value: item.数量 \\n }); \\n } \\n }); \\n\\n // 项目 -> 任务的链接 \\n data.forEach(item => { \\n const existingLink = links.find( \\n link => link.source === item.项目 && link.target === item.任务 \\n ); \\n if (existingLink) { \\n existingLink.value += item.数量; \\n } else { \\n links.push({ \\n source: item.项目, \\n target: item.任务, \\n value: item.数量 \\n }); \\n } \\n }); \\n\\n return { nodes, links }; \\n}; \\n\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"工时表\\\"]); \\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 tooltip: { \\n trigger: 'item', \\n triggerOn: 'mousemove', \\n backgroundColor: '#fff', \\n borderColor: '#eee', \\n borderWidth: 1, \\n textStyle: { \\n color: '#333' \\n }, \\n formatter: function(params) { \\n if (params.dataType === 'node') { \\n return `${params.name}\\\\n数量: ${params.value}`; \\n } \\n return `${params.source} → ${params.target}\\\\n数量: ${params.value}`; \\n } \\n }, \\n series: [{ \\n type: 'sankey', \\n emphasis: { \\n focus: 'adjacency' \\n }, \\n nodeAlign: 'left', \\n orient: 'horizontal', \\n data: nodes, \\n links: links, \\n layoutIterations: 64, // 增加布局迭代次数,使布局更加均匀 \\n nodeGap: 30, // 调整节点之间的间距 \\n nodeWidth: 20, // 调整节点的宽度 \\n draggable: false, // 禁止拖动,保持布局稳定 \\n lineStyle: { \\n color: 'source', \\n curveness: 0.5, \\n opacity: 0.5 \\n }, \\n levels: [{ \\n depth: 0, \\n itemStyle: { \\n color: '#2196f3' \\n }, \\n lineStyle: { \\n color: 'source', \\n opacity: 0.6 \\n } \\n }, { \\n depth: 1, \\n itemStyle: { \\n color: '#ff5722' \\n }, \\n lineStyle: { \\n color: 'source', \\n opacity: 0.4 \\n } \\n }, { \\n depth: 2, \\n itemStyle: { \\n color: '#4caf50' \\n } \\n }], \\n label: { \\n position: 'right', \\n fontSize: 12, \\n color: '#666', \\n formatter: function(params) { \\n return [ \\n params.name, \\n `数量: ${params.value || 0}` \\n ].join('\\\\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 // 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型));\\n const projectSet = new Set(data.map(item => item.项目));\\n const taskSet = new Set(data.map(item => item.任务));\\n // 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...Array.from(typeSet).map((name, index) => ({\\n name: name,\\n depth: 0,\\n itemStyle: {\\n color: '#2196f3'\\n }\\n })),\\n // 项目节点 \\n ...Array.from(projectSet).map((name, index) => ({\\n name: name,\\n depth: 1,\\n itemStyle: {\\n color: '#ff5722'\\n }\\n })),\\n // 任务节点 \\n ...Array.from(taskSet).map((name, index) => ({\\n name: name,\\n depth: 2,\\n itemStyle: {\\n color: '#4caf50'\\n }\\n }))\\n ];\\n // 生成连接数组 \\n const links = [];\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.类型 && link.target === item.项目);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量\\n });\\n }\\n });\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.项目 && link.target === item.任务);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量\\n });\\n }\\n });\\n return { nodes, links };\\n};\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"工时表\\\"]);\\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 tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n backgroundColor: '#fff',\\n borderColor: '#eee',\\n borderWidth: 1,\\n textStyle: {\\n color: '#333'\\n },\\n formatter: function (params) {\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.source} → ${params.target}\\\\n数量: ${params.value}`;\\n }\\n },\\n series: [{\\n type: 'sankey',\\n emphasis: {\\n focus: 'adjacency'\\n },\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n layoutIterations: 64,\\n nodeGap: 30,\\n nodeWidth: 20,\\n draggable: false,\\n lineStyle: {\\n color: 'source',\\n curveness: 0.5,\\n opacity: 0.5\\n },\\n levels: [{\\n depth: 0,\\n itemStyle: {\\n color: '#2196f3'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.6\\n }\\n }, {\\n depth: 1,\\n itemStyle: {\\n color: '#ff5722'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.4\\n }\\n }, {\\n depth: 2,\\n itemStyle: {\\n color: '#4caf50'\\n }\\n }],\\n label: {\\n position: 'right',\\n fontSize: 12,\\n color: '#666',\\n formatter: function (params) {\\n return [\\n params.name,\\n `数量: ${params.value || 0}`\\n ].join('\\\\n');\\n }\\n }\\n }]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}"
+ "Config": "{\"option\":\"console.log(Context[\\\"recommands\\\"]);\\n\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型));\\n const projectSet = new Set(data.map(item => item.项目));\\n const taskSet = new Set(data.map(item => item.任务));\\n\\n // 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...Array.from(typeSet).map((name, index) => ({\\n name: name,\\n depth: 0, // 明确指定深度 \\n itemStyle: {\\n color: '#2196f3'\\n }\\n })),\\n // 项目节点 \\n ...Array.from(projectSet).map((name, index) => ({\\n name: name,\\n depth: 1, // 明确指定深度 \\n itemStyle: {\\n color: '#ff5722'\\n }\\n })),\\n // 任务节点 \\n ...Array.from(taskSet).map((name, index) => ({\\n name: name,\\n depth: 2, // 明确指定深度 \\n itemStyle: {\\n color: '#4caf50'\\n }\\n }))\\n ];\\n\\n // 生成连接数组 \\n const links = [];\\n\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.类型 && link.target === item.项目\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量\\n });\\n }\\n });\\n\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(\\n link => link.source === item.项目 && link.target === item.任务\\n );\\n if (existingLink) {\\n existingLink.value += item.数量;\\n } else {\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量\\n });\\n }\\n });\\n\\n return { nodes, links };\\n};\\n\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n}\\n\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\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 tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n backgroundColor: '#fff',\\n borderColor: '#eee',\\n borderWidth: 1,\\n textStyle: {\\n color: '#333'\\n },\\n formatter: gettooltip\\n },\\n series: [{\\n type: 'sankey',\\n emphasis: {\\n focus: 'adjacency'\\n },\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n layoutIterations: 64, // 增加布局迭代次数,使布局更加均匀 \\n nodeGap: 30, // 调整节点之间的间距 \\n nodeWidth: 20, // 调整节点的宽度 \\n draggable: false, // 禁止拖动,保持布局稳定 \\n lineStyle: {\\n color: 'source',\\n curveness: 0.5,\\n opacity: 0.5\\n },\\n levels: [{\\n depth: 0,\\n itemStyle: {\\n color: '#2196f3'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.6\\n }\\n }, {\\n depth: 1,\\n itemStyle: {\\n color: '#ff5722'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.4\\n }\\n }, {\\n depth: 2,\\n itemStyle: {\\n color: '#4caf50'\\n }\\n }],\\n label: {\\n position: 'right',\\n fontSize: 12,\\n color: '#666',\\n formatter: function (params) {\\n return [\\n params.name,\\n `数量: ${params.value || 0}`\\n ].join('\\\\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 console.log(Context[\\\"recommands\\\"]);\\n// 处理数据,生成节点和链接 \\nconst processData = (data) => {\\n // 收集所有唯一的节点 \\n const typeSet = new Set(data.map(item => item.类型));\\n const projectSet = new Set(data.map(item => item.项目));\\n const taskSet = new Set(data.map(item => item.任务));\\n // 生成节点数组,确保节点按照类型、项目、任务的顺序排列 \\n const nodes = [\\n // 类型节点 \\n ...Array.from(typeSet).map((name, index) => ({\\n name: name,\\n depth: 0,\\n itemStyle: {\\n color: '#2196f3'\\n }\\n })),\\n // 项目节点 \\n ...Array.from(projectSet).map((name, index) => ({\\n name: name,\\n depth: 1,\\n itemStyle: {\\n color: '#ff5722'\\n }\\n })),\\n // 任务节点 \\n ...Array.from(taskSet).map((name, index) => ({\\n name: name,\\n depth: 2,\\n itemStyle: {\\n color: '#4caf50'\\n }\\n }))\\n ];\\n // 生成连接数组 \\n const links = [];\\n // 类型 -> 项目的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.类型 && link.target === item.项目);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.类型,\\n target: item.项目,\\n value: item.数量\\n });\\n }\\n });\\n // 项目 -> 任务的链接 \\n data.forEach(item => {\\n const existingLink = links.find(link => link.source === item.项目 && link.target === item.任务);\\n if (existingLink) {\\n existingLink.value += item.数量;\\n }\\n else {\\n links.push({\\n source: item.项目,\\n target: item.任务,\\n value: item.数量\\n });\\n }\\n });\\n return { nodes, links };\\n};\\n//获取提示文字\\nconst gettooltip = (params) => {\\n console.log(params);\\n if (params.dataType === 'node') {\\n return `${params.name}\\\\n数量: ${params.value}`;\\n }\\n return `${params.data.source} → ${params.data.target}\\\\n数量: ${params.value}`;\\n};\\n// 处理数据 \\nconst { nodes, links } = processData(Context[\\\"recommands\\\"]);\\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 tooltip: {\\n trigger: 'item',\\n triggerOn: 'mousemove',\\n backgroundColor: '#fff',\\n borderColor: '#eee',\\n borderWidth: 1,\\n textStyle: {\\n color: '#333'\\n },\\n formatter: gettooltip\\n },\\n series: [{\\n type: 'sankey',\\n emphasis: {\\n focus: 'adjacency'\\n },\\n nodeAlign: 'left',\\n orient: 'horizontal',\\n data: nodes,\\n links: links,\\n layoutIterations: 64,\\n nodeGap: 30,\\n nodeWidth: 20,\\n draggable: false,\\n lineStyle: {\\n color: 'source',\\n curveness: 0.5,\\n opacity: 0.5\\n },\\n levels: [{\\n depth: 0,\\n itemStyle: {\\n color: '#2196f3'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.6\\n }\\n }, {\\n depth: 1,\\n itemStyle: {\\n color: '#ff5722'\\n },\\n lineStyle: {\\n color: 'source',\\n opacity: 0.4\\n }\\n }, {\\n depth: 2,\\n itemStyle: {\\n color: '#4caf50'\\n }\\n }],\\n label: {\\n position: 'right',\\n fontSize: 12,\\n color: '#666',\\n formatter: function (params) {\\n return [\\n params.name,\\n `数量: ${params.value || 0}`\\n ].join('\\\\n');\\n }\\n }\\n }]\\n};\\n\\n return {\\n option,\\n datGUI,\\n };\\n }\\n \"}"
}
}
},
@@ -626,34 +748,90 @@
{
"FontSize": 37.33333333333333,
"Foreground": 0
+ },
+ {
+ "HorizontalAlignment": 1
+ },
+ {
+ "FontFamily": 2,
+ "FontSize": 37.33333333333333,
+ "Foreground": 0,
+ "HorizontalAlignment": 3
}
],
"Types": {
"Strs": [
"Background 1 -15",
+ "Left",
"Body",
"Center"
]
},
"CellStyles": {
"1,38": 0,
- "5,38": 0,
- "7,1": 0,
- "9,1": 0
+ "1,40": 0,
+ "2,40": 0,
+ "3,40": 0,
+ "6,39": 1,
+ "8,39": 2,
+ "8,40": 2,
+ "9,40": 2,
+ "10,1": 0,
+ "10,40": 2,
+ "11,40": 2,
+ "12,1": 0,
+ "12,40": 2,
+ "13,1": 0,
+ "13,2": 0,
+ "13,3": 0,
+ "13,4": 0,
+ "13,5": 0,
+ "13,6": 0,
+ "13,7": 0,
+ "13,8": 0,
+ "13,9": 0,
+ "13,10": 0,
+ "13,11": 0,
+ "13,12": 0,
+ "13,13": 0,
+ "13,14": 0,
+ "13,15": 0,
+ "13,16": 0,
+ "13,17": 0,
+ "13,18": 0,
+ "13,19": 0,
+ "13,20": 0,
+ "13,21": 0,
+ "13,22": 0,
+ "13,23": 0,
+ "13,24": 0,
+ "13,25": 0,
+ "13,26": 0,
+ "13,27": 0,
+ "13,28": 0,
+ "13,29": 0,
+ "13,30": 0,
+ "13,31": 0,
+ "13,32": 0,
+ "13,33": 0,
+ "13,34": 0,
+ "13,35": 0,
+ "13,36": 0,
+ "13,40": 2
},
"SheetStyle": {
- "FontFamily": 1,
- "HorizontalAlignment": 2
+ "FontFamily": 2,
+ "HorizontalAlignment": 3
}
},
"Spans": [
- "1,38,3,1",
- "5,38,5,1",
+ "1,38,3,3",
"1,1,1,36",
"3,1,1,36",
- "5,1,1,36",
- "7,1,1,36",
- "9,1,1,36"
+ "5,1,4,36",
+ "10,1,1,36",
+ "12,1,2,36",
+ "8,39,5,1"
],
"PageInfo": {
"$type": "Forguncy.Model.Pages.NormalPage, ServerDesignerCommon",
@@ -697,7 +875,7 @@
"Fill": "Background 2 0"
},
"IsAutomaticFill": false,
- "Size": "1530,1224"
+ "Size": "1553,1245"
},
{
"Name": "0f5baa2c-2dec-44c7-8a3f-45868371fe7b.png",
@@ -707,7 +885,7 @@
"Fill": "Background 1 0"
},
"IsAutomaticFill": false,
- "Location": "24,220",
+ "Location": "24,234",
"Size": "1152,300"
},
{
@@ -719,7 +897,7 @@
},
"IsAutomaticFill": false,
"Location": "1186,15",
- "Size": "320,195"
+ "Size": "343,209"
},
{
"Name": "75cbd09e-882c-427a-a52b-ba015444352e.png",
@@ -729,8 +907,8 @@
"Fill": "Background 1 0"
},
"IsAutomaticFill": false,
- "Location": "1186,220",
- "Size": "320,957"
+ "Location": "1186,234",
+ "Size": "343,964"
},
{
"Name": "9585c733-c922-4ba2-8923-e5c50a4f429c.png",
@@ -740,7 +918,7 @@
"Fill": "Background 1 0"
},
"IsAutomaticFill": false,
- "Location": "24,530",
+ "Location": "24,544",
"Size": "1152,383"
},
{
@@ -751,8 +929,8 @@
"Fill": "Background 1 0"
},
"IsAutomaticFill": false,
- "Location": "24,923",
- "Size": "1152,254"
+ "Location": "24,937",
+ "Size": "1152,261"
}
]
-}//IQqcyQKyecg6I0rAgI3RCrXGqrGYd49pii7OwyD90tQy8w/rCBEUsKZcQGOveEYLfUtRZQiDf/yyd2dPFw7syBMg/gYE5V4YzAd7h3pBxn5Ol1VJdikD46Pr+rM0MWY0YcSpfFn0AcVGAY+efla/9xVwvsS7EtcPohtgykhB76xDCuiirEKLSETKE3CAfecfOpHswIIzwnCI+FKk0nZe9cpyYHiYSFJbKd0ZvzplO+z6XIWKz9Qi7l7pOWcWAJOrP7+HP0VZFmDUvvJMMuWrDRZOhaZ7qn8bXh4F0fjCx6G1QrQNxAXIvH/gpeqwJvSbL4NZNIOai96ynOsp9bMI3hv7pJTlSYSRyHmoXpYVKiEdOEOq5zgkv6cAc2vDRHScqp3f/IwveWHAYNqsSyOz3vJi0aV134a0jCvnh20cK+FCh+Z7vsgVxhZ1XEgTMmu+5U+4Ce8U95bbZN0aUretum6E/i82UAT0ENWKGWo9qZ3hNFfvLFBbP323ncgxhbNqGuGLp5nnxwymJm5G8A+BuyolkPNOwz5r7k2Bz2mILr57CBdjc6xUkFoUR9xnA38Hyf5S89I5gjdA0OvTLQg6/T9fZ3omoA4DdBIyWrdgv4ymdoUoP1+j4W0QwCy/aK5Zuuno3+//taZr38UAAqRpxDGalccGJ2tk03/evz1vOR5nRZum+FnkkLJjh76aUjryx8Si3yx0WBL60oNesErxueAgzOHRRKs8IMAtlSskDIvyk71kghMTQxnqh0rIxOigLniZ92IOGvY9wOZ1E/60RvU3IjXOHG7o9KsAq1UVZRKK8oZ4Rf4873LRyK/bJ4sk9eAHfIQGGZe+vTnWeaNAFnf2BVWK5uum6IU5yy/Qy7SUD7wYoR24iCzW2+CCwPdg1uwdR6wvJoP+ALU8A41HiQ==|920
\ No newline at end of file
+}//jK8Q357Mi2QKIpuGYxu/T4GpwgE95aCzIn1/vnraipT0XN1oIW7pEtn5iUOCTPVrJFIfg298YYQg0w4XZFED2XOIN29hY2nUrm4ZGMLdB5aTp/0q6pA0ouFJZe+HcP85HEnsen9xhRfQrVQ422bnrK5q8xRWN+jNzDn9/MKsEKCTP6pvuRKW6HXt/GvBRtsqTUKwxA7wmybzeIXMihUHNtXss1yQsPOn+vfmHeKPaXEBAQA4REeuTuGc7smIedb8B3elUuj3bG9Uo6hUjmQU2H2l12R6NtOEOOZ56Hm3stCNmCuUfPTPY23EtscxO9qj3MU5vrNBw0VwV3ul8Jz8SjZSSEVvANX5OTE/Pt+97Z5dggUEjmHlj/xIkXpveQZHR9fn0X+Fx5ZY2mcYU84ScvPzzYtVIwgolqWvX+MzflZKFtVVUQNdaxLIMkq9hUeiEwobvAVPQ0buU48t3BTugQilj+l82YBYUC0KuEjNOFNdX8SCsei37lfcPZQZLwYPXC2VgtJYCcPQ0sa254DZJ6ifHvMg8ufGUi865pd36iOf8gLWaZC7JGU0rAe8e6xxsmvEDqv9P3bQUWmU+6tg/jleHdg86oASlEeb5paWxoM1di/boG/gPy79G9L8KIyQtuKPMQtUAKnBBy8fTppyLJxV78IuULUtjIKhUpYlgFX/pzU8luSStJWvaObdMZfbJ1UgOTMqMKuyw2h+YE7Od0/ptFAWz70HiDxVEOVduHghipwKb3X//IPD4d5uVITJ+8r+WRluTEtmjmj4vIMsXcoo0ICCR2uU7/n4S7qWsFahci39DfDX4Qp8sJMmAFfUiVdddIF41HBQR0sjFmwU12apGW1GyXv8b9qEUykDvF5bLGl1EJ7bUkZlCJeGIPBW6aa/UxujwxlcRVao9CsPIQ==|920
\ No newline at end of file
diff --git a/Pages/工作台/工作台首页.rd b/Pages/工作台/工作台首页.rd
index 86914c9b..348e6258 100644
--- a/Pages/工作台/工作台首页.rd
+++ b/Pages/工作台/工作台首页.rd
@@ -1,5 +1,5 @@
{
"PageType": 0,
- "ColumnCount": 40,
- "RowCount": 12
+ "ColumnCount": 42,
+ "RowCount": 16
}
\ No newline at end of file
diff --git a/ServerCommands/项目/新增或修改项目.json b/ServerCommands/项目/新增或修改项目.json
index 4c4247a2..5e494602 100644
--- a/ServerCommands/项目/新增或修改项目.json
+++ b/ServerCommands/项目/新增或修改项目.json
@@ -257,11 +257,11 @@
"ErrorCode": "400",
"Message": {
"$type": "Forguncy.Model.FormulaReferObject, ServerDesignerCommon",
- "SerializeProperty": "=\"项目总核定工时已超标,无法为您切换为严格模式!\""
+ "SerializeProperty": "=\"当前项目总核定工时为\"&项目信息.项目总核定工时&\",低于预算工时\"&项目信息.项目预算工时&\",无法为您切换为严格模式!\""
}
}
],
- "ID": "cec38e27-e103-472a-bc40-9b4130803fb5"
+ "ID": "d47756ef-74d6-44b6-8126-c60bbcce3ab7"
},
{
"Condition": {
@@ -285,17 +285,17 @@
"ErrorCode": "400",
"Message": {
"$type": "Forguncy.Model.FormulaReferObject, ServerDesignerCommon",
- "SerializeProperty": "=\"项目费用已超标,此时无法为您切换为严格模式\""
+ "SerializeProperty": "=\"当前项目消耗成本为\"&项目信息.已消耗成本&\",低于预算费用\"&项目信息.项目预算费用&\",无法为您切换为严格模式\""
}
}
],
- "ID": "da641921-20b5-4e5e-8d42-dfa84e05eb94"
+ "ID": "900e7e9a-bbf3-46d5-baa2-c8568fb35d45"
}
]
}
],
"Comments": "如果是更新项目,且改变了严格模式,那么就要校验。超标就不允许切换",
- "ID": "767ccea8-519f-4580-8cdd-746b41248d21"
+ "ID": "b84fc0b5-ed1c-4a76-8545-4ebc4a20a87d"
}
]
},