提交
This commit is contained in:
parent
d520288bca
commit
92d22a29b6
|
@ -4,7 +4,9 @@
|
|||
<i class="el-icon-arrow-left"/>
|
||||
</div>
|
||||
<div class="title">
|
||||
{{title}}
|
||||
<slot name="title">
|
||||
{{title}}
|
||||
</slot>
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot/>
|
||||
|
|
|
@ -120,6 +120,11 @@
|
|||
:user-query="userQuery"
|
||||
/>
|
||||
|
||||
<user-prod-preview
|
||||
:show.sync="showUserProdPreview"
|
||||
:data="currentPreviewData"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
@ -140,6 +145,7 @@ import HoverShow from "@/components/HoverShow/index.vue";
|
|||
import ReportProductRowEdit from "@/views/yh/report/edit/components/ReportProductRowEdit.vue";
|
||||
import PriceDrawer from "@/components/Business/Price/PriceDrawer.vue";
|
||||
import {calcTotalAmount} from "@/views/yh/report/utils";
|
||||
import UserProdPreview from './UserProdPreview.vue'
|
||||
|
||||
export default {
|
||||
name: "ReportProductEdit",
|
||||
|
@ -151,7 +157,7 @@ export default {
|
|||
Dict,
|
||||
ReportProductUserListEdit,
|
||||
ReportProductOrderListEdit,
|
||||
UserProductBatchDialog, FormCol, PriceInput, PriceDialog, UserInput},
|
||||
UserProductBatchDialog, FormCol, PriceInput, PriceDialog, UserInput, UserProdPreview},
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
|
@ -226,6 +232,8 @@ export default {
|
|||
showMore: false,
|
||||
editingIndex: -1, // 当前正在编辑的工序索引
|
||||
isAllSelected: false,
|
||||
showUserProdPreview: false,
|
||||
currentPreviewData: null,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -418,6 +426,10 @@ export default {
|
|||
item.selected = !item.selected;
|
||||
this.handleSelect(item, item.selected);
|
||||
},
|
||||
handlePreview(row) {
|
||||
this.currentPreviewData = row;
|
||||
this.showUserProdPreview = true;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -496,6 +508,20 @@ export default {
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
.preview-icon {
|
||||
color: #909399;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
background-color: rgba(64, 158, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
color: #909399;
|
||||
cursor: pointer;
|
||||
|
@ -618,5 +644,19 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.preview-icon {
|
||||
color: #909399;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
background-color: rgba(64, 158, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
|
345
src/views/yh/report/edit/components/UserProdPreview.vue
Normal file
345
src/views/yh/report/edit/components/UserProdPreview.vue
Normal file
|
@ -0,0 +1,345 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
title="员工产量明细"
|
||||
:visible.sync="visible"
|
||||
width="90%"
|
||||
close-on-click-modal
|
||||
append-to-body
|
||||
>
|
||||
<div class="preview-container" v-if="data != null">
|
||||
<!-- 汇总信息 -->
|
||||
<div class="summary-info">
|
||||
<div class="info-item">
|
||||
<span class="label">日期:</span>
|
||||
<span class="value">{{ data.reportDate | dv}}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">总金额:</span>
|
||||
<span class="value highlight">{{ totalAmount | dv}} 元</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 透视表 -->
|
||||
<el-table
|
||||
v-if="tableData.length"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
size="small"
|
||||
border
|
||||
:header-cell-style="{ background: '#f5f7fa' }"
|
||||
:cell-style="{ padding: '8px 4px' }"
|
||||
>
|
||||
<!-- 员工列 -->
|
||||
<el-table-column
|
||||
prop="userName"
|
||||
label="员工"
|
||||
fixed="left"
|
||||
min-width="100"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="user-name">{{ scope.row.userName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 动态生成工序列 -->
|
||||
<el-table-column
|
||||
v-for="process in processList"
|
||||
:key="process.priceId"
|
||||
:label="process.priceName"
|
||||
align="center"
|
||||
min-width="200"
|
||||
>
|
||||
<template slot="header" slot-scope="scope">
|
||||
<div class="process-header">
|
||||
<div class="process-title">
|
||||
<div class="process-name" :title="process.priceName">{{ process.priceName }}</div>
|
||||
<div class="process-code" :title="process.priceCode">{{ process.priceCode }}</div>
|
||||
</div>
|
||||
<div class="process-info">
|
||||
<span class="info-item">
|
||||
<i class="el-icon-box"></i>
|
||||
<span>{{ process.num }}{{ process.priceUnit }}</span>
|
||||
</span>
|
||||
<span class="info-item">
|
||||
<i class="el-icon-money"></i>
|
||||
<span>{{ process.pricePrice }}元/{{ process.priceUnit }}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<template v-if="scope.row.products[process.priceId]">
|
||||
<div class="prod-cell">
|
||||
<div class="prod-num">
|
||||
<span class="num">{{ scope.row.products[process.priceId].num }}</span>
|
||||
<span class="unit">{{ process.priceUnit }}</span>
|
||||
</div>
|
||||
<div class="prod-amount">
|
||||
<span class="amount">{{ calculateIncome(scope.row.products[process.priceId].num, process.pricePrice) }}</span>
|
||||
<span class="unit">元</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 合计列 -->
|
||||
<el-table-column
|
||||
label="合计金额"
|
||||
fixed="right"
|
||||
min-width="120"
|
||||
align="center"
|
||||
class-name="total-column"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span class="total-income">{{ scope.row.totalAmount }}元</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 添加空状态 -->
|
||||
<el-empty v-else description="暂无数据" />
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<el-button @click="visible = false">关 闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { notNullDecimal } from "@/utils";
|
||||
import Decimal from "decimal.js";
|
||||
|
||||
export default {
|
||||
name: "UserProdPreview",
|
||||
props: {
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 获取所有工序列表
|
||||
processList() {
|
||||
return (this.data?.productList || []).filter(item =>
|
||||
item && item.userProdList && item.userProdList.length > 0
|
||||
);
|
||||
},
|
||||
// 计算表格数据
|
||||
tableData() {
|
||||
if (!this.data || !this.data.productList) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const userMap = new Map();
|
||||
|
||||
// 遍历所有工序
|
||||
this.processList.forEach(process => {
|
||||
if (!process.userProdList) return;
|
||||
|
||||
// 遍历工序下的所有用户产量
|
||||
process.userProdList.forEach(userProd => {
|
||||
if (!userProd || !userProd.userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userMap.has(userProd.userId)) {
|
||||
userMap.set(userProd.userId, {
|
||||
userId: userProd.userId,
|
||||
userName: userProd.userName || '',
|
||||
products: {},
|
||||
totalAmount: 0
|
||||
});
|
||||
}
|
||||
|
||||
const userData = userMap.get(userProd.userId);
|
||||
userData.products[process.priceId] = {
|
||||
num: userProd.num || 0,
|
||||
amount: this.calculateIncome(userProd.num, process.pricePrice)
|
||||
};
|
||||
userData.totalAmount = new Decimal(userData.totalAmount)
|
||||
.plus(userData.products[process.priceId].amount)
|
||||
.toNumber();
|
||||
});
|
||||
});
|
||||
|
||||
return Array.from(userMap.values());
|
||||
},
|
||||
// 计算总金额
|
||||
totalAmount() {
|
||||
if (!this.tableData.length) return '0.00';
|
||||
|
||||
return this.tableData.reduce((sum, row) => {
|
||||
return new Decimal(sum).plus(row.totalAmount || 0).toNumber();
|
||||
}, 0).toFixed(2);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show: {
|
||||
handler(val) {
|
||||
this.visible = val;
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
visible(val) {
|
||||
if (!val) {
|
||||
this.$emit('update:show', false);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 计算工资
|
||||
calculateIncome(num, price) {
|
||||
if (!num || !price) return '0.00';
|
||||
return new Decimal(num || 0)
|
||||
.mul(notNullDecimal(price || 0))
|
||||
.toFixed(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.preview-container {
|
||||
.summary-info {
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
|
||||
.info-item {
|
||||
.label {
|
||||
color: #606266;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
|
||||
&.highlight {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
.process-header {
|
||||
padding: 4px;
|
||||
|
||||
.process-title {
|
||||
margin-bottom: 4px;
|
||||
|
||||
.process-name {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.process-code {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.process-info {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
padding-top: 4px;
|
||||
border-top: 1px dashed #ebeef5;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.prod-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
.prod-num {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
|
||||
.unit {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.prod-amount {
|
||||
font-size: 12px;
|
||||
color: #67c23a;
|
||||
|
||||
.unit {
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.total-column {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.total-income {
|
||||
color: #409EFF;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加响应式布局支持
|
||||
@media screen and (max-width: 1024px) {
|
||||
.preview-container {
|
||||
:deep(.el-table) {
|
||||
.process-header {
|
||||
.process-title {
|
||||
.process-name, .process-code {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.process-info {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,10 @@
|
|||
<template>
|
||||
<div class="report-edit-container" v-loading="loading">
|
||||
<edit-header class="edit-header" :title="title">
|
||||
<edit-header class="edit-header">
|
||||
<template #title>
|
||||
{{title}}
|
||||
<el-button type="text" @click="previewUserProd = true" style="margin-left: 16px" icon="el-icon-view" >员工产量汇总</el-button>
|
||||
</template>
|
||||
<el-button plain @click="cancel" icon="el-icon-close" size="small">取消</el-button>
|
||||
<el-button type="primary" plain @click="submitForm(false)" icon="el-icon-check" size="small">仅保存</el-button>
|
||||
<el-button type="primary" @click="submitForm(true)" icon="el-icon-s-check" size="small">保存并提交</el-button>
|
||||
|
@ -54,6 +58,11 @@
|
|||
:rules="rules"
|
||||
/>
|
||||
|
||||
<!-- 添加员工产量预览组件 -->
|
||||
<user-prod-preview
|
||||
:show.sync="previewUserProd"
|
||||
:data="form"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -73,14 +82,24 @@ import {parseTime} from "@/utils/ruoyi";
|
|||
import {$reportCheck} from "@/views/yh/report/mixins";
|
||||
import {DatePickerOptions} from "@/utils/constants";
|
||||
import ReportProductRowEdit from "@/views/yh/report/edit/components/ReportProductRowEdit.vue";
|
||||
import UserProdPreview from './components/UserProdPreview.vue'
|
||||
|
||||
export default {
|
||||
name: "ReportEdit",
|
||||
mixins: [$reportCheck],
|
||||
dicts: ['income_mode'],
|
||||
components: {ReportProductEdit, EditHeader, DeptTreeSelect, PriceInput, FormCol, ReportProductRowEdit},
|
||||
components: {
|
||||
UserProdPreview,
|
||||
ReportProductEdit,
|
||||
EditHeader,
|
||||
DeptTreeSelect,
|
||||
PriceInput,
|
||||
FormCol,
|
||||
ReportProductRowEdit
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previewUserProd: false,
|
||||
row: {},
|
||||
index: null,
|
||||
showMore: false,
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
<template>
|
||||
<div :class="listConfig.containerClass">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<!-- 报表日期 -->
|
||||
<el-form-item label="报表日期" prop="reportDateRange">
|
||||
<el-date-picker
|
||||
v-model="queryParams.reportDateRange"
|
||||
type="daterange"
|
||||
value-format="yyyy-MM-dd"
|
||||
clearable
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
@change="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="员工名称" prop="userName">
|
||||
<el-input
|
||||
v-model="queryParams.userName"
|
||||
|
@ -179,10 +192,12 @@ export default {
|
|||
// 字段列表
|
||||
columns: [
|
||||
{key: 'id', visible: false, label: '明细ID', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
|
||||
{key: 'reportDate', visible: true, label: '报表日期', minWidth: null, sortable: true, overflow: false, align: 'center', width: "180"},
|
||||
{key: 'reportDate', visible: true, label: '报表日期', minWidth: null, sortable: true, overflow: false, align: 'center', width: "100"},
|
||||
{key: 'deptName', visible: true, label: '部门', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'reportStatus', visible: true, label: '报表状态', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'userName', visible: true, label: '员工', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'priceName', visible: true, label: '工序', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'priceCode', visible: true, label: '工序代码', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'pricePrice', visible: true, label: '单价', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'num', visible: true, label: '产量', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
{key: 'totalPrice', visible: true, label: '工资', minWidth: null, sortable: true, overflow: false, align: 'center', width: null},
|
||||
|
@ -217,6 +232,7 @@ export default {
|
|||
id: null,
|
||||
prodId: null,
|
||||
userId: null,
|
||||
reportDateRange: []
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
|
|
Loading…
Reference in New Issue
Block a user