1. 给执行诊室绑定检查项目时,也需要增加看到全部本身以及子诊室的相关联的检查项目

2. 增加一个和管理员一样的检查项目管理页面
main
鹿和sa0ChunLuyu 3 weeks ago
parent ee0e6febef
commit ab2c0f8252

@ -0,0 +1,47 @@
<?php
namespace App\Http\Controllers\API\Admin\YeWu;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\Admin\YeWu\DeptCheckItemService;
class DeptCheckItemController extends Controller
{
//获取检查项目类别列表
public function GetClassList(Request $request)
{
$searchInfo = request('searchInfo');
$service = new DeptCheckItemService();
return $service->GetClassList($searchInfo);
}
//获取当前科室权限范围内的检查项目列表
public function GetItemList(Request $request)
{
$searchInfo = request('searchInfo');
$page = request('page');
$pageSize = request('pageSize');
$userid = $request->get('userid');
$service = new DeptCheckItemService();
return $service->GetItemList($searchInfo, $page, $pageSize, $userid);
}
//绑定设备
public function BindDevice(Request $request)
{
$item_id = request('item_id');
$device_ids = request('device_ids');
$userid = $request->get('userid');
$service = new DeptCheckItemService();
return $service->BindDevice($item_id, $device_ids, $userid);
}
//保存检查项目信息
public function Save()
{
$Info = request('Info');
$service = new DeptCheckItemService();
return $service->Save($Info);
}
}

@ -0,0 +1,172 @@
<?php
namespace App\Services\Admin\YeWu;
use Illuminate\Support\Facades\DB;
class DeptCheckItemService
{
//获取检查项目类别列表
public function GetClassList($searchInfo){
$bigClass=DB::table('s_check_item_class')->where(['pid'=>0,'is_del'=>0])->get();
$smallClass=[];
if(!empty($searchInfo['bigClass'])) {
$smallClass = DB::table('s_check_item_class')->where(['pid'=>$searchInfo['bigClass'],'is_del'=>0])->get();
}
return \Yz::Return(true, '查询成功', ['bigClass'=>$bigClass,'smallClass'=>$smallClass]);
}
//获取当前科室权限范围内的检查项目列表
public function GetItemList($searchInfo,$page,$pageSize,$userid){
$user = DB::table('users')->where('id', $userid)->first();
if (!$user || !$user->department_id) {
return \Yz::Return(true, '查询成功', ['list' => [], 'count' => 0]);
}
//获取当前科室及子科室的 department_number
$deptNumbers = DB::table('s_department')
->where('is_del', 0)
->where(function($q) use ($user) {
$q->where('id', $user->department_id)
->orWhere('pid', $user->department_id);
})
->pluck('department_number')
->toArray();
$small_id=[];
$list=DB::table('s_check_item')->where('s_check_item.is_del', 0)->whereNotNull('sheetType')->where('sheetType', '!=', '');
//科室过滤hisExecDepts 包含当前科室及子科室编号
$list->whereNotNull('hisExecDepts')->where('hisExecDepts', '!=', '');
if (!empty($deptNumbers)) {
$list->where(function($q) use ($deptNumbers) {
foreach ($deptNumbers as $num) {
$q->orWhere('hisExecDepts', 'like', '%"' . $num . '"%');
}
});
} else {
return \Yz::Return(true, '查询成功', ['list' => [], 'count' => 0]);
}
if(empty($searchInfo['bigClass'])!==true and empty($searchInfo['smallClass'])===true){
$small_id= DB::table('s_check_item_class')->where(['pid'=>$searchInfo['bigClass'],'is_del'=>0])->pluck('id')->toArray();
$list= $list->whereIn('item_class_id',$small_id);
}
if(!empty($searchInfo['smallClass'])){
$small_id[0]=$searchInfo['smallClass'];
$list= $list->whereIn('item_class_id',$small_id);
}
if(!empty($searchInfo['name'])){
$list->where(function($query) use ($searchInfo) {
$query->where('item_name', 'like', '%'.$searchInfo['name'].'%')
->orWhere('item_code', 'like', '%'.$searchInfo['name'].'%');
});
}
if (isset($searchInfo['deviceBind']) && $searchInfo['deviceBind'] !== '') {
if ($searchInfo['deviceBind'] == 1) {
$list->whereIn('s_check_item.id', function($q) {
$q->select('item_id')->from('s_check_item_device');
});
} elseif ($searchInfo['deviceBind'] == 0) {
$list->whereNotIn('s_check_item.id', function($q) {
$q->select('item_id')->from('s_check_item_device');
});
}
}
//执行科室筛选
if (isset($searchInfo['hisExecDepts']) && $searchInfo['hisExecDepts'] !== '') {
if ($searchInfo['hisExecDepts'] == 1) {
$list->whereNotNull('hisExecDepts')->where('hisExecDepts', '!=', '');
} elseif ($searchInfo['hisExecDepts'] == 0) {
$list->where(function($q) {
$q->whereNull('hisExecDepts')->orWhere('hisExecDepts', '');
});
}
}
$count = $list->count();
$list= $list
->leftJoin('s_appointment_type', 's_check_item.reservation_method', '=', 's_appointment_type.id')
->select('s_check_item.*','s_appointment_type.name as reservation_method_name');
if (!empty($searchInfo['orderField']) && !empty($searchInfo['orderDirection'])) {
$direction = $searchInfo['orderDirection'] == 'ascending' ? 'asc' : 'desc';
$list->orderBy($searchInfo['orderField'], $direction);
}
$list = $list->skip(($page-1)*$pageSize)->take($pageSize)->get();
//查询出所有的预约渠道
$qudaoList=DB::table('s_appointment_type')->get();
//获取当前科室下的设备 IDs
$deptDeviceIds = DB::table('s_department_resources_device')
->where('department_id', $user->department_id)
->pluck('device_id')
->toArray();
foreach ($list as $k=>$v){
$qudao_names=[];
$qudao_ids = explode(",", $v->reservation_method);
foreach ($qudaoList as $k1=>$v1){
foreach ($qudao_ids as $k2=>$v2){
if($v1->id==$v2){
$qudao_names[]=$v1->name;
}
}
}
$list[$k]->reservation_method= array_map('intval', $qudao_ids);
$list[$k]->reservation_method_name=$qudao_names;
$list[$k]->devicesInfo=DB::table('s_check_item_device')
->join('s_devices', 's_check_item_device.device_id', '=', 's_devices.id')
->select('s_devices.*')
->where('item_id',$v->id)
->whereIn('s_check_item_device.device_id', $deptDeviceIds)
->get();
}
return \Yz::Return(true, '查询成功', ['list'=>$list,'count'=>$count]);
}
//绑定设备(只影响当前科室下的排班关联)
public function BindDevice($item_id,$device_ids,$userid){
$user = DB::table('users')->where('id', $userid)->first();
if (!$user || !$user->department_id) {
return \Yz::Return(false, '用户科室信息不存在');
}
//获取当前科室下的设备 IDs
$deptDeviceIds = DB::table('s_department_resources_device')
->where('department_id', $user->department_id)
->pluck('device_id')
->toArray();
$data=[];
foreach ($device_ids as $k=>$v){
$data[$k]['item_id']=$item_id;
$data[$k]['device_id']=$v;
}
DB::beginTransaction();
//只删除当前科室下的关联
DB::table('s_check_item_device')
->where('item_id',$item_id)
->whereIn('device_id', $deptDeviceIds)
->delete();
$i= DB::table('s_check_item_device')->insert($data);
if($i>0){
DB::commit();
return \Yz::Return(true, '绑定成功', []);
}else{
DB::rollBack();
return \Yz::Return(false, '绑定失败');
}
}
public function Save($Info){
if(!empty($Info['id'])){
$Info['reservation_method']=implode(',', $Info['reservation_method']);
$res=DB::table('s_check_item')->where('id',$Info['id'])->update($Info);
if($res){
return \Yz::Return(true, '修改成功');
}else{
return \Yz::Return(false, '修改失败');
}
}else{
return \Yz::Return(false, 'id不能为空');
}
}
}

