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