diff --git a/vue-fastapi-backend/module_admin/controller/datastd_controller.py b/vue-fastapi-backend/module_admin/controller/datastd_controller.py index 561af2d..63b0e07 100644 --- a/vue-fastapi-backend/module_admin/controller/datastd_controller.py +++ b/vue-fastapi-backend/module_admin/controller/datastd_controller.py @@ -96,7 +96,7 @@ async def delete_std_code( delete_std_code_result = await DataStdService.delete_std_code_services(request, query_db, delete_std_code) logger.info(delete_std_code_result.message) return ResponseUtil.success(msg=delete_std_code_result.message) -@datastdController.delete('/stdcode/codeWithItems/appr', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeWithItems:delete'))]) +@datastdController.delete('/stdcode/codeappr/{ids}', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeWithItems:delete'))]) @Log(title='标准代码与代码项管理', business_type=BusinessType.DELETE) async def delete_std_code_with_items_appr( request: Request, diff --git a/vue-fastapi-backend/module_admin/dao/datastd_dao.py b/vue-fastapi-backend/module_admin/dao/datastd_dao.py index d87a7f8..34d3882 100644 --- a/vue-fastapi-backend/module_admin/dao/datastd_dao.py +++ b/vue-fastapi-backend/module_admin/dao/datastd_dao.py @@ -57,6 +57,18 @@ class DataStdDao: ) return col_list @classmethod + async def get_last_std_code_appr_by_id(cls,db: AsyncSession, Id: str ): + result = await db.execute( + select(DataStdCodeAppr) + .where( + DataStdCodeAppr.oldInstId == Id, + DataStdCodeAppr.approStatus == "succeed" + ) + .order_by(DataStdCodeAppr.update_time.desc()) + .limit(1) + ) + return result.scalar_one_or_none() + @classmethod async def get_std_code_map_list(cls, db: AsyncSession, query_object: DataStdCodeModel, is_page: bool = False): # 构建查询条件 filters = [] @@ -803,6 +815,12 @@ class DataStdDao: query = select(DataStdDictAppr).where(*filters).order_by(desc(DataStdDictAppr.create_time)) return await PageUtil.paginate(db, query, 0, 0, False) @classmethod + async def get_std_code_appr_list(cls, flowId:str,db: AsyncSession): + filters = [] + filters.append(DataStdCodeAppr.flowId == flowId) + query = select(DataStdCodeAppr).where(*filters).order_by(desc(DataStdCodeAppr.create_time)) + return await PageUtil.paginate(db, query, 0, 0, False) + @classmethod async def get_std_main_appr_by_id(cls, db: AsyncSession, Id: str): col = await db.execute(select(DataStdMainAppr).where(DataStdMainAppr.id == Id)) return col.scalars().first() diff --git a/vue-fastapi-backend/module_admin/service/approval_service.py b/vue-fastapi-backend/module_admin/service/approval_service.py index 5e7fad0..fbba1f1 100644 --- a/vue-fastapi-backend/module_admin/service/approval_service.py +++ b/vue-fastapi-backend/module_admin/service/approval_service.py @@ -14,7 +14,7 @@ from module_admin.dao.approval_dao import ApprovalDao from module_admin.dao.user_dao import UserDao from module_admin.dao.meta_dao import MetaDao from module_admin.dao.datastd_dao import DataStdDao -from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DataStdDictModel,DataStdMainModel,DataStdMainApprModel,DataStdDictApprModel,DataStdDictModel +from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DataStdDictModel,DataStdMainModel,DataStdMainApprModel,DataStdDictApprModel,DataStdDictModel,DataStdCodeApprModel class ApprovalService: @@ -96,7 +96,10 @@ class ApprovalService: await cls.syncStdMainInfo(result_db, flow_approval.businessId, edit.status) # 数据字典审批 elif flow_approval.businessType == 'dataStdDict': - await cls.syncStdDictInfo(result_db, flow_approval.businessId, edit.status) + await cls.syncStdDictInfo(result_db, flow_approval.businessId, edit.status) + # 标准代码审批 + elif flow_approval.businessType == 'dataStdCode': + await cls.syncStdCodeInfo(result_db, flow_approval.businessId, edit.status) await ApprovalDao.edit_flow_approval(result_db, edit.model_dump(exclude_unset=True)) await result_db.commit() return CrudResponseModel(is_success=True, message='操作成功') @@ -193,6 +196,39 @@ class ApprovalService: return CrudResponseModel(is_success=True, message='操作成功') + + @classmethod + async def syncStdCodeInfo(cls, result_db: AsyncSession, suppId: str, operateType: str): + apprList = await DataStdDao.get_std_code_appr_list(suppId, result_db) + + for appr in apprList: + # 将 SQLAlchemy 模型实例转换为 Pydantic 模型实例 + appr_model = DataStdCodeApprModel.model_validate(appr) + + change_type = appr_model.changeType + if operateType =='succeed': + if change_type == "add": + # 将 DataStdDictApprModel 转换为 DataStdDictModel + main_model = DataStdDictModel(**appr_model.model_dump(exclude_unset=True, by_alias=True)) + + await DataStdDao.add_std_code(result_db, main_model) + + elif change_type == "edit": + # 使用 oldInstId 作为主键 + main_model = DataStdDictModel(**appr_model.model_dump(exclude_unset=True, by_alias=True)) + + main_model.id = appr_model.oldInstId + await DataStdDao.update_std_code(result_db, main_model.model_dump(exclude_unset=True)) + + elif change_type == "delete": + await DataStdDao.delete_std_code(result_db, appr_model.oldInstId) + + # 更新 approStatus 状态 + appr_model.approStatus = operateType + await DataStdDao.update_std_dict_appr(result_db, appr_model) + + + return CrudResponseModel(is_success=True, message='操作成功') @classmethod diff --git a/vue-fastapi-backend/module_admin/service/datastd_service.py b/vue-fastapi-backend/module_admin/service/datastd_service.py index 5834d82..d38de0d 100644 --- a/vue-fastapi-backend/module_admin/service/datastd_service.py +++ b/vue-fastapi-backend/module_admin/service/datastd_service.py @@ -126,7 +126,55 @@ class DataStdService: else: raise ServiceException(message=f'标准代码{page_object.id}不存在') - + @classmethod + async def delete_std_code_with_items_appr( + cls, + ids: str, + query_db: AsyncSession, + current_user: CurrentUserModel + ): + """ + 批量删除标准代码及其代码项的审批流程。 + :param ids: 多个标准代码ID,用逗号分隔 + """ + try: + id_list = [i.strip() for i in ids.split(',') if i.strip()] + if not id_list: + raise ServiceException(message="请提供有效的标准代码ID列表") + + for std_id in id_list: + std_code = await DataStdDao.get_std_code_by_id(query_db, std_id) + if not std_code: + raise ServiceException(message=f"ID 为 {std_id} 的标准代码不存在,无法提交删除审批") + + + flow_id = str(uuid.uuid4()) + last_appr= await DataStdDao.get_last_std_code_appr_by_id(query_db,std_id) + + # 标准代码审批记录 + std_code_appr = DataStdCodeApprModel(**std_code.model_dump(exclude_unset=True, by_alias=True)) + std_code_appr.changeType = "delete" + std_code_appr.compareId = last_appr.id + std_code_appr.oldInstId = std_code.id + std_code_appr.approStatus = "waiting" + std_code_appr.code_status = "9" + std_code_appr.flowId = flow_id + std_code_appr.update_by = current_user.user.user_name + std_code_appr.update_time = datetime.now() + await DataStdDao.add_std_code_appr(query_db, std_code_appr) + # 发起审批流程(每个标准代码一条审批) + apply_model = ApplyModel() + apply_model.businessType = "dataStdCode" + apply_model.businessId = flow_id + apply_model.applicant = current_user.user.user_name + await ApprovalService.apply_services(query_db, apply_model, 'dataStdCode') + + return CrudResponseModel(is_success=True, message="批量提交删除标准代码审批成功!") + + except Exception as e: + await query_db.rollback() + raise ServiceException(message=f"提交删除标准代码审批失败: {str(e)}") + @classmethod async def delete_std_code_services(cls, request: Request, query_db: AsyncSession, page_object: DeleteDataStdModel): """ @@ -222,14 +270,6 @@ class DataStdService: # 将标准代码添加到审批表 await DataStdDao.add_std_code_appr(query_db, appr_model) - - # 创建审批申请 - apply_model = ApplyModel() - apply_model.businessType = "dataStdCode" - apply_model.businessId = appr_model.flowId - apply_model.applicant = appr_model.create_by - await ApprovalService.apply_services(query_db, apply_model, 'dataStdCode') - # 同时处理代码项的添加 for item in code_item_list: item.id = str(uuid.uuid4()) # 新生成 ID @@ -254,12 +294,14 @@ class DataStdService: await DataStdDao.add_std_code_appr(query_db, item_appr_model) - + # 创建审批申请 + apply_model = ApplyModel() + apply_model.businessType = "dataStdCode" + apply_model.businessId = appr_model.flowId + apply_model.applicant = appr_model.create_by + await ApprovalService.apply_services(query_db, apply_model, 'dataStdCode') - return CrudResponseModel(is_success=True, message='新增标准代码和代码项成功') - - - + return CrudResponseModel(is_success=True, message='提交新增标准代码审批成功!') @classmethod async def edit_std_code_with_items_services(cls, request, query_db: AsyncSession, code: DataStdCodeModel, code_item_list: list[DataStdCodeModel]): """ @@ -302,7 +344,88 @@ class DataStdService: return CrudResponseModel(is_success=True, message='标准代码和代码项修改成功') except Exception as e: await query_db.rollback() - raise ServiceException(message=f"修改标准代码失败: {str(e)}") + raise ServiceException(message=f"修改标准代码失败: {str(e)}") + + + @classmethod + async def edit_std_code_with_items_appr( + cls, + code: DataStdCodeModel, + code_item_list: list[DataStdCodeModel], + query_db: AsyncSession, + current_user: CurrentUserModel + ): + """ + 修改标准代码及其代码项的审批流程(修改审批)。 + code_item.id 存在为修改,若为空则为新增。 + """ + # 更新时间及人 + code.update_by = current_user.user.user_name + code.update_time = datetime.now() + code.sys_name = '公司级' if 'company' == code.code_type else code.sys_name + + # 校验标准代码是否存在并且唯一 + if not await cls.check_code_unique_services(query_db, code): + raise ServiceException(message=f'标准代码{code.code_num}不存在或已存在,无法提交修改审批') + + # 创建标准代码的审批记录(changeType 为 update) + appr_model = DataStdCodeApprModel(**code.model_dump(exclude_unset=True, by_alias=True)) + last_appr= await DataStdDao.get_last_std_code_appr_by_id(query_db,code.id) + appr_model.changeType = "update" + appr_model.compareId = last_appr.id # 对比对象为正式表的 ID + appr_model.oldInstId = code.id + appr_model.code_status = "9" + appr_model.approStatus = "waiting" + appr_model.flowId = str(uuid.uuid4()) # flowId 共用 + + await DataStdDao.add_std_code_appr(query_db, appr_model) + + # 同步处理代码项 + for item in code_item_list: + item.parent_id = code.id + item.update_by = current_user.user.user_name + item.update_time = datetime.now() + item.sys_name = '公司级' if 'company' == item.code_type else item.sys_name + + if item.id: # 修改项 + if not await cls.check_code_unique_services(query_db, item): + raise ServiceException(message=f'父级代码{code.code_num}下代码项{item.code_num}重复,无法提交修改审批') + + item_appr_model = DataStdCodeApprModel(**item.model_dump(exclude_unset=True, by_alias=True)) + item_appr_model.changeType = "update" + item_appr_model.compareId = item.id + item_appr_model.oldInstId = item.id + item_appr_model.approStatus = "waiting" + item_appr_model.flowId = appr_model.flowId + + await DataStdDao.add_std_code_appr(query_db, item_appr_model) + + else: # 新增项 + item.id = str(uuid.uuid4()) + item.create_by = current_user.user.user_name + item.create_time = datetime.now() + + if not await cls.check_code_unique_services(query_db, item): + raise ServiceException(message=f'父级代码{code.code_num}下代码项{item.code_num}重复,无法提交新增审批') + + item_appr_model = DataStdCodeApprModel(**item.model_dump(exclude_unset=True, by_alias=True)) + item_appr_model.changeType = "add" + item_appr_model.compareId = item.id + item_appr_model.oldInstId = item.id + item_appr_model.approStatus = "waiting" + item_appr_model.flowId = appr_model.flowId + + await DataStdDao.add_std_code_appr(query_db, item_appr_model) + + # 创建审批流程 + apply_model = ApplyModel() + apply_model.businessType = "dataStdCode" + apply_model.businessId = appr_model.flowId + apply_model.applicant = appr_model.update_by + await ApprovalService.apply_services(query_db, apply_model, 'dataStdCode') + + return CrudResponseModel(is_success=True, message='提交修改标准代码审批成功!') + @classmethod async def check_code_unique_services(cls, query_db: AsyncSession, page_object: DataStdCodeModel): """ diff --git a/vue-fastapi-frontend/src/api/datastd/std.js b/vue-fastapi-frontend/src/api/datastd/std.js index 4483590..40d0d0d 100644 --- a/vue-fastapi-frontend/src/api/datastd/std.js +++ b/vue-fastapi-frontend/src/api/datastd/std.js @@ -58,7 +58,7 @@ export function getStdCodeMap(rowId) { // 新增标准代码 export function addStdCode(data) { return request({ - url: '/default-api/datastd/stdcode/codeWithItems', + url: '/default-api/datastd/stdcode/codeWithItems/appr', method: 'post', data: data }) @@ -76,7 +76,7 @@ export function addStdCodeItem(data) { // 修改标准代码 export function updateStdCode(data) { return request({ - url: '/default-api/datastd/stdcode/codeWithItems', + url: '/default-api/datastd/stdcode/codeWithItems/appr', method: 'put', data: data }) @@ -94,7 +94,7 @@ export function updateStdCodeItem(data) { // 删除标准代码 export function deleteStdCode(colId) { return request({ - url: '/default-api/datastd/stdcode/code/' + colId, + url: '/default-api/datastd/stdcodeappr/code/' + colId, method: 'delete' }) }