@ -170,6 +170,25 @@ public function GetUnboundItems($device_id, $keyword, $page, $pageSize)
->where('s_check_item_device.device_id', $device_id); ->where('s_check_item_device.device_id', $device_id);
}); });
//根据设备关联科室过滤 hisExecDepts
$deptNumbers = DB::table('s_department_resources_device')
->join('s_department', 's_department_resources_device.department_id', '=', 's_department.id')
->where('s_department_resources_device.device_id', $device_id)
->where('s_department.is_del', 0)
->pluck('s_department.department_number')
->toArray();
$list->whereNotNull('hisExecDepts')->where('hisExecDepts', '!=', '');
if (!empty($deptNumbers)) {
$list->where(function($q) use ($deptNumbers) {
foreach ($deptNumbers as $num) {
$q->orWhere('hisExecDepts', 'like', '%"' . $num . '"%');
}
});
} else {
$list->whereRaw('1 = 0');
}
if (!empty($keyword)) { if (!empty($keyword)) {
$list->where(function ($q) use ($keyword) { $list->where(function ($q) use ($keyword) {
$q->where('s_check_item.item_name', 'like', '%' . $keyword . '%') $q->where('s_check_item.item_name', 'like', '%' . $keyword . '%')

@ -53,6 +53,10 @@
Route::post('admin/CalendarChangeInfo','App\Http\Controllers\API\Admin\YeWu\healthCalendarController@ChangeInfo'); //admin后台更新日历 Route::post('admin/CalendarChangeInfo','App\Http\Controllers\API\Admin\YeWu\healthCalendarController@ChangeInfo'); //admin后台更新日历
Route::post('admin/GetCheckItemClassList','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetClassList');//admin后台获取检查项目类别列表 Route::post('admin/GetCheckItemClassList','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetClassList');//admin后台获取检查项目类别列表
Route::post('admin/GetCheckItemList','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetItemList');//admin后台获取检 Route::post('admin/GetCheckItemList','App\Http\Controllers\API\Admin\YeWu\CheckItemController@GetItemList');//admin后台获取检
Route::post('admin/GetDeptCheckItemClassList','App\Http\Controllers\API\Admin\YeWu\DeptCheckItemController@GetClassList');//获取当前科室权限的检查项目类别列表
Route::post('admin/GetDeptCheckItemList','App\Http\Controllers\API\Admin\YeWu\DeptCheckItemController@GetItemList');//获取当前科室权限的检查项目列表
Route::post('admin/DeptItemBindDevice','App\Http\Controllers\API\Admin\YeWu\DeptCheckItemController@BindDevice');//当前科室权限的检查项目绑定设备
Route::post('admin/DeptSaveItemInfo','App\Http\Controllers\API\Admin\YeWu\DeptCheckItemController@Save');//当前科室权限的保存检查项目信息
Route::post('admin/GetDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@GetList');//admin后台获取设备列表 Route::post('admin/GetDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@GetList');//admin后台获取设备列表
Route::post('admin/SaveDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@Save');//admin后台保存设备列表 Route::post('admin/SaveDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@Save');//admin后台保存设备列表
Route::post('admin/GetEnableDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@GetEnableList');//admin后台可用设备列表 Route::post('admin/GetEnableDeviceList','App\Http\Controllers\API\Admin\YeWu\DevicesController@GetEnableList');//admin后台可用设备列表

@ -168,6 +168,22 @@ export const GetYuYueTypes = (data = {}) => {
export const SaveItemInfo = (data = {}) => { export const SaveItemInfo = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/SaveItemInfo', data: data }) return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/SaveItemInfo', data: data })
} }
//获取当前科室权限的检查项目类别列表
export const GetDeptCheckItemClassList = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetDeptCheckItemClassList', data: data })
}
//获取当前科室权限的检查项目列表
export const GetDeptCheckItemList = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetDeptCheckItemList', data: data })
}
//当前科室权限的检查项目绑定设备
export const DeptItemBindDevice = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/DeptItemBindDevice', data: data })
}
//当前科室权限的保存检查项目信息
export const DeptSaveItemInfo = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/DeptSaveItemInfo', data: data })
}
//admin获取科室列表 //admin获取科室列表
export const GetDepartmentList = (data = {}) => { export const GetDepartmentList = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetDepartmentList', data: data }) return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/GetDepartmentList', data: data })

