feat: 增加工时报表导出并调整质量菜单

This commit is contained in:
2026-07-11 17:56:29 +08:00
parent 345f39386d
commit 078474631f
3 changed files with 244 additions and 7 deletions

View File

@@ -25,7 +25,7 @@ BEGIN
( (
SELECT SELECT
src.[], src.[],
COALESCE(prodParent.[id], src.[pid]) AS [pid], qualityParent.[id] AS [pid],
src.[icon], src.[icon],
src.[AddData], src.[AddData],
src.[DeleteData], src.[DeleteData],
@@ -37,13 +37,15 @@ BEGIN
SELECT TOP (1) rp.[id] SELECT TOP (1) rp.[id]
FROM [dbo].[_二级菜单] AS rp FROM [dbo].[_二级菜单] AS rp
WHERE rp.[] = src.[] WHERE rp.[] = src.[]
AND rp.[pid] = 0
AND rp.[] = 1 AND rp.[] = 1
AND rp.[title] = N'生产管理' AND (rp.[title] = N'质量管理' OR rp.[path] = '/QualityManagement' OR rp.[name] = 'QualityManagement')
ORDER BY rp.[id] ORDER BY rp.[id]
) AS prodParent ) AS qualityParent
WHERE src.[] = 1 WHERE src.[] = 1
AND (@TargetRole IS NULL OR src.[] = @TargetRole) AND (@TargetRole IS NULL OR src.[] = @TargetRole)
AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪') AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪')
AND qualityParent.[id] IS NOT NULL
AND NOT EXISTS AND NOT EXISTS
( (
SELECT 1 SELECT 1
@@ -77,7 +79,7 @@ BEGIN
SELECT SELECT
ROW_NUMBER() OVER (ORDER BY src.[], src.[id]) AS rn, ROW_NUMBER() OVER (ORDER BY src.[], src.[id]) AS rn,
src.[], src.[],
COALESCE(prodParent.[id], src.[pid]) AS [pid], qualityParent.[id] AS [pid],
src.[icon], src.[icon],
src.[AddData], src.[AddData],
src.[DeleteData], src.[DeleteData],
@@ -89,13 +91,15 @@ BEGIN
SELECT TOP (1) rp.[id] SELECT TOP (1) rp.[id]
FROM [dbo].[_二级菜单] AS rp FROM [dbo].[_二级菜单] AS rp
WHERE rp.[] = src.[] WHERE rp.[] = src.[]
AND rp.[pid] = 0
AND rp.[] = 1 AND rp.[] = 1
AND rp.[title] = N'生产管理' AND (rp.[title] = N'质量管理' OR rp.[path] = '/QualityManagement' OR rp.[name] = 'QualityManagement')
ORDER BY rp.[id] ORDER BY rp.[id]
) AS prodParent ) AS qualityParent
WHERE src.[] = 1 WHERE src.[] = 1
AND (@TargetRole IS NULL OR src.[] = @TargetRole) AND (@TargetRole IS NULL OR src.[] = @TargetRole)
AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪') AND (src.[path] = @SourcePath OR src.[componet] = @SourceComponent OR src.[title] = N'生产计划跟踪')
AND qualityParent.[id] IS NOT NULL
AND NOT EXISTS AND NOT EXISTS
( (
SELECT 1 SELECT 1
@@ -132,6 +136,24 @@ END;
UPDATE [dbo].[_二级菜单] UPDATE [dbo].[_二级菜单]
SET SET
[pid] = COALESCE
(
(
SELECT TOP (1) qualityParent.[id]
FROM [dbo].[_二级菜单] AS qualityParent
WHERE qualityParent.[] = [dbo].[_二级菜单].[]
AND qualityParent.[pid] = 0
AND qualityParent.[] = 1
AND
(
qualityParent.[title] = N'质量管理'
OR qualityParent.[path] = '/QualityManagement'
OR qualityParent.[name] = 'QualityManagement'
)
ORDER BY qualityParent.[id]
),
[pid]
),
[path] = @Path, [path] = @Path,
[componet] = @Component, [componet] = @Component,
[name] = @Name, [name] = @Name,
@@ -144,4 +166,3 @@ SELECT [id], [pid], [path], [componet], [name], [title], [icon], [账号代码],
FROM [dbo].[_二级菜单] FROM [dbo].[_二级菜单]
WHERE [path] = @Path OR [componet] = @Component OR [title] = @Title WHERE [path] = @Path OR [componet] = @Component OR [title] = @Title
ORDER BY [], [id]; ORDER BY [], [id];

View File

@@ -0,0 +1,124 @@
USE [YL_MESDB];
GO
SET NOCOUNT ON;
SET XACT_ABORT ON;
DECLARE @QualityMenuId int = 4;
DECLARE @TargetAccounts TABLE
(
[] int PRIMARY KEY
);
INSERT INTO @TargetAccounts ([])
SELECT DISTINCT []
FROM [dbo].[_二级菜单]
WHERE [path] = 'ProductPassRateWorkstation/index'
OR [componet] = '/ProductionManagement/ProductPassRateWorkstation/index'
OR [name] = 'ProductPassRateWorkstation'
OR [title] IN (N'产品合格率工位', N'产品合格率(工位)');
IF NOT EXISTS (SELECT 1 FROM @TargetAccounts)
BEGIN
THROW 50001, N'未找到产品合格率工位菜单,未执行迁移。', 1;
END;
BEGIN TRANSACTION;
IF EXISTS
(
SELECT 1
FROM @TargetAccounts AS target
INNER JOIN [dbo].[_二级菜单] AS menu WITH (UPDLOCK, HOLDLOCK)
ON menu.[] = target.[]
AND menu.[id] = @QualityMenuId
WHERE menu.[pid] <> 0
OR menu.[path] <> '/QualityManagement'
OR menu.[name] <> 'QualityManagement'
OR menu.[title] <> N'质量管理'
)
BEGIN
THROW 50002, N'目标账号的菜单 ID 4 已被其他菜单占用,未执行迁移。', 1;
END;
INSERT INTO [dbo].[_二级菜单]
([id], [pid], [path], [componet], [redirect], [name], [title], [icon], [], [], [], [])
SELECT
@QualityMenuId,
0,
'/QualityManagement',
'/layout/Layout',
NULL,
'QualityManagement',
N'质量管理',
'KKIMaintenance',
target.[],
@QualityMenuId,
GETDATE(),
1
FROM @TargetAccounts AS target
WHERE NOT EXISTS
(
SELECT 1
FROM [dbo].[_二级菜单] AS existing WITH (UPDLOCK, HOLDLOCK)
WHERE existing.[] = target.[]
AND existing.[id] = @QualityMenuId
);
UPDATE qualityMenu
SET
qualityMenu.[pid] = 0,
qualityMenu.[path] = '/QualityManagement',
qualityMenu.[componet] = '/layout/Layout',
qualityMenu.[redirect] = NULL,
qualityMenu.[name] = 'QualityManagement',
qualityMenu.[title] = N'质量管理',
qualityMenu.[icon] = 'KKIMaintenance',
qualityMenu.[] = @QualityMenuId,
qualityMenu.[] = 1,
qualityMenu.[] = GETDATE()
FROM [dbo].[_二级菜单] AS qualityMenu
INNER JOIN @TargetAccounts AS target
ON target.[] = qualityMenu.[]
WHERE qualityMenu.[id] = @QualityMenuId;
UPDATE targetMenu
SET
targetMenu.[pid] = @QualityMenuId,
targetMenu.[path] = 'ProductPassRateWorkstation/index',
targetMenu.[componet] = '/ProductionManagement/ProductPassRateWorkstation/index',
targetMenu.[redirect] = NULL,
targetMenu.[name] = 'ProductPassRateWorkstation',
targetMenu.[title] = N'产品合格率(工位)',
targetMenu.[] = targetMenu.[id],
targetMenu.[] = 1,
targetMenu.[] = GETDATE()
FROM [dbo].[_二级菜单] AS targetMenu
INNER JOIN @TargetAccounts AS target
ON target.[] = targetMenu.[]
WHERE targetMenu.[path] = 'ProductPassRateWorkstation/index'
OR targetMenu.[componet] = '/ProductionManagement/ProductPassRateWorkstation/index'
OR targetMenu.[name] = 'ProductPassRateWorkstation'
OR targetMenu.[title] IN (N'产品合格率工位', N'产品合格率(工位)');
COMMIT TRANSACTION;
SELECT
menu.[id],
menu.[pid],
menu.[path],
menu.[componet],
menu.[name],
menu.[title],
menu.[],
menu.[],
menu.[]
FROM [dbo].[_二级菜单] AS menu
INNER JOIN @TargetAccounts AS target
ON target.[] = menu.[]
WHERE menu.[id] = @QualityMenuId
OR menu.[path] = 'ProductPassRateWorkstation/index'
OR menu.[componet] = '/ProductionManagement/ProductPassRateWorkstation/index'
ORDER BY menu.[], menu.[pid], menu.[id];
GO

View File

@@ -63,6 +63,15 @@
<span class="show-text">任务ID:</span> <span class="show-text">任务ID:</span>
<el-input v-model="searchForm.did" clearable size="small" style="width: 90px; margin-right: 8px" /> <el-input v-model="searchForm.did" clearable size="small" style="width: 90px; margin-right: 8px" />
<el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="searchTable">查询</el-button> <el-button :loading="loading" icon="el-icon-search" plain size="small" type="primary" @click="searchTable">查询</el-button>
<el-button
:disabled="loading || tableData.length === 0"
:loading="exporting"
icon="el-icon-download"
plain
size="small"
type="success"
@click="exportToExcel"
>导出</el-button>
</div> </div>
<el-table <el-table
@@ -110,11 +119,14 @@
</template> </template>
<script> <script>
import * as XLSX from 'xlsx'
export default { export default {
name: 'DesignReportHoursReport', name: 'DesignReportHoursReport',
data() { data() {
return { return {
loading: false, loading: false,
exporting: false,
tableData: [], tableData: [],
projectOptions: [], projectOptions: [],
materialOptions: [], materialOptions: [],
@@ -176,6 +188,86 @@ export default {
this.loading = false this.loading = false
} }
}, },
exportToExcel() {
if (this.tableData.length === 0) {
this.$message.warning('没有数据可导出')
return
}
this.exporting = true
try {
const rows = this.flattenTree(this.tableData)
const exportData = rows.map(row => ({
层级: row.Level === 1 ? '操作人汇总' : (row.Level === 2 ? '日期汇总' : '任务明细'),
'操作人 / 日期 / 任务': `${' '.repeat(Math.max((row.Level || 1) - 1, 0))}${this.getTreeTitle(row)}`,
工作日期: this.getExportValue(row.工作日期),
RID: this.getExportValue(row.RID),
DID: this.getExportValue(row.DID),
项目号: this.getExportValue(row.项目号),
物料编码: this.getExportValue(row.物料编码),
物料名称: this.getExportValue(row.物料名称),
图号: this.getExportValue(row.图号),
类别: this.getExportValue(row.类别),
报工次数: this.getExportValue(row.报工次数),
'工时(h)': this.formatHours(row.工时小时),
开始时间: this.getExportValue(row.开始时间),
结束时间: this.getExportValue(row.结束时间),
校验状态: this.getExportValue(row.校验状态),
进度说明: this.getExportValue(row.进度说明),
备注: this.getExportValue(row.备注)
}))
const workbook = XLSX.utils.book_new()
const worksheet = XLSX.utils.json_to_sheet(exportData)
worksheet['!cols'] = [
{ wch: 12 },
{ wch: 32 },
{ wch: 14 },
{ wch: 10 },
{ wch: 10 },
{ wch: 16 },
{ wch: 22 },
{ wch: 24 },
{ wch: 16 },
{ wch: 16 },
{ wch: 12 },
{ wch: 12 },
{ wch: 20 },
{ wch: 20 },
{ wch: 14 },
{ wch: 30 },
{ wch: 30 }
]
XLSX.utils.book_append_sheet(workbook, worksheet, '设计工时报表')
XLSX.writeFile(workbook, `设计工时报表_${this.formatDateForFileName(new Date())}.xlsx`)
this.$message.success('导出成功')
} catch (error) {
console.error('设计工时报表导出失败:', error)
this.$message.error('导出失败')
} finally {
this.exporting = false
}
},
flattenTree(rows) {
return rows.reduce((result, row) => {
result.push(row)
if (row.children && row.children.length > 0) {
result.push(...this.flattenTree(row.children))
}
return result
}, [])
},
getExportValue(value) {
return value === null || value === undefined ? '' : value
},
formatDateForFileName(date) {
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
const seconds = String(date.getSeconds()).padStart(2, '0')
return `${year}${month}${day}_${hours}${minutes}${seconds}`
},
async queryProjects(query) { async queryProjects(query) {
const data = this.CreateData('11', '设计报工_项目查询', [['过滤', query || '']]) const data = this.CreateData('11', '设计报工_项目查询', [['过滤', query || '']])
try { try {