同步科室

main
鹿和sa0ChunLuyu 6 days ago
parent 0d1257c431
commit b55c117b19

@ -6,6 +6,8 @@
use App\Services\Admin\UserService; use App\Services\Admin\UserService;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Services\Admin\YeWu\DepartmentService; use App\Services\Admin\YeWu\DepartmentService;
use App\Http\Controllers\API\His\HisController;
use Illuminate\Support\Facades\DB;
class DepartmentController extends Controller class DepartmentController extends Controller
{ {
//获取科室列表 //获取科室列表
@ -102,4 +104,115 @@ public function GetChildrenDepartments()
return $service->GetChildrenDepartments($department_id); return $service->GetChildrenDepartments($department_id);
} }
//从HIS同步科室 + 返回统计
public function SyncDepartment()
{
// 1. 同步前快照
$beforeSnapshot = $this->getDeptSnapshot();
// 2. 调用 HIS 接口获取科室列表
$His = new HisController();
$res = $His::Get('查询科室列表', []);
if ($res['code'] != 200) {
return \Yz::JsonError('调用His接口失败');
}
$hisData = $res['data'];
$receivedCodes = [];
foreach ($hisData as $item) {
$deptCode = $item['deptCode'];
$deptName = $item['deptName'];
$validState = $item['validState'] ?? '1';
$deptStatus = ($validState == '1') ? 1 : 0;
$receivedCodes[] = $deptCode;
$dpt = DB::table('s_department')
->where('department_number', $deptCode)
->first();
if (!$dpt) {
DB::table('s_department')->insert([
'department_number' => $deptCode,
'department_name' => $deptName,
'department_status' => $deptStatus,
'is_del' => 0,
]);
} else {
DB::table('s_department')
->where('department_number', $deptCode)
->update([
'department_name' => $deptName,
'department_status' => $deptStatus,
'is_del' => 0,
]);
}
}
// 3. 处理移除HIS未返回的科室标记 is_del=1
DB::table('s_department')
->where('is_del', 0)
->whereNotIn('department_number', $receivedCodes)
->update(['is_del' => 1]);
// 4. 同步后快照
$afterSnapshot = $this->getDeptSnapshot();
// 5. 对比统计
$beforeCodes = array_keys($beforeSnapshot);
$afterCodes = array_keys($afterSnapshot);
$beforeSet = array_flip($beforeCodes);
$afterSet = array_flip($afterCodes);
$addedCodes = array_diff_key($afterSet, $beforeSet);
$removedCodes = array_diff_key($beforeSet, $afterSet);
$commonCodes = array_intersect_key($beforeSet, $afterSet);
$updatedCount = 0;
$enabledCount = 0;
$disabledCount = 0;
foreach ($commonCodes as $code => $v) {
$before = $beforeSnapshot[$code];
$after = $afterSnapshot[$code];
if ($before['name'] !== $after['name']) {
$updatedCount++;
}
if ($before['status'] == 0 && $after['status'] == 1) {
$enabledCount++;
}
if ($before['status'] == 1 && $after['status'] == 0) {
$disabledCount++;
}
}
return \Yz::Return(true, '同步完成', [
'added' => count($addedCodes),
'removed' => count($removedCodes),
'updated' => $updatedCount,
'enabled' => $enabledCount,
'disabled' => $disabledCount,
]);
}
//获取所有 is_del=0 的科室快照
private function getDeptSnapshot()
{
$items = DB::table('s_department')
->where('is_del', 0)
->select('department_number', 'department_name', 'department_status')
->get();
$snapshot = [];
foreach ($items as $item) {
$snapshot[$item->department_number] = [
'name' => $item->department_name,
'status' => $item->department_status,
];
}
return $snapshot;
}
} }