@ -131,6 +131,13 @@ const router = createRouter({
meta: { meta: {
title: '检查项目设置' title: '检查项目设置'
} }
},{
path: '/yewu/deptCheckItemConfig',
name: 'YewuDeptCheckItemConfig',
component: () => import('../views/YeWu/DeptCheckItemConfig.vue'),
meta: {
title: '检查项目管理'
}
},{ },{
path: '/yewu/devicesConfig', path: '/yewu/devicesConfig',
name: 'YewuDevicesConfig', name: 'YewuDevicesConfig',
@ -157,7 +164,7 @@ const router = createRouter({
name: 'YewuDeviceCheckItemBind', name: 'YewuDeviceCheckItemBind',
component: () => import('../views/YeWu/DeviceCheckItemBind.vue'), component: () => import('../views/YeWu/DeviceCheckItemBind.vue'),
meta: { meta: {
title: '检查项目管理' title: '排班项目管理'
} }
},{ },{
path: '/appointmentmngr/timeperiodmngr', path: '/appointmentmngr/timeperiodmngr',

@ -0,0 +1,832 @@
<template>
<div v-loading="loading">
<div class="head">
<el-row>
<div style="display: inline-flex; align-items: center;">
<el-tag class="ml-2" type="success" style="margin-right: 20px;">医嘱类别</el-tag>
<el-select clearable :filterable="true" v-model="searchInfo.bigClass" @change="GetItemClassList()"
placeholder="所有医嘱大类">
<el-option v-for="(item, index) in BigClassList" :key="index" :label="item.item_class_name"
:value="item.id" />
</el-select>
<el-select :filterable="true" clearable v-model="searchInfo.smallClass" placeholder="所有医嘱小类"
style="margin-left: 10px;">
<el-option v-for="(item, index) in SmallClassList" :key="index" :label="item.item_class_name"
:value="item.id" />
</el-select>
<el-select clearable v-model="searchInfo.deviceBind" placeholder="关联排班" style="margin-left: 10px;">
<el-option label="全部" value="" />
<el-option label="已关联排班" :value="1" />
<el-option label="未关联排班" :value="0" />
</el-select>
<el-select clearable v-model="searchInfo.hisExecDepts" placeholder="执行科室" style="margin-left: 10px;">
<el-option label="全部" value="" />
<el-option label="有执行科室" value="1" />
<el-option label="无执行科室" value="0" />
</el-select>
<el-input v-model="searchInfo.name" placeholder="请输入项目编号/名称" style="margin-left: 10px;" />
</div>
<el-button type="primary" @click="GetItemList()" style="margin-left: 10px;">查询</el-button>
<el-button type="primary" @click="BatchLinkDevice()" style="margin-left: 10px;">批量关联排班</el-button>
</el-row>
</div>
<el-table ref="checkItemTableRef" :data="tableData" style="width: 100%; margin-top: 10px;" row-key="id" @sort-change="onSortChange" @selection-change="onSelectionChange">
<el-table-column type="selection" width="50" />
<el-table-column prop="item_code" label="检查项目编号" width="160" sortable="custom" />
<el-table-column prop="item_name" label="检查项目名称" sortable="custom" />
<el-table-column prop="reservation_method_name" label="预约方式" />
<el-table-column prop="limosis" label="要求空腹" width="100">
<template #default="scope">
<el-tag v-if="scope.row.limosis==1" class="ml-2" type="danger"></el-tag>
<el-tag v-if="scope.row.limosis==0" class="ml-2" type="success"></el-tag>
</template>
</el-table-column>
<el-table-column prop="check_notice" label="检查须知" />
<el-table-column prop="check_time" label="检查时间" width="100" />
<el-table-column prop="check_begin_time" label="开始预约时间" width="120" />
<el-table-column prop="devicesInfo" label="关联排班">
<template #default="scope">
<span v-for="(item,index) in scope.row.devicesInfo " :key="index">
<el-tag v-if="item.status==1 && item.is_del==0" class="ml-2"
type="success">{{item.device_name}}</el-tag>
<el-tag v-if="item.status==0 || item.is_del==1" class="ml-2"
type="danger">{{item.device_name}}</el-tag>
</span>
</template>
</el-table-column>
<el-table-column prop="" label="医嘱关联排班" width="150">
<template #default="scope">
<el-button size="small" @click="LinkDeviceClick(scope.row)"></el-button>
</template>
</el-table-column>
<el-table-column prop="" label="操作" width="220">
<template #default="scope">
<el-button type="primary" @click="EditItem(scope.row)" size="small">修改</el-button>
<el-button type="warning" @click="HuChi(scope.row)" size="small">互斥</el-button>
<el-button type="success" @click="OpenRuleDialog(scope.row)" size="small">规则</el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
:page-sizes="[15, 50, 100, 200]" layout="total,sizes, prev, pager, next" :total="total"
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
</div>
<el-dialog v-model="DevicedialogVisible" :title="linkDialogTitle" width="40%">
<div class="chuansuokuang">
<el-transfer v-model="selectedDevice" :titles="['可选排班', '已关联排班']"
:props="{ key: 'id',label: 'device_name'}" :data="deviceList" />
</div>
<div v-if="isBatchLink && batchProgressShow" style="padding: 0 20px 12px; margin-top: 10px;">
<el-progress :percentage="batchProgress" :stroke-width="14" />
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="DevicedialogVisible = false">取消</el-button>
<el-button type="primary" @click="SaveLinkDevice()">
确定
</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="ItemDialogVisible" title="编辑项目" width="40%">
<div class="row"><span class="title">医嘱名称</span>{{selectedItemInfo.item_name}}</div>
<div class="row"><span class="title">预约方式</span>
<el-checkbox-group v-if="yuyueType" v-model="selectedItemInfo.reservation_method">
<el-checkbox v-for="(item, index) in yuyueType" :label="item.id" :value="item.id"
:key="index">{{item.name}}</el-checkbox>
</el-checkbox-group>
</div>
<div class="row"><span class="title">空腹</span><el-select :filterable="true" clearable
v-model="selectedItemInfo.limosis" placeholder="是否空腹" style=" width: 100px;">
<el-option label="否" :value="0" />
<el-option label="是" :value="1" />
</el-select>
</div>
<div class="row"><span class="title">检查时间</span><el-input v-model="selectedItemInfo.check_time"
placeholder="请输入此项检查的时长" style="width: 200px;" /></div>
<div class="row"><span class="title">等待时间</span><el-input v-model="selectedItemInfo.check_begin_time"
placeholder="开医嘱后,等待时间" style="width: 200px;" />
<div style="margin-left: 4px;">医嘱开具后预约时间需在设定的等待期之后,单位分钟</div>
</div>
<div class="row"><span class="title">检查须知</span><el-input v-model="selectedItemInfo.check_notice"
type="textarea" placeholder="请输入检查须知" style=" width: 500px;" /></div>
<template #footer>
<span class="dialog-footer">
<el-button @click="ItemDialogVisible = false">取消</el-button>
<el-button type="primary" @click="SaveItemInfoFunc()">
确定
</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="HuChiDialogVisible" :title="'为 '+SelectedHuChiItemInfo.name+' 设置互斥'" width="80%">
请输入想要与 <span style="font-weight: 900;font-size: 16px;">{{SelectedHuChiItemInfo.name}}</span> 互斥的项目名称
<div style="display: flex;margin-top: 20px;">
<div style="width: 30%;border-right: 1px solid #ccc;padding:4px 20px;">
<div v-loading="HuChiLoading"
style="border-bottom: 1px solid #ccc;padding-bottom: 12px;margin-bottom: 20px;">
<div style="display: flex;margin-bottom: 8px;">
<el-select clearable :filterable="true" v-model="HuChi_bigClass"
@change="GetItemClassList('Dialog')" placeholder="所有医嘱大类">
<el-option v-for="(item, index) in DialogBigClassList" :key="index"
:label="item.item_class_name" :value="item.id" />
</el-select>
<el-select :filterable="true" clearable v-model="HuChi_smallClass" placeholder="所有医嘱小类" @change="HuChi_SearchItem()"
style="margin-left: 10px;">
<el-option v-for="(item, index) in DialogSmallClassList" :key="index"
:label="item.item_class_name" :value="item.id" />
</el-select>
</div>
<div>
<el-input v-model="HuChi_InputItem" placeholder="项目搜索" style="width: 200px;" />
<el-button type="success" style="margin-left: 8px;" @click="HuChi_SearchItem()"></el-button>
</div>
</div>
<div style="padding-left: 40px;max-height: 400px;overflow-y:scroll;">
<el-checkbox-group v-model="HuChiCheckedItems" style="display: flex;flex-direction: column;">
<el-checkbox v-for="(item1,index1) in HuChiSelectItemList" :key="index1"
:label="item1.item_code">{{item1.item_name}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
style="width: 100px;border-right: 1px solid #ccc;text-align: center;height:400px;line-height: 400px;">
<el-button type="primary" :icon="ArrowRight" circle @click="AddHuChiItem()" />
</div>
<div style="width: 60%;padding-left: 20px;max-height: 450px;overflow-y:scroll;">
<div style="color: #999;margin-bottom: 4px;font-size: 12px;">已经存在互斥项{{itemHuChiList.length}}</div>
<table id="huchi_table" v-if="itemHuChiList.length>0">
<tr v-for="(item,index) in itemHuChiList" :key="index">
<td>{{item.code2_item_name}}</td>
<td><el-input v-model="itemHuChiList[index].time" placeholder="时间,0为永久互斥"
style="width: 150px;" /><span style="font-size: 12px;color:#bbb;"> 小时</span></td>
<td>
<span v-if="item.id" style="display: flex;">
<el-button type="danger" style="margin-left: 8px;"
@click="HuChi_Del(item.id)">解除</el-button>
<el-button type="primary" style="margin-left: 8px;"
@click="HuChi_Save(SelectedHuChiItemInfo.code,item.code2,itemHuChiList[index].time,item.id)">更新</el-button>
</span>
<span v-else style="display: flex;">
<el-button type="success" style="margin-left: 8px;"
@click="HuChi_Save(SelectedHuChiItemInfo.code,item.code2,itemHuChiList[index].time)">保存</el-button>
<el-button style="margin-left: 8px;" @click="HuChi_YiChu(item)"></el-button>
</span>
</td>
</tr>
</table>
<div v-else style="text-align: center;margin-top: 20px;color:#bbb;">
-- 暂未设置互斥项 --
</div>
</div>
</div>
</el-dialog>
<el-dialog v-model="HuChiSelectDialogVisible" :title="'为 '+SelectedHuChiItemInfo.name+' 设置互斥'" width="50%">
<div v-loading="HuChiLoading">
<span style="font-weight: 900;">设置互斥时间单位小时0为永久互斥</span>
<div class="row" v-for="(item,index) in HuChiSelectItemList" :key="index">
<div style="margin-right: 12px;">{{SelectedHuChiItemInfo.name}} </div>
<el-icon>
<DArrowLeft />
</el-icon><el-icon>
<DArrowRight />
</el-icon>
<div style="margin-left: 12px; width: 250px;">{{item.item_name}} </div>
<el-input v-model="HuChi_InputTimeList[index]" placeholder="时间,0为永久互斥" style="width: 150px;" />
<el-button type="danger" style="margin-left: 8px;"
@click="HuChi_Save(SelectedHuChiItemInfo.code,item.item_code,HuChi_InputTimeList[index])">添加</el-button>
</div>
</div>
</el-dialog>
<el-dialog v-model="RuleDialogVisible" :title="'时段规则 - ' + RuleItemInfo.item_name" width="700px" v-loading="RuleLoading">
<div style="margin-bottom: 12px;">
<el-button type="primary" size="small" @click="AddRuleRow"></el-button>
<span style="margin-left: 8px; color: #999; font-size: 12px;">无规则表示不限制预约时段</span>
</div>
<div v-for="(rule, index) in RuleList" :key="index"
style="border: 1px solid #ddd; border-radius: 4px; padding: 12px; margin-bottom: 10px;">
<div style="display: flex; align-items: center; margin-bottom: 8px;">
<span style="font-weight: 700; margin-right: 12px;">规则 {{ index + 1 }}</span>
<el-button type="danger" size="small" @click="RemoveRuleRow(index)"></el-button>
</div>
<div style="display: flex; align-items: center; margin-bottom: 8px;">
<span style="width: 80px; font-weight: 500;">允许星期</span>
<el-checkbox-group v-model="rule.days">
<el-checkbox v-for="d in weekOptions" :key="d" :label="d" :value="d" />
</el-checkbox-group>
</div>
<div style="display: flex; align-items: center;">
<span style="width: 80px; font-weight: 500;">允许时段</span>
<el-time-select v-model="rule.start_time" :max-time="rule.end_time"
placeholder="开始时间" start="06:00" step="00:30" end="23:30"
style="width: 140px;" />
<span style="margin: 0 8px;">~</span>
<el-time-select v-model="rule.end_time" :min-time="rule.start_time"
placeholder="结束时间" start="06:00" step="00:30" end="23:30"
style="width: 140px;" />
</div>
</div>
<div v-if="RuleList.length === 0" style="text-align: center; color: #bbb; padding: 20px;">
暂未设置时段限制
</div>
<template #footer>
<el-button @click="RuleDialogVisible = false">取消</el-button>
<el-button type="primary" @click="SaveRulesFunc"></el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
ref,
computed,
onMounted
} from 'vue'
import {
GetDeptCheckItemClassList,
GetDeptCheckItemList,
GetDeptDeviceList,
DeptItemBindDevice,
GetYuYueTypes,
DeptSaveItemInfo,
SetHuChi,
DelHuChi,
GetHuChiList,
GetCheckItemList,
GetCheckItemRules,
SaveCheckItemRules
} from '@/api/api.js'
import {
ElMessage,
ElMessageBox
} from 'element-plus'
import {
ArrowRight
} from '@element-plus/icons-vue'
let loading = ref(false);
let searchInfo = ref({
bigClass: '',
smallClass: '',
name: '',
orderField: '',
orderDirection: '',
hisExecDepts: '1',
deviceBind: ''
})
//
let selectedItemInfo = ref({
id: null,
item_name: '',
limosis: '',
reservation_method: '',
check_time: '',
check_begin_time: '',
check_notice: ''
})
//list
let BigClassList = ref([]);
let SmallClassList = ref([]);
let DialogBigClassList = ref([]);
let DialogSmallClassList = ref([]);
const GetItemClassList = (type='') => {
let searchData={}
searchData= { ...searchInfo.value }
if(type=='Dialog'){
searchData.bigClass=HuChi_bigClass.value
}
loading.value = true
GetDeptCheckItemClassList({
searchInfo: searchData
}).then(res => {
loading.value = false
if (res.status) {
if(type=='Dialog'){
DialogBigClassList.value = res.data.bigClass
DialogSmallClassList.value = res.data.smallClass
}else{
BigClassList.value = res.data.bigClass
SmallClassList.value = res.data.smallClass
}
GetItemList()
} else {
ElMessage.error(res.msg)
}
})
}
//
let tableData = ref([])
let currentPage = ref(1) //
let pageSize = ref(15) //
let total = 0 //
const GetItemList = () => {
//
if (checkItemTableRef.value) {
checkItemTableRef.value.clearSelection()
}
selectedCheckItems.value = []
loading.value = true
GetDeptCheckItemList({
searchInfo: searchInfo.value,
page: currentPage.value,
pageSize: pageSize.value
}).then(res => {
loading.value = false
if (res.status) {
let list = res.data.list;
tableData.value = list
total = res.data.count
} else {
ElMessage.error(res.msg)
}
})
}
const onSortChange = ({ prop, order }) => {
searchInfo.value.orderField = prop || ''
searchInfo.value.orderDirection = order || ''
GetItemList()
}
const PageSizeChange = (e) => { //
pageSize.value = e
GetItemList()
}
const PageCurrentChange = (e) => { //
currentPage.value = e
GetItemList()
}
let DevicedialogVisible = ref(false); //
let ItemDialogVisible = ref(false); //
let isBatchLink = ref(false) //
let selectedCheckItems = ref([]) //
let checkItemTableRef = ref(null) //ref
//
const linkDialogTitle = computed(() => {
return isBatchLink.value ? '批量关联排班' : '关联排班'
})
//
const onSelectionChange = (rows) => {
selectedCheckItems.value = rows
}
//穿
const LinkDeviceClick = (row) => {
isBatchLink.value = false
selectedDevice.value = []
DevicedialogVisible.value = true
selectedItemInfo.value.id = row.id
//
GetDeptDeviceList({}).then(res => {
if (res.status) {
deviceList.value = res.data
}
//
if (row.devicesInfo && row.devicesInfo.length > 0) {
row.devicesInfo.forEach(function(v) {
if (deviceList.value.find(function(d) { return d.id == v.id })) {
selectedDevice.value.push(v.id)
}
})
}
})
}
//
const BatchLinkDevice = () => {
if (selectedCheckItems.value.length === 0) {
ElMessage.error('请先勾选要批量关联的检查项目')
return
}
isBatchLink.value = true
GetDeptDeviceList({}).then(res => {
if (res.status) {
deviceList.value = res.data
}
//
let common = []
if (selectedCheckItems.value.length > 0) {
common = selectedCheckItems.value[0].devicesInfo.map(d => d.id)
for (let i = 1; i < selectedCheckItems.value.length; i++) {
const ids = selectedCheckItems.value[i].devicesInfo.map(d => d.id)
common = common.filter(id => ids.includes(id))
}
}
selectedDevice.value = common
DevicedialogVisible.value = true
})
}
let selectedDevice = ref([]) //
let batchProgress = ref(0) //
let batchProgressShow = ref(false) //
const SaveLinkDevice = async () => {
const saveOne = (itemId) => {
return DeptItemBindDevice({
item_id: itemId,
device_ids: selectedDevice.value,
})
}
if (isBatchLink.value) {
//
batchProgressShow.value = true
batchProgress.value = 0
const total = selectedCheckItems.value.length
let successCount = 0
let failCount = 0
for (let i = 0; i < total; i++) {
try {
const res = await saveOne(selectedCheckItems.value[i].id)
if (res.status) {
successCount++
} else {
failCount++
}
} catch {
failCount++
}
batchProgress.value = Math.round(((i + 1) / total) * 100)
}
setTimeout(() => {
batchProgressShow.value = false
}, 1500)
if (failCount === 0) {
ElMessage.success(`批量关联成功,共${total}`)
} else {
ElMessage.warning(`完成${successCount}项,失败${failCount}`)
}
DevicedialogVisible.value = false
selectedDevice.value = []
GetItemClassList()
} else {
//
saveOne(selectedItemInfo.value.id).then(res => {
if (res.status) {
DevicedialogVisible.value = false
selectedDevice.value = []
GetItemClassList()
} else {
ElMessage.error(res.msg)
}
})
}
}
//
let deviceList = ref([])
const GetDeviceList = () => {
GetDeptDeviceList({}).then(res => {
if (res.status) {
deviceList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const EditItem = (row) => {
ItemDialogVisible.value = true
selectedItemInfo.value.id = row.id
selectedItemInfo.value.item_name = row.item_name
selectedItemInfo.value.limosis = row.limosis
selectedItemInfo.value.reservation_method = row.reservation_method
selectedItemInfo.value.check_time = row.check_time
if (row.check_begin_time == '' || row.check_begin_time == null) {
row.check_begin_time = 0
}
selectedItemInfo.value.check_begin_time = row.check_begin_time
selectedItemInfo.value.check_notice = row.check_notice
}
//
let yuyueType = ref('')
const GetyuYueTypeFunc = () => {
GetYuYueTypes({}).then(res => {
if (res.status) {
yuyueType.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const SaveItemInfoFunc = () => {
DeptSaveItemInfo({
Info: selectedItemInfo.value
}).then(res => {
if (res.status) {
ItemDialogVisible.value = false
GetItemList()
} else {
ElMessage.error(res.msg)
}
})
}
let HuChiDialogVisible = ref(false);
let HuChi_InputItem = ref('');
let HuChi_smallClass=ref(null);
let HuChi_bigClass=ref(null)
let HuChiSelectItemList = ref(null)
let HuChiSelectDialogVisible = ref(false);
let HuChi_InputTimeList = ref([]); //
let HuChiLoading = ref(false);
let HuChiCheckedItems = ref([]); //
let SelectedHuChiItemInfo = ref({
code: '',
name: ''
})
const HuChi = (row) => {
HuChiDialogVisible.value = true
SelectedHuChiItemInfo.value.name = row.item_name
SelectedHuChiItemInfo.value.code = row.item_code
HuChiSelectItemList.value = [];
HuChi_InputItem.value = '';
GetItemClassList('Dialog')
HuChiList()
}
const HuChi_SearchItem = () => {
HuChiLoading.value = true
HuChi_InputTimeList.value = [];
GetCheckItemList({
searchInfo: {
name: HuChi_InputItem.value,
bigClass: HuChi_bigClass.value,
smallClass: HuChi_smallClass.value
},
page: 1,
pageSize: 100
}).then(res => {
HuChiLoading.value = false
if (res.status) {
if (res.data.list.length > 0) {
HuChiSelectItemList.value = res.data.list
} else {
ElMessage.error('未找到相关项目')
}
} else {
ElMessage.error(res.msg)
}
})
}
//
const AddHuChiItem = () => {
let newArr = [];
//
let enable = true
itemHuChiList.value.forEach(function(v, i) {
HuChiCheckedItems.value.forEach(function(v2, i2) {
if (v.code2 == v2) {
ElMessage.error(v.code2_item_name + " 已经存在于右侧,不能重复添加")
enable = false
}
})
})
if (!enable) return false;
HuChiSelectItemList.value.forEach(item => {
if (HuChiCheckedItems.value.includes(item.item_code)) {
itemHuChiList.value.push({
code2: item.item_code,
code2_item_name: item.item_name
});
} else {
newArr.push(item);
}
});
HuChiSelectItemList.value = newArr;
HuChiCheckedItems.value = []
}
//
const HuChi_YiChu = (y_item) => {
itemHuChiList.value = itemHuChiList.value.filter(item => item.code2 != y_item.code2);
if (!HuChiSelectItemList.value.find(item => item.item_code == y_item.code2)) {
HuChiSelectItemList.value.push({
item_code: y_item.code2,
item_name: y_item.code2_item_name
});
}
}
//
const HuChi_Save = (code1, code2, time, id = 0) => {
HuChiLoading.value = true
SetHuChi({
id: id,
code1: code1,
code2: code2,
time: time
}).then(res => {
HuChiLoading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
itemHuChiList.value.forEach(function(v, i) {
if (v.code2 == res.data.code2) {
itemHuChiList.value[i].id = res.data.id
}
})
} else {
ElMessage.error(res.msg)
}
})
}
//
let itemHuChiList = ref([]);
const HuChiList = () => {
HuChiLoading.value = true
GetHuChiList({
code: SelectedHuChiItemInfo.value.code
}).then(res => {
HuChiLoading.value = false
if (res.status) {
itemHuChiList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const HuChi_Del = (id) => {
ElMessageBox.confirm(
'确定解除此项互斥关系吗?',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
HuChiLoading.value = true
DelHuChi({
id: id
}).then(res => {
HuChiLoading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
HuChiList();
} else {
ElMessage.error(res.msg)
}
})
})
}
let RuleDialogVisible = ref(false);
let RuleLoading = ref(false);
let RuleItemInfo = ref({ id: null, item_name: '' });
let RuleList = ref([]);
const weekOptions = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
const OpenRuleDialog = (row) => {
RuleItemInfo.value = { id: row.id, item_name: row.item_name };
RuleDialogVisible.value = true;
RuleLoading.value = true;
GetCheckItemRules({ item_id: row.id }).then(res => {
RuleLoading.value = false;
if (res.status) {
RuleList.value = (res.data || []).map(r => ({
days: r.rule_value.days || [],
start_time: r.rule_value.start_time || '',
end_time: r.rule_value.end_time || ''
}));
} else {
ElMessage.error(res.msg);
}
});
};
const AddRuleRow = () => {
RuleList.value.push({ days: [], start_time: '', end_time: '' });
};
const RemoveRuleRow = (index) => {
RuleList.value.splice(index, 1);
};
const SaveRulesFunc = () => {
for (let i = 0; i < RuleList.value.length; i++) {
const rule = RuleList.value[i];
if (rule.days.length === 0) {
ElMessage.error('规则 ' + (i + 1) + ' 至少选择一个星期');
return;
}
if (!rule.start_time || !rule.end_time) {
ElMessage.error('规则 ' + (i + 1) + ' 请设置完整的时间段');
return;
}
}
const rules = RuleList.value.map(rule => ({
rule_type: 'TIME_RESTRICTION',
rule_value: {
days: rule.days,
start_time: rule.start_time,
end_time: rule.end_time
}
}));
RuleLoading.value = true;
SaveCheckItemRules({ item_id: RuleItemInfo.value.id, rules: rules }).then(res => {
RuleLoading.value = false;
if (res.status) {
ElMessage.success('保存成功');
RuleDialogVisible.value = false;
} else {
ElMessage.error(res.msg);
}
});
};
onMounted(() => {
GetItemClassList()
GetDeviceList()
GetyuYueTypeFunc()
})
</script>
<style scoped>
.page {
display: flex;
justify-content: flex-end;
margin-top: 10px;
}
.chuansuokuang {
display: flex;
justify-content: center;
}
.row {
display: flex;
align-items: center;
margin-left: 20px;
margin-top: 12px;
}
.title {
font-weight: 700;
white-space: nowrap;
width: 100px;
text-align: left;
}
.col {
border: 1px solid #ddd;
padding: 4px;
width: 400px;
}
#huchi_table {
width: 100%;
border: 1px solid #ccc;
border-collapse: collapse;
}
#huchi_table tr {
border: 1px solid #ccc;
}
#huchi_table td {
border: 1px solid #ccc;
padding: 4px 8px;
}
</style>

@ -1,10 +1,10 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<div class="page-container"> <div class="page-container">
<!-- 左侧服务组执行检查室列表 --> <!-- 左侧排班列表 -->
<div class="left-panel"> <div class="left-panel">
<div class="panel-header"> <div class="panel-header">
<span class="panel-title">执行检查室</span> <span class="panel-title">排班</span>
</div> </div>
<div class="device-list"> <div class="device-list">
<div v-for="item in deviceList" :key="item.id" <div v-for="item in deviceList" :key="item.id"
@ -24,7 +24,7 @@
<div class="right-panel"> <div class="right-panel">
<div class="panel-header"> <div class="panel-header">
<span class="panel-title"> <span class="panel-title">
{{ selectedDevice ? selectedDevice.device_name + ' - 已绑定的检查项目' : '请选择一个执行检查室' }} {{ selectedDevice ? selectedDevice.device_name + ' - 已绑定的检查项目' : '请选择一个排班' }}
</span> </span>
</div> </div>

Loading…
Cancel
Save