修改发票管理页面
This commit is contained in:
@@ -4,12 +4,6 @@
|
||||
<!-- 页面标题和用户信息 -->
|
||||
<div class="header-section">
|
||||
<h2>发票管理</h2>
|
||||
<div class="user-info">
|
||||
<span class="welcome-text">欢迎, {{ currentUser.name }}</span>
|
||||
<span class="role-badge" :class="currentUser.role">
|
||||
{{ currentUser.role === 'admin' ? '管理员' : '操作员' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
@@ -58,35 +52,14 @@
|
||||
<td class="sequence-number">{{ index + 1 }}</td>
|
||||
<td class="employee-info">
|
||||
<div class="input-container">
|
||||
<select
|
||||
v-if="item.isActive"
|
||||
v-model="item.operator"
|
||||
class="form-control"
|
||||
>
|
||||
<option value="">请选择操作员</option>
|
||||
<option
|
||||
v-for="user in userList"
|
||||
:key="user.employeeId"
|
||||
:value="user.name"
|
||||
:data-employee-id="user.employeeId"
|
||||
@change="updateEmployeeId(item, user.employeeId)"
|
||||
>
|
||||
{{ user.name }}
|
||||
</option>
|
||||
</select>
|
||||
<span v-else class="employee-name">{{ item.operator || '-' }}</span>
|
||||
<!-- 操作员字段始终不可编辑 -->
|
||||
<span class="employee-name">{{ item.operator || '-' }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="employee-id-cell">
|
||||
<div class="input-container">
|
||||
<input
|
||||
v-if="item.isActive"
|
||||
v-model="item.employeeId"
|
||||
class="form-control"
|
||||
placeholder="请输入员工工号"
|
||||
maxlength="10"
|
||||
/>
|
||||
<span v-else>{{ item.employeeId || '-' }}</span>
|
||||
<!-- 员工工号字段始终不可编辑 -->
|
||||
<span>{{ item.employeeId || '-' }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="date-cell">
|
||||
@@ -191,6 +164,7 @@
|
||||
<script>
|
||||
import { listUser } from '@/api/system/user';
|
||||
import request from '@/utils/request'; // 导入请求工具
|
||||
import useUserStore from '@/store/modules/user'; // 导入用户store
|
||||
|
||||
export default {
|
||||
name: 'InvoiceManagement',
|
||||
@@ -198,9 +172,10 @@ export default {
|
||||
return {
|
||||
// 用户信息和权限
|
||||
currentUser: {
|
||||
name: 'admin',
|
||||
employeeId: '1702',
|
||||
role: 'admin' // operator: 普通操作员, admin: 管理员
|
||||
name: '',
|
||||
nickName: '',
|
||||
employeeId: '',
|
||||
role: '' // operator: 普通操作员, admin: 管理员
|
||||
},
|
||||
// 用户列表,用于操作员下拉选择(将在created中从后端获取)
|
||||
userList: [],
|
||||
@@ -222,6 +197,17 @@ export default {
|
||||
},
|
||||
created() {
|
||||
console.log('组件初始化,开始加载数据');
|
||||
|
||||
// 获取当前登录用户信息
|
||||
const userStore = useUserStore();
|
||||
this.currentUser = {
|
||||
name: userStore.nickName || userStore.name,
|
||||
nickName: userStore.nickName,
|
||||
employeeId: userStore.id || userStore.practitionerId,
|
||||
role: userStore.roles && userStore.roles.length > 0 ? userStore.roles[0] : 'operator'
|
||||
};
|
||||
console.log('当前登录用户信息:', this.currentUser);
|
||||
|
||||
// 从后端获取用户列表后再加载发票数据,确保用户信息可用
|
||||
this.getUserList().then(() => {
|
||||
console.log('用户列表加载完成,开始加载发票数据');
|
||||
@@ -247,12 +233,17 @@ export default {
|
||||
methods: {
|
||||
// 获取用户列表
|
||||
getUserList() {
|
||||
return listUser().then((res) => {
|
||||
// 传递分页参数,获取所有用户数据
|
||||
const queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 1000 // 设置较大的pageSize以获取所有用户
|
||||
};
|
||||
return listUser(queryParams).then((res) => {
|
||||
// 从响应中提取用户列表,并转换为需要的格式
|
||||
this.userList = res.data.records.map(user => ({
|
||||
name: user.nickName, // 使用用户昵称作为显示名称
|
||||
name: user.nickName || user.username || user.name, // 尝试多种可能的名称字段
|
||||
employeeId: user.userId, // 使用用户ID作为员工工号
|
||||
role: user.practitionerRolesDtoList?.some(role => role.roleKey === 'admin') ? 'admin' : 'operator'
|
||||
role: user.role || 'operator' // 默认为普通操作员
|
||||
}));
|
||||
console.log('获取到的用户列表:', this.userList);
|
||||
return Promise.resolve();
|
||||
@@ -474,19 +465,30 @@ export default {
|
||||
addNewRow() {
|
||||
// 新增行时自动填充当前用户信息
|
||||
// 使用负数作为临时ID,避免与后端数据库ID冲突
|
||||
const newId = -Math.max(...this.invoiceData.map(item => Math.abs(item.id)), 0) - 1;
|
||||
this.invoiceData.push({
|
||||
let maxId = 0;
|
||||
if (this.invoiceData.length > 0) {
|
||||
maxId = Math.max(...this.invoiceData.map(item => Math.abs(item.id)));
|
||||
}
|
||||
const newId = -(maxId + 1);
|
||||
const newSegmentId = Date.now(); // 生成唯一的segmentId
|
||||
const currentDate = new Date().toISOString().split('T')[0];
|
||||
|
||||
const newRecord = {
|
||||
id: newId,
|
||||
segmentId: newSegmentId, // 为新记录设置segmentId
|
||||
operator: this.currentUser.name, // 自动使用当前用户名称
|
||||
employeeId: this.currentUser.employeeId,
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
date: currentDate, // 自动填充当日日期
|
||||
startNum: '',
|
||||
endNum: '',
|
||||
currentNum: '',
|
||||
status: '未使用',
|
||||
isActive: true, // 新增行默认处于编辑状态
|
||||
isNewRecord: true // 添加标记表示这是新记录
|
||||
});
|
||||
};
|
||||
|
||||
console.log('添加新行,自动填充领用日期为当日:', { newRecord });
|
||||
this.invoiceData.push(newRecord);
|
||||
},
|
||||
|
||||
deleteRow(record) {
|
||||
@@ -495,6 +497,19 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// 对于新添加的记录,直接从前端移除,不需要调用API
|
||||
if (record.isNewRecord) {
|
||||
if (confirm('确定要删除这条未保存的记录吗?')) {
|
||||
const index = this.invoiceData.findIndex(item => item.keyId === record.keyId);
|
||||
if (index > -1) {
|
||||
this.invoiceData.splice(index, 1);
|
||||
this.filterDataByPermission();
|
||||
alert('删除成功');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 严格检查权限:只有管理员或记录所有者可以删除
|
||||
if (this.currentUser.role !== 'admin' && record.employeeId !== this.currentUser.employeeId) {
|
||||
alert('您没有权限删除此记录!操作员只能删除自己的记录。');
|
||||
@@ -815,17 +830,15 @@ export default {
|
||||
},
|
||||
|
||||
// 从字符串末尾向前提取前缀,直到遇到第一个字母
|
||||
// 规则:前缀定义为从号码最末位开始往前推直到出现字母为止的前面字符,若无字母则无前缀
|
||||
// 规则:前缀定义为从号码最末位开始往前推直到出现字母为止,其前面的字符全部称为前缀;若无字母则无前缀
|
||||
extractPrefixFromEnd(str) {
|
||||
if (!str) return '';
|
||||
|
||||
// 从末尾向前遍历字符串
|
||||
for (let i = str.length - 1; i >= 0; i--) {
|
||||
// 如果遇到字母,返回从开始到该字母之前的部分
|
||||
// 例如:对于"ABC123",从末尾向前找到第一个字母'C',前缀就是'AB'
|
||||
// 对于"123ABC456",从末尾向前找到第一个字母'C',前缀就是"123AB"
|
||||
// 如果遇到字母,返回从开始到该字母的所有字符
|
||||
if (/[A-Za-z]/.test(str[i])) {
|
||||
return str.substring(0, i);
|
||||
return str.substring(0, i + 1);
|
||||
}
|
||||
}
|
||||
// 如果没有找到字母,则无前缀
|
||||
@@ -1030,11 +1043,6 @@ export default {
|
||||
return currentNumValue >= startNumValue && currentNumValue <= endNumValue;
|
||||
},
|
||||
|
||||
// 验证单个记录
|
||||
// 测试用例说明:
|
||||
// 1. 测试起始和终止号码前缀一致性:例如"AB123"和"AB456"通过,"AB123"和"AC456"失败
|
||||
// 2. 测试当前号码与起始号码前缀一致性:例如"AB123"作为起始,"AB125"作为当前号码通过,"AC125"失败
|
||||
// 3. 测试无字母情况:纯数字"123456"作为起始、终止和当前号码都通过验证
|
||||
validateRecord(record, rowIndex) {
|
||||
const errors = [];
|
||||
const rowInfo = rowIndex ? `第${rowIndex}行` : '';
|
||||
@@ -1145,24 +1153,23 @@ export default {
|
||||
const savePromises = recordsToSave.map((record, index) => {
|
||||
// 准备发送到后端的数据格式,适配adm_invoice_segment表结构
|
||||
const dataToSend = {
|
||||
// 对于更新操作,同时传递id和segmentId,确保后端能正确识别
|
||||
...(!record.isNewRecord && { id: record.keyId }),
|
||||
// 确保segmentId不为null,优先使用keyId,然后是segmentId,新记录时使用生成的临时ID
|
||||
segmentId: record.keyId || record.segmentId || Date.now(),
|
||||
// 员工和开票员信息
|
||||
employeeId: record.employeeId,
|
||||
employeeName: record.operator || this.getUserNameById(record.employeeId),
|
||||
// 员工和开票员信息,确保字段名称与后端API期望一致
|
||||
invoicingStaffId: record.employeeId,
|
||||
invoicingStaffName: record.operator || this.getUserNameById(record.employeeId),
|
||||
// 日期信息
|
||||
employeeId: record.employeeId, // 同时提供employeeId字段以保持一致性
|
||||
// 日期信息,确保同时设置billBusDate和createDate字段
|
||||
billBusDate: record.date ? new Date(record.date) : null,
|
||||
createDate: record.date ? new Date(record.date) : null,
|
||||
// 号码信息,只使用数据库表对应的字段名
|
||||
// 号码信息,使用后端API期望的字段名
|
||||
beginNumber: record.startNum,
|
||||
startNum: record.startNum, // 同时提供startNum字段以保持一致性
|
||||
endNumber: record.endNum,
|
||||
endNum: record.endNum, // 同时提供endNum字段以保持一致性
|
||||
currentNumber: record.currentNum,
|
||||
currentNum: record.currentNum, // 同时提供currentNum字段以保持一致性
|
||||
// 状态信息
|
||||
status: record.status || '未使用',
|
||||
statusEnum: { value: record.status || '未使用' }, // 同时提供statusEnum字段
|
||||
// 备注信息
|
||||
remark: record.currentNum ?
|
||||
(record.remark && !record.remark.includes('当前使用号码:') ?
|
||||
@@ -1174,6 +1181,13 @@ export default {
|
||||
deleteFlag: '0'
|
||||
};
|
||||
|
||||
// 对于更新记录,设置id字段;对于新记录,不设置id,让后端自动生成
|
||||
if (!record.isNewRecord) {
|
||||
dataToSend.id = record.id || record.keyId;
|
||||
}
|
||||
// 对于所有记录,确保设置segmentId字段,因为数据库表中segment_id是必填的
|
||||
dataToSend.segmentId = record.segmentId || Date.now(); // 确保segmentId有值
|
||||
|
||||
// 添加调试信息,打印完整的记录对象
|
||||
console.log(`准备${record.isNewRecord ? '新增' : '更新'}的原始记录对象:`, {
|
||||
keyId: record.keyId,
|
||||
@@ -1200,6 +1214,8 @@ export default {
|
||||
return response;
|
||||
}).catch(err => {
|
||||
console.error(`${operation}记录 ${index + 1} 失败:`, err);
|
||||
console.error(`${operation}记录 ${index + 1} 失败详情:`, JSON.stringify(err, null, 2));
|
||||
console.error(`${operation}记录 ${index + 1} 请求数据:`, JSON.stringify(dataToSend, null, 2));
|
||||
throw err; // 重新抛出错误以便上层catch捕获
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user