🐞 fix: 部分bug修复

This commit is contained in:
2025-03-13 11:12:01 +08:00
parent 0ce49d1504
commit 6b5ceef475
7 changed files with 391 additions and 205 deletions

View File

@@ -5,8 +5,8 @@ VUE_APP_TITLE = 福安德综合办公系统
ENV = 'development'
# 若依管理系统/开发环境
VUE_APP_BASE_API = '/prod-api'
# VUE_APP_BASE_API = 'http://110.41.139.73:8080'
# VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API = 'http://110.41.139.73:8080'
# 应用访问路径 例如使用前缀 /admin/
VUE_APP_CONTEXT_PATH = '/'

View File

@@ -17,7 +17,7 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button
type="primary"
plain
@@ -27,7 +27,7 @@
v-hasPermi="['system:offboarding:add']"
>新增
</el-button>
</el-col>
</el-col> -->
<el-col :span="1.5">
<el-button
type="success"

View File

@@ -31,7 +31,7 @@
:loading="loading"
:pagination="pagination"
@selection-change="handleSelection"
@delete="handleDelete"
@detail="showDetail"
@page-change="handlePageChange"
/>
</el-tab-pane>
@@ -55,7 +55,40 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="理由" prop="reason"></el-table-column>
<el-table-column label="理由" prop="reason" width="180">
<template slot-scope="scope">
<el-popover
placement="left"
width="400"
trigger="hover"
:content="scope.row.reason"
:disabled="!scope.row.reason || scope.row.reason.length <= 50"
>
<template #reference>
<div class="text-ellipsis">
{{ truncateText(scope.row.reason) }}
</div>
</template>
<!-- 自定义内容区域 -->
<div class="reason-popover">
<div class="popover-header">
<span>详细理由</span>
<el-button
size="mini"
type="text"
@click="handleCopy(scope.row.reason)"
>
<i class="el-icon-document-copy"></i>
</el-button>
</div>
<div class="popover-content">
{{ scope.row.reason }}
</div>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="涉及时间" prop="signTime"></el-table-column>
<el-table-column label="涉及金额" prop="price"></el-table-column>
<el-table-column label="类型" prop="type"></el-table-column>
@@ -112,6 +145,13 @@ export default {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
},
truncateText(text) {
if (!text) return '-'
return text.length > 20
? text.substring(0, 20) + '...'
: text
},
async fetchData() {
this.loading = true
try {
@@ -201,4 +241,42 @@ export default {
.text-right {
text-align: right;
}
.text-ellipsis {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 内容容器 */
.reason-popover {
max-height: 300px;
overflow-y: auto;
}
/* 头部样式 */
.popover-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding-bottom: 5px;
border-bottom: 1px solid #eee;
}
/* 内容样式 */
.popover-content {
white-space: pre-wrap;
line-height: 1.6;
word-break: break-word;
}
/* 文本省略 */
.text-ellipsis {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

@@ -0,0 +1,244 @@
<!-- components/SalaryUploadDialog.vue -->
<template>
<el-dialog
title="薪资计算"
:visible.sync="localVisible"
width="30%"
@closed="handleClose"
:close-on-click-modal="false">
<!-- 全局加载状态 -->
<div v-if="globalLoading" class="global-loading">
<div class="loading-content">
<i class="el-icon-loading"></i>
<p>{{ loadingText }}</p>
</div>
</div>
<el-form ref="calcForm">
<el-form-item label="计算月份" required>
<el-date-picker
v-model="month"
type="month"
value-format="yyyyMM"
placeholder="选择月份"
style="width: 100%"
:disabled="isProcessing">
</el-date-picker>
</el-form-item>
<el-form-item label="薪资文件" required>
<el-upload
class="upload-demo"
drag
:auto-upload="false"
:on-change="handleFileChange"
:file-list="fileList"
action=""
:disabled="isProcessing">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">仅支持xlsx格式文件</div>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button
@click="localVisible = false"
:disabled="isProcessing">
取消
</el-button>
<el-button
@click="handleUpload"
:disabled="!canUpload"
:loading="uploading">
{{ uploadButtonText }}
</el-button>
<el-button
type="primary"
@click="handleSubmit"
:disabled="!canSubmit"
:loading="calculating">
开始计算
</el-button>
</span>
</el-dialog>
</template>
<script>
import { uploadOssFile } from '@/api/oa/salary'
export default {
name: 'SalaryUploadDialog',
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
localVisible: this.visible,
isProcessing: false, // 整体处理状态
uploading: false, // 上传中状态
calculating: false, // 计算中状态
month: '',
fileList: [],
filePath: '',
currentFileKey: null, // 文件唯一标识
globalLoading: false,
loadingText: ''
}
},
computed: {
// 是否可以上传(有文件且未处理)
canUpload() {
return this.fileList.length > 0 && !this.uploading && !this.currentFileKey
},
// 是否可以提交计算
canSubmit() {
return Boolean(this.filePath) && !this.calculating
},
uploadButtonText() {
return this.uploading ? '上传中...' : '确认上传'
},
// 生成文件唯一标识
fileIdentifier() {
if (!this.fileList.length) return null
const file = this.fileList[0].raw
return `${file.name}-${file.lastModified}-${file.size}`
}
},
watch: {
visible(newVal) {
this.localVisible = newVal
},
localVisible(newVal) {
this.$emit('update:visible', newVal)
}
},
methods: {
handleFileChange(file, fileList) {
this.fileList = [fileList[fileList.length - 1]]
// 检测到文件变化时重置状态
if (this.fileIdentifier !== this.currentFileKey) {
this.currentFileKey = null
this.filePath = ''
}
},
async handleUpload() {
try {
this.uploading = true
this.isProcessing = true
this.showGlobalLoading('文件上传中...')
const formData = new FormData()
formData.append('file', this.fileList[0].raw)
const { data } = await uploadOssFile(formData)
this.filePath = '/data' + data.url.split('/data')[1]
this.currentFileKey = this.fileIdentifier
this.$message.success('文件上传成功')
} catch (error) {
this.$message.error('文件上传失败')
} finally {
this.uploading = false
this.isProcessing = false
this.hideGlobalLoading()
}
},
async handleSubmit() {
if (!this.validateForm()) return
try {
this.calculating = true
this.isProcessing = true
this.showGlobalLoading('薪资计算中...')
// 触发父组件计算
this.$emit('submit', {
monthStr: this.month,
filePath: this.filePath
})
} catch (error) {
this.$message.error(error.message || '计算失败')
} finally {
this.calculating = false
this.isProcessing = false
this.hideGlobalLoading()
}
},
validateForm() {
if (!this.month) {
this.$message.warning('请选择计算月份')
return false
}
if (!this.filePath) {
this.$message.warning('请先上传薪资文件')
return false
}
return true
},
showGlobalLoading(text) {
this.globalLoading = true
this.loadingText = text
},
hideGlobalLoading() {
this.globalLoading = false
this.loadingText = ''
},
handleClose() {
this.resetForm()
this.$emit('closed')
},
resetForm() {
this.fileList = []
this.month = ''
this.filePath = ''
this.currentFileKey = null
this.isProcessing = false
this.uploading = false
this.calculating = false
}
}
}
</script>
<style scoped>
/* 全局加载样式 */
.global-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.8);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-content {
text-align: center;
padding: 20px;
background: rgba(0, 0, 0, 0.7);
border-radius: 4px;
color: #fff;
}
.loading-content i {
font-size: 40px;
margin-bottom: 10px;
}
.upload-demo {
text-align: center;
}
</style>

View File

@@ -5,53 +5,12 @@
<el-button type="primary" @click="showUploadDialog">新增计算</el-button>
</div>
<!-- 上传弹窗 -->
<el-dialog
title="薪资计算"
<!-- 上传弹窗组件 -->
<SalaryUploadDialog
:visible.sync="uploadVisible"
width="30%"
@closed="resetUpload"
:close-on-click-modal="false">
<el-form ref="calcForm">
<el-form-item label="计算月份" required>
<el-date-picker
v-model="month"
type="month"
value-format="yyyyMM"
placeholder="选择月份"
style="width: 100%"
:disabled="isUploading">
</el-date-picker>
</el-form-item>
<el-form-item label="薪资文件" required>
<el-upload
class="upload-demo"
drag
:auto-upload="false"
:on-change="handleFileChange"
:file-list="fileList"
:disabled="isUploading">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">仅支持xlsx格式文件</div>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="uploadVisible = false" :disabled="isUploading">取消</el-button>
<el-button @click="handleUpload" :disabled="fileList.length === 0">确认上传</el-button>
<el-button
type="primary"
@click="handleSubmit"
:loading="isUploading"
:disabled="isUploading"
>
{{ isUploading ? '计算中...' : '开始计算' }}
</el-button>
</span>
</el-dialog>
@submit="handleCalculate"
@closed="handleDialogClosed"
/>
<!-- 计算结果展示 -->
<div class="result-area">
@@ -96,32 +55,29 @@
</template>
<script>
import { calculateSalary, uploadOssFile, getCalcHistory, convertToDateString } from '@/api/oa/salary'
import SalaryUploadDialog from '../components/SalaryUploadDialog'
import { calculateSalary, getCalcHistory, convertToDateString } from '@/api/oa/salary'
export default {
components: {
SalaryUploadDialog
},
data() {
return {
uploadVisible: false,
isUploading: false,
month: '',
fileList: [],
currentResult: [],
showCurrentResult: false,
currentMonth: '',
historyData: [],
filePath: '',
query:{
pageSize:10,
pageNum:1,
payTime:"2025-03-01"
query: {
pageSize: 10,
pageNum: 1,
payTime: "2025-03-01"
},
StaffSalaryList:[]
StaffSalaryList: []
}
},
computed: {
canSubmit() {
return this.month && this.fileList.length > 0
},
totalAmount() {
return this.currentResult.reduce((sum, item) => sum + item.total, 0)
}
@@ -129,7 +85,6 @@ export default {
mounted() {
const firstDayOfLastMonth = new Date();
firstDayOfLastMonth.setMonth(firstDayOfLastMonth.getMonth() - 1, 1);
const firstDayStr = [
firstDayOfLastMonth.getFullYear(),
(firstDayOfLastMonth.getMonth() + 1).toString().padStart(2, '0'),
@@ -138,68 +93,29 @@ export default {
this.getHistoryData(firstDayStr)
},
methods: {
getStaffList(){
listStaff(this.query).then(res => {
this.StaffSalaryList = res.rows
console.log(this.StaffSalaryList)
})
},
showUploadDialog() {
this.uploadVisible = true
},
handleFileChange(file, fileList) {
// 限制单个文件上传
this.fileList = [fileList[fileList.length - 1]]
},
async handleSubmit() {
async handleCalculate(params) {
try {
this.isUploading = true
// 第二步:提交计算
const { result } = await calculateSalary({
filePath: this.filePath,
monthStr: this.month
})
const { result } = await calculateSalary(params)
this.currentResult = result
this.currentMonth = params.month
this.showCurrentResult = true
// 获取当前日期的第一天
try {
const firstDayStr = convertToDateString(this.month);
this.getHistoryData(firstDayStr)
} catch (e) {
console.log(e.message); // "Invalid month value"
}
// 刷新历史数据
const firstDayStr = convertToDateString(params.month)
this.getHistoryData(firstDayStr)
this.$message.success('计算完成')
this.uploadVisible = false
} catch (error) {
this.$message.error(error.message || '计算失败')
} finally {
this.isUploading = false
}
},
// 上传文件
async handleUpload() {
const formData = new FormData()
formData.append('file', this.fileList[0].raw)
const { data } = await uploadOssFile(formData)
const filePath = '/data' + data.url.split('/data')[1];
this.filePath = filePath;
message.success('上传成功');
},
resetUpload() {
this.fileList = []
this.month = ''
},
showDetail(row) {
// 查看历史详情逻辑
console.log('查看详情', row)
handleDialogClosed() {
// 可在此处添加关闭后的清理逻辑
},
// 获取计算历史
@@ -213,12 +129,17 @@ export default {
this.$message.error(error.message || '获取计算历史失败')
}
},
showDetail(row) {
// 查看历史详情逻辑
console.log('查看详情', row)
}
}
}
</script>
<style scoped>
/* 保持原有样式不变 */
.salary-container {
padding: 20px;
background: #f5f7fa;
@@ -260,8 +181,4 @@ export default {
color: #E6A23C;
font-weight: 500;
}
.upload-demo {
text-align: center;
}
</style>
</style>

View File

@@ -6,51 +6,11 @@
</div>
<!-- 上传弹窗 -->
<el-dialog
title="薪资计算"
<SalaryUploadDialog
:visible.sync="uploadVisible"
width="30%"
@closed="resetUpload"
:close-on-click-modal="false">
<el-form ref="calcForm">
<el-form-item label="计算月份" required>
<el-date-picker
v-model="month"
type="month"
value-format="yyyyMM"
placeholder="选择月份"
style="width: 100%"
:disabled="isUploading">
</el-date-picker>
</el-form-item>
<el-form-item label="薪资文件" required>
<el-upload
class="upload-demo"
drag
:auto-upload="false"
:on-change="handleFileChange"
:file-list="fileList"
:disabled="isUploading">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">仅支持xlsx格式文件</div>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="uploadVisible = false" :disabled="isUploading">取消</el-button>
<el-button @click="handleUpload" :disabled="fileList.length === 0">确认上传</el-button>
<el-button
type="primary"
@click="handleSubmit"
:loading="isUploading"
:disabled="!filePath">
{{ isUploading ? '计算中...' : '开始计算' }}
</el-button>
</span>
</el-dialog>
@submit="handleCalculate"
@closed="handleDialogClosed"
/>
<!-- 计算结果展示 -->
<div class="result-area">
@@ -95,9 +55,13 @@
</template>
<script>
import SalaryUploadDialog from '../components/SalaryUploadDialog'
import { calculateSalary, uploadOssFile, getWorkersCalcHistory, convertToDateString } from '@/api/oa/salary'
export default {
components: {
SalaryUploadDialog
},
data() {
return {
uploadVisible: false,
@@ -140,46 +104,27 @@ export default {
this.fileList = [fileList[fileList.length - 1]]
},
async handleSubmit() {
async handleCalculate(params) {
try {
this.isUploading = true
// 第二步:提交计算
const { result } = await calculateSalary({
filePath: this.filePath,
monthStr: this.month
})
const { result } = await calculateSalary(params)
this.currentResult = result
this.currentMonth = params.month
this.showCurrentResult = true
// 获取当前日期的第一天
try {
const firstDayStr = convertToDateString(this.month);
this.getHistoryData(firstDayStr)
} catch (e) {
console.log(e.message); // "Invalid month value"
}
// this.currentResult = result.details
// this.currentMonth = this.month
// this.showCurrentResult = true
// // 更新历史记录
// this.historyData.unshift({
// calcMonth: this.month,
// calcTime: new Date().toLocaleString(),
// totalAmount: this.totalAmount
// })
// 刷新历史数据
const firstDayStr = convertToDateString(params.month)
this.getHistoryData(firstDayStr)
this.$message.success('计算完成')
this.uploadVisible = false
} catch (error) {
this.$message.error(error.message || '计算失败')
} finally {
this.isUploading = false
}
},
handleDialogClosed() {
// 可在此处添加关闭后的清理逻辑
},
// 上传文件
async handleUpload() {
const formData = new FormData()

View File

@@ -68,7 +68,7 @@
<li class="list-group-item" v-if="hasDocument">
个人档案
<div class="pull-right">
<el-button type="danger" @click="openFileDrawer">查看档案</el-button>
<el-button type="text" @click="openFileDrawer">查看档案</el-button>
</div>
</li>
</ul>
@@ -92,7 +92,7 @@
</el-col>
</el-row>
<el-drawer :title="`${user.nickName} - 文件管理`"
<el-drawer :title="`文件管理`"
:visible.sync="fileDrawerVisible"
size="800px"
direction="rtl"
@@ -100,7 +100,7 @@
<UserFileManager
:user-id="user.userId"
:read-only="true"
v-if="showFile" />
v-if="fileDrawerVisible" />
</el-drawer>
</div>
</template>
@@ -122,9 +122,9 @@ export default {
roleGroup: {},
postGroup: {},
activeTab: "userinfo",
showFile: false,
onBoardingInfo: {},
hasDocument: false,
fileDrawerVisible: false
};
},
@@ -154,11 +154,13 @@ export default {
this.hasDocument = !dir.includes("admin")
},
openFileDrawer() {
console.log("打开文件抽屉");
this.showFile = true;
console.log(this.showFile);
this.fileDrawerVisible = true;
},
// 跳转到申请入职页面
toApplyOnboarding() {
console.log("跳转到申请入职页面");
this.$router.push('/people/addOnboarding');
},
// 跳转到申请转正页面
toApplyProbation() {