@ -89,6 +89,7 @@
Route::post('admin/GetLeafDepartmentList','App\Http\Controllers\API\Admin\YeWu\DepartmentController@GetLeafList');//获取可作为诊室的叶子节点科室列表 Route::post('admin/GetLeafDepartmentList','App\Http\Controllers\API\Admin\YeWu\DepartmentController@GetLeafList');//获取可作为诊室的叶子节点科室列表
Route::post('admin/SaveDepartmentChildren','App\Http\Controllers\API\Admin\YeWu\DepartmentController@SaveChildren');//保存科室关联诊室关系 Route::post('admin/SaveDepartmentChildren','App\Http\Controllers\API\Admin\YeWu\DepartmentController@SaveChildren');//保存科室关联诊室关系
Route::post('admin/GetHasScheduleTopDepartments','App\Http\Controllers\API\Admin\YeWu\DepartmentController@GetHasScheduleTopDepartments');//获取有排班资源的科室列表 Route::post('admin/GetHasScheduleTopDepartments','App\Http\Controllers\API\Admin\YeWu\DepartmentController@GetHasScheduleTopDepartments');//获取有排班资源的科室列表
Route::post('admin/DeptSyncDepartment','App\Http\Controllers\API\Admin\YeWu\DepartmentController@SyncDepartment');//从HIS同步科室
Route::post('admin/SaveDepartmentResource','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@Save');//保存科室资源信息 Route::post('admin/SaveDepartmentResource','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@Save');//保存科室资源信息
Route::post('admin/DepartmentResourceGetList','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@GetList');//获取科室资源list Route::post('admin/DepartmentResourceGetList','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@GetList');//获取科室资源list
Route::post('admin/DepartmentResourceGetEnableList','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@GetEnableList');//获取可用科室资源 Route::post('admin/DepartmentResourceGetEnableList','App\Http\Controllers\API\Admin\YeWu\DepartmentResourceController@GetEnableList');//获取可用科室资源

@ -249,6 +249,10 @@ export const SaveDepartmentChildren = (data = {}) => {
export const GetHasScheduleTopDepartments = (data = {}) => { export const GetHasScheduleTopDepartments = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetHasScheduleTopDepartments', data: data }) return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetHasScheduleTopDepartments', data: data })
} }
//从HIS同步科室
export const DeptSyncDepartment = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/DeptSyncDepartment', data: data })
}
//admin保存科室资源信息 //admin保存科室资源信息
export const SaveDepartmentResource = (data = {}) => { export const SaveDepartmentResource = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/SaveDepartmentResource', data: data }) return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/SaveDepartmentResource', data: data })

@ -14,6 +14,7 @@
</el-form-item> </el-form-item>
<el-button @click="GetList()" style="margin-left: 10px;">查询</el-button> <el-button @click="GetList()" style="margin-left: 10px;">查询</el-button>
<el-button v-if="isAdmin" type="primary" @click="add()" style="margin-left: 10px;"></el-button> <el-button v-if="isAdmin" type="primary" @click="add()" style="margin-left: 10px;"></el-button>
<el-button v-if="isAdmin" type="warning" @click="openSyncDialog" style="margin-left: 10px;">HIS</el-button>
<el-form-item> <el-form-item>
<el-checkbox v-model="searchInfo.only_execute" @change="GetList" style="margin-left: 15px;"></el-checkbox> <el-checkbox v-model="searchInfo.only_execute" @change="GetList" style="margin-left: 15px;"></el-checkbox>
</el-form-item> </el-form-item>
@ -164,6 +165,57 @@
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
<el-dialog v-model="syncDialogVisible" title="从HIS同步科室" width="480px" :close-on-click-modal="false">
<template v-if="!syncDone">
<div v-if="syncLoading" style="text-align: center; padding: 12px 0; color: #303133; font-size: 15px; font-weight: 500;">
<el-icon class="is-loading" style="vertical-align: middle; margin-right: 4px;">
<Loading />
</el-icon>
{{ syncLoadingText }}
</div>
<el-steps :active="syncStep" align-center finish-status="success" style="margin-top: 10px;">
<el-step title="同步科室" />
</el-steps>
<el-progress :percentage="syncPercent" :stroke-width="14" style="margin-top: 24px;" />
</template>
<template v-else>
<el-result icon="success" title="同步完成">
<template #extra>
<div style="display: flex; justify-content: space-around; padding: 12px 0;">
<div style="text-align: center; flex: 1;">
<div style="font-size: 26px; font-weight: 700; color: #409eff;">{{ syncResult.added }}</div>
<div style="color: #999; font-size: 13px;">新增</div>
</div>
<div style="width: 1px; background: #e8e8e8; margin: 0 8px;"></div>
<div style="text-align: center; flex: 1;">
<div style="font-size: 26px; font-weight: 700; color: #e6a23c;">{{ syncResult.removed }}</div>
<div style="color: #999; font-size: 13px;">移除</div>
</div>
<div style="width: 1px; background: #e8e8e8; margin: 0 8px;"></div>
<div style="text-align: center; flex: 1;">
<div style="font-size: 26px; font-weight: 700; color: #67c23a;">{{ syncResult.updated }}</div>
<div style="color: #999; font-size: 13px;">更新</div>
</div>
</div>
<div style="display: flex; justify-content: space-around; padding: 4px 0 12px;">
<div style="text-align: center; flex: 1;">
<div style="font-size: 26px; font-weight: 700; color: #00aaff;">{{ syncResult.enabled }}</div>
<div style="color: #999; font-size: 13px;">启用</div>
</div>
<div style="width: 1px; background: #e8e8e8; margin: 0 8px;"></div>
<div style="text-align: center; flex: 1;">
<div style="font-size: 26px; font-weight: 700; color: #f56c6c;">{{ syncResult.disabled }}</div>
<div style="color: #999; font-size: 13px;">停用</div>
</div>
<div style="flex: 1;"></div>
</div>
</template>
</el-result>
</template>
<template #footer>
<el-button v-if="syncDone" type="primary" @click="syncDialogVisible = false; GetList()"></el-button>
</template>
</el-dialog>
</div> </div>
</template> </template>
@ -181,9 +233,13 @@
GetDepartmentChildren, GetDepartmentChildren,
GetLeafDepartmentList, GetLeafDepartmentList,
SaveDepartmentChildren, SaveDepartmentChildren,
GetHasScheduleTopDepartments GetHasScheduleTopDepartments,
DeptSyncDepartment
} from '@/api/api.js' } from '@/api/api.js'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import {
Loading
} from '@element-plus/icons-vue'
import DepartmentResourcesSave from '@/components/Yewu/DepartmentResourcesSave.vue' import DepartmentResourcesSave from '@/components/Yewu/DepartmentResourcesSave.vue'
let loginUserinfo = ref(null) let loginUserinfo = ref(null)
if (sessionStorage.getItem("LoginUserInfo")) { if (sessionStorage.getItem("LoginUserInfo")) {
@ -397,6 +453,15 @@ let topScheduleDepts = ref([])
let leafDepartmentList = ref([]); let leafDepartmentList = ref([]);
let selectedChildren = ref([]); let selectedChildren = ref([]);
//
let syncDialogVisible = ref(false)
let syncStep = ref(0)
let syncPercent = ref(0)
let syncDone = ref(false)
let syncLoading = ref(false)
let syncLoadingText = ref('')
let syncResult = ref({ added: 0, removed: 0, updated: 0, enabled: 0, disabled: 0 })
const openLinkDialog = (row) => { const openLinkDialog = (row) => {
currentLinkDepartment.value = row currentLinkDepartment.value = row
selectedChildren.value = [] selectedChildren.value = []
@ -443,6 +508,32 @@ let topScheduleDepts = ref([])
}) })
} }
//
const openSyncDialog = async () => {
syncDialogVisible.value = true
syncStep.value = 0
syncPercent.value = 0
syncDone.value = false
syncLoading.value = false
syncResult.value = { added: 0, removed: 0, updated: 0, enabled: 0, disabled: 0 }
syncLoadingText.value = '正在同步科室...'
syncLoading.value = true
const res = await DeptSyncDepartment()
syncLoading.value = false
if (!res.status) {
ElMessage.error('同步科室失败:' + (res.msg || '未知错误'))
syncDialogVisible.value = false
return
}
syncResult.value = res.data
syncStep.value = 1
syncPercent.value = 100
syncDone.value = true
}
const loadTopScheduleDepts = () => { const loadTopScheduleDepts = () => {
GetHasScheduleTopDepartments({ GetHasScheduleTopDepartments({
department_id: departmentInfo.value.id department_id: departmentInfo.value.id

Loading…
Cancel
Save