号源计划模板增加节假日区分、号源计划增加按时长计算总量

main
yanzai 1 year ago
parent 7876505a0a
commit 6242bc167e

Binary file not shown.

@ -7,6 +7,7 @@ use App\Services\Admin\YeWu\PlanListService;
use DateTime;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Tools;
class PlanListController extends Controller
@ -19,6 +20,8 @@ class PlanListController extends Controller
$department_id = $userInfo[0]->department_id;
$dateRange = request('dateRange');
$planModelIds = request('ids');
$HolidayEnable = request('HolidayEnable');
$date_type = request('date_type');
//循环日期和勾选的模板创建明细
if (count($dateRange) == 2 && count($planModelIds) > 0) {
$models = DB::table('s_source_roster')->whereIn('id', $planModelIds)->get();
@ -54,16 +57,32 @@ class PlanListController extends Controller
}
}
return \Yz::Return(false, '已有重复的计划明细,禁止创建!' . $msg . '已存在相同记录,</br>存在于:</br>' . $msglist . '</br>对应记录Id为' . $msgIds . '</br>请先删除后再操作', $checkList);
}
//查询勾选的时间范围内所有的节假日
$holiday_list=DB::table('s_holiday')->whereBetween('date',$dateRange)->where(['type'=>2])->pluck('date')->toArray();
// 循环日期并判断星期
$current_date = clone $start_date;
DB::beginTransaction();
$success_count = 0;//成功创建的数量
while ($current_date <= $end_date) {
//如果是节假日模板,则判断当前日期是否是节假日,不是则跳过
if ($date_type == 2) {
if (!in_array($current_date->format('Y-m-d'),$holiday_list)){
// 将当前日期增加一天
$current_date->modify('+1 day');
continue;
}
}
//如果选择节假日不可用,并且当前日期是节假日,则跳过
if($HolidayEnable==0 and in_array($current_date->format('Y-m-d'),$holiday_list)){
// 将当前日期增加一天
$current_date->modify('+1 day');
continue;
}
// 获取当前日期的星期几0表示星期日1表示星期一以此类推
$weekday = $current_date->format('w');
$weekname = '';
@ -91,7 +110,10 @@ class PlanListController extends Controller
break;
}
foreach ($models as $model) {
if ($model->weekname == $weekname) {
if ($date_type == 1 and $model->date_type==1) {
if ($model->weekname <> $weekname) continue;
}
// 插入明细表
$data = [
'roster_id' => $model->id,
@ -112,7 +134,6 @@ class PlanListController extends Controller
];
$plan_id = DB::table('s_source_roster_detail')->insertGetId($data);
if ($plan_id) {
$success_count++;
@ -154,7 +175,7 @@ class PlanListController extends Controller
return \Yz::echoError1('模板未关联设备,请重新选择!异常模板Id:' . $model->id);
}
}
}
// 将当前日期增加一天
$current_date->modify('+1 day');
@ -322,6 +343,7 @@ class PlanListController extends Controller
$service = new PlanListService();
return $service->GetEnablePlan($regnum, $entrustid, $episodeid, $appointment_type, $appointment_date);
}
//获取最近可用的,计划 日期
public function NearestEnablePlanDate()
{

@ -15,13 +15,14 @@ class PlanModelController extends Controller
$searchInfo = request('searchInfo');
$page = request('page');
$pageSize = request('pageSize');
$searchInfo['date_type']=$searchInfo['date_type']?$searchInfo['date_type']:1;
$department_id = 0;
$list = DB::table('s_source_roster')
->leftJoin('s_department_resources', 's_source_roster.resources_id', '=', 's_department_resources.id')
// ->leftJoin('s_devices', 's_source_roster.device_id', '=', 's_devices.id')
->leftJoin('s_period', 's_source_roster.period_id', '=', 's_period.id')
->select('s_source_roster.*', 's_department_resources.department_resources_name', 's_period.period_name')
->where(['s_source_roster.is_del' => 0]);
->where(['s_source_roster.is_del' => 0,'s_source_roster.date_type' => $searchInfo['date_type']]);
if ($group == 1) {//如果是管理员
if (!empty($searchInfo['department_id'])) {
$list = $list->where('s_source_roster.department_id', $searchInfo['department_id']);
@ -95,24 +96,29 @@ class PlanModelController extends Controller
public function Save(Request $request)
{
$userid = $request->get('userid');//中间件产生的参数
$bitian = array('xingqi', 'max_total', 'qudao_total', 'period_id', 'begin_time', 'end_time', 'end_reservation_time', 'resources_id', 'devices', 'patientType');
$bitian_zh = array('星期', '当日总量', '渠道数量', '时间段', '开始时间', '结束时间', '停止预约时间', '资源', '设备', '患者类型');
$date_type = request('date_type');
$planInfo = request('planInfo');
$bitian = array('max_total', 'qudao_total', 'period_id', 'begin_time', 'end_time', 'end_reservation_time', 'resources_id', 'devices', 'patientType');
$bitian_zh = array('当日总量', '渠道数量', '时间段', '开始时间', '结束时间', '停止预约时间', '资源', '设备', '患者类型');
if($date_type==1){//如果是普通类型计划 1普通2节假日
$bitian[]='xingqi';
$bitian_zh[]='星期';
}
foreach ($bitian as $key => $field) { //必填项不能为空
if (array_key_exists($field, $planInfo) && $planInfo[$field] !== '' && $planInfo[$field] !== null && $planInfo[$field] !== [] && $planInfo[$field] !== 0) {
} else {
return \Yz::echoError1($bitian_zh[$key] . ' 不能为空');
}
}
if($planInfo['end_reservation_time']>$planInfo['end_time']) return \Yz::echoError1('停止预约时间不能超过结束时间');
$userInfo = DB::table('users')->where(['id' => $userid])->first();
if (!isset($userInfo->department_id)) return \Yz::echoError1('该用户未绑定科室');
$department_id = $userInfo->department_id;
DB::beginTransaction();
foreach ($planInfo['xingqi'] as $key => $value) {
$data = [
'department_id' => $department_id,
'weekname' => $value,
'weekname' => '',
'resources_id' => $planInfo['resources_id'],
'device_id' => isset($planInfo['devices']) ? implode(',', $planInfo['devices']) : '',
'period_id' => $planInfo['period_id'], //时间段id
@ -123,45 +129,52 @@ class PlanModelController extends Controller
'time_unit' => $planInfo['time_unit'],
'status' => $planInfo['status'],
'adduser' => $userid,
'date_type' => $date_type,
];
if($planInfo['end_reservation_time']>$planInfo['end_time']) return \Yz::echoError1('停止预约时间不能超过结束时间');
//判断记录是否存在
$is_ex = DB::table('s_source_roster')->where([
$param=[
'department_id' => $department_id,
'weekname' => $value,
'resources_id' => $planInfo['resources_id'],
// 'period_id' => $planInfo['period_id'], //时间段id
'is_del' => 0,
'date_type' => $date_type,
];
if($date_type==1){
foreach ($planInfo['xingqi'] as $key => $value) {
$data['weekname'] = $value;
//判断记录是否存在
$param['weekname'] = $value;
$check=$this->Check($planInfo,$param,$value);
if(!$check['status']){
DB::rollBack();
return \Yz::echoError1($check['msg']);
}
if ($planInfo['id'] == 0) {//新增
$roster_id = DB::table('s_source_roster')->insertGetId($data);
if ($roster_id) {
foreach ($planInfo['qudao_total'] as $k => $v) {
$i_c = DB::table('s_source_roster_count')->insert([
'roster_id' => $roster_id,
'appointment_type_id' => $v['id'],
'max_total' => $planInfo['max_total'],
'count' => $v['count'],
]);
if ($planInfo['id'] > 0) {
$is_ex = $is_ex->where('id', '<>', $planInfo['id']);
if (!$i_c) {
DB::rollBack();
return \Yz::echoError1('保存失败');
}
$start = $planInfo['begin_time'];
$end = $planInfo['end_time'];
$is_ex = $is_ex->where(function ($query) use ($start, $end) {
// 情况1开始时间在查询区间内
$query->whereBetween('begin_time', [$start, $end])
->orWhereBetween('end_time', [$start, $end]);
// 情况2查询区间的开始时间在数据库记录的开始和结束时间之间
// 注意:对于时间类型的比较,直接使用字符串比较可能不够精确,特别是跨天情况,以下逻辑需根据实际情况调整
$query->orWhere(function ($query) use ($start, $end) {
$query->where('begin_time', '<=', $start)
->where('end_time', '>=', $end);
});
})->get();
// dd($is_ex);
//遍历判断设备是否有重叠,有则返回错误
foreach ($is_ex as $k => $v) {
$db_device_ids = explode(',', $v->device_id);
$overlap = array_intersect($planInfo['devices'], $db_device_ids);
if (count($overlap) > 0) {
}
} else {
DB::rollBack();
return \Yz::echoError1($value . '时段服务组关联重复,计划id为:' . $v->id);
return \Yz::echoError1('保存失败');
}
}
}
}elseif ($date_type==2){
$check=$this->Check($planInfo,$param,"当前选定的");
if(!$check['status']){
DB::rollBack();
return \Yz::echoError1($check['msg']);
}
if ($planInfo['id'] == 0) {//新增
$roster_id = DB::table('s_source_roster')->insertGetId($data);
if ($roster_id) {
@ -181,7 +194,10 @@ class PlanModelController extends Controller
DB::rollBack();
return \Yz::echoError1('保存失败');
}
} else {//修改
}
}
if($planInfo['id'] > 0) {//修改
$data['id'] = $planInfo['id'];
$i = DB::table('s_source_roster')->where(['id' => $planInfo['id'], 'is_del' => 0])->update($data);
@ -200,10 +216,40 @@ class PlanModelController extends Controller
}
}
}
DB::commit();
return \Yz::Return(true, '保存成功', []);
}
//检测提交的信息是否有效
function Check($planInfo,$param,$shiduan)
{
$is_ex = DB::table('s_source_roster')->where($param);
if ($planInfo['id'] > 0) {
$is_ex = $is_ex->where('id', '<>', $planInfo['id']);
}
$start = $planInfo['begin_time'];
$end = $planInfo['end_time'];
$is_ex = $is_ex->where(function ($query) use ($start, $end) {
// 情况1开始时间在查询区间内
$query->whereBetween('begin_time', [$start, $end])
->orWhereBetween('end_time', [$start, $end]);
// 情况2查询区间的开始时间在数据库记录的开始和结束时间之间
// 注意:对于时间类型的比较,直接使用字符串比较可能不够精确,特别是跨天情况,以下逻辑需根据实际情况调整
$query->orWhere(function ($query) use ($start, $end) {
$query->where('begin_time', '<=', $start)
->where('end_time', '>=', $end);
});
})->get();
//遍历判断设备是否有重叠,有则返回错误
foreach ($is_ex as $k => $v) {
$db_device_ids = explode(',', $v->device_id);
$overlap = array_intersect($planInfo['devices'], $db_device_ids);
if (count($overlap) > 0) {
return ['status'=>false,'msg'=>$shiduan . '时段服务组关联重复,计划id为:' . $v->id];
}
}
return ['status'=>true,'msg'=>''];
}
//获取模板信息详情
public function GetDetailInfo()

@ -57,11 +57,12 @@ class TimePeriodController extends Controller
$searchInfo =request('searchInfo');
$page =request('page');
$pageSize =request('pageSize');
$searchInfo['date_type']=$searchInfo['date_type']?$searchInfo['date_type']:1;
$department_id=0;
$list=DB::table('s_period')
->leftJoin('s_department', 's_period.department_id', '=', 's_department.id')
->select('s_period.*','s_department.department_name')
->where(['s_period.is_del'=>0]);
->where(['s_period.is_del'=>0,'s_period.date_type'=>$searchInfo['date_type']]);
if($group==1){//如果是管理员
if(!empty($searchInfo['department_id'])){
@ -83,9 +84,14 @@ class TimePeriodController extends Controller
{
$userid = $request->get('userid');//中间件产生的参数
$group = $request->get('role');//中间件产生的参数
$date_type =request('date_type');
$userInfo = DB::table('users')->where(['id'=>$userid])->get();
$department_id=$userInfo[0]->department_id;
$list=DB::table('s_period');
if(isset($date_type)){
$list=$list->where('date_type',$date_type);
}
$list=$list->where(['department_id'=>$department_id,'period_status'=>1,'is_del'=>0])->get();
if(count($list)>0){
return \Yz::Return(true, '操作成功',$list);

@ -1,6 +1,6 @@
ENV = 'production'
VITE_APP_API = 'http://10.50.120.166/YiJiYuYue/Laravel/public/api/'
VITE_APP_FILE = 'http://10.50.120.166/YiJiYuYue/Laravel/public/'
VITE_APP_API_66 = 'http://10.50.120.166/YiJiYuYue/Laravel/public/api/'
VITE_APP_FILE_666 = 'http://10.50.120.166/YiJiYuYue/Laravel/public/'
VITE_APP_API_6666 = 'https://yiji.yuluo.online/Laravel/public/api/'
VITE_APP_FILE_555 = 'https://yiji.yuluo.online/Laravel/public/'
VITE_APP_API = 'https://yiji.yuluo.online/Laravel/public/api/'
VITE_APP_FILE = 'https://yiji.yuluo.online/Laravel/public/'

@ -43,11 +43,18 @@
<el-button type="success" @click="CreatedPlanClick()" style="margin-left: 20px;">生成选中的计划</el-button>
</el-row>
</div>
<el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%;" row-key="id" v-loading="loading"
@selection-change="handleSelectionChange">
<el-row>
<el-radio-group style="margin-bottom: 8px;" v-model="searchInfo.date_type"
@change="DateTypeChange()">
<el-radio-button :label="1">工作日</el-radio-button>
<el-radio-button :label="2">节假日</el-radio-button>
</el-radio-group>
</el-row>
<el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%;" row-key="id"
v-loading="loading" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column prop="id" label="Id" width="70" />
<el-table-column prop="weekname" label="星期" width="80" />
<el-table-column prop="weekname" label="星期" width="80" v-if="searchInfo.date_type==1"/>
<el-table-column prop="resources_id" label="" v-if="false" />
<el-table-column prop="department_resources_name" label="资源" width="150" />
<el-table-column prop="" label="服务组" show-overflow-tooltip width="150">
@ -92,12 +99,12 @@
: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="dialogVisible" title="时间段" width="45%">
<el-dialog v-model="dialogVisible" :title="'时间段('+date_type_name+')'" width="45%">
<el-form ref="PlanInfoForm" :model="PlanInfo" label-width="100px" v-loading="loading"
style="padding-right: 40px;">
<el-form-item label="星期:" prop="xingqi">
<el-checkbox :disabled="PlanInfo.id==0?false:true" style="margin-right: 8px;" v-model="CheckedAll" @change="CheckedAllFunc"
label="全选"><span style="font-weight: 700;color: #409eff;">全选</span>
<el-form-item label="星期:" prop="xingqi" v-if="searchInfo.date_type==1">
<el-checkbox :disabled="PlanInfo.id==0?false:true" style="margin-right: 8px;" v-model="CheckedAll"
@change="CheckedAllFunc" label="全选"><span style="font-weight: 700;color: #409eff;">全选</span>
</el-checkbox>
<el-checkbox-group v-model="PlanInfo.xingqi">
<el-checkbox :disabled="PlanInfo.id==0?false:true" v-for="(item, index) in xingqi" :key="index"
@ -106,11 +113,20 @@
</el-checkbox-group>
</el-form-item>
<el-form-item label="渠道名额:">
<div style="margin-right: 16px">
<div>当日总量</div>
<div style="margin-right: 26px">
<div>
<el-radio-group v-model="CountType" @change="CountTypeChange">
<el-radio label="1">根据总量</el-radio>
<el-radio style="margin-left: -10px;" label="2">根据时长(分钟)</el-radio>
</el-radio-group>
</div>
<div class="qudao_k_input">
<el-input @input="MaxCountChange" type="number" v-model="PlanInfo.max_total" :min="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
<el-input v-if="CountType==1" style="width: 220px;" @input="MaxCountChange" type="number"
v-model="PlanInfo.max_total" :min="1" placeholder="0"
oninput="value=value.replace(/^0|[^0-9]/g, '')" />
<el-input v-if="CountType==2" style="width: 220px;" @input="TimeLongChange" type="number"
v-model="PlanInfo.time_long" :min="1" placeholder="0"
oninput="value=value.replace(/^0|[^0-9]/g, '')" />
</div>
<div style="font-size: 12px;color: #999">设置渠道比例可自动分配</div>
</div>
@ -172,7 +188,8 @@
</el-select>
</el-form-item>
<el-form-item label="服务组:" v-if="devicesList.length>0">
<div v-if="devicesList.length>1" style="width: 100%;font-size: 12px;color: #999;">()</div>
<div v-if="devicesList.length>1" style="width: 100%;font-size: 12px;color: #999;">
此诊室包含多台设备如同时勾选多个被勾选设备将共同占用分配的名额如需为设备单独分配名额请单独勾选(推荐)</div>
<el-checkbox-group v-model="PlanInfo.devices">
<el-checkbox v-for="(item,index) in devicesList" :key="index"
:label="item.id">{{ item.device_name }}
@ -208,6 +225,10 @@
<el-date-picker v-model="dateRange" type="daterange" range-separator="To" start-placeholder=""
end-placeholder="结束时间" value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item label="节假日生成:">
<el-switch v-model="HolidayEnable" size="large" active-text="" inactive-text=""
:active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
@ -245,7 +266,7 @@
ElMessage,
ElMessageBox
} from 'element-plus'
let CountType = ref("1"); //
let loading = ref(false)
let tableData = ref([])
let currentPage = ref(1) //
@ -284,6 +305,8 @@
CreatePlanList({
dateRange: dateRange.value,
ids: ids,
HolidayEnable:HolidayEnable.value,
date_type:searchInfo.value.date_type
}).then(res => {
if (res.status) {
CreatePlanDialogVisible.value = false;
@ -308,6 +331,8 @@
xingqi: null,
status: null,
})
let HolidayEnable=ref(1)
let date_type_name =ref('工作日')
let dialogVisible = ref(false)
const GetList = () => {
PlanModelGetList({
@ -381,7 +406,11 @@
}
}
const DateTypeChange=()=>{
if(searchInfo.value.date_type==1) date_type_name.value='工作日'
if(searchInfo.value.date_type==2) date_type_name.value='节假日'
GetList()
}
const Save = () => {
// console.log(PlanInfo.value)
//
@ -404,6 +433,7 @@
.then(() => {
loading.value = true
PlanModelSave({
date_type:searchInfo.value.date_type,
planInfo: PlanInfo.value
}).then(res => {
loading.value = false
@ -497,7 +527,6 @@
}
//
const MaxCountChange = (e) => {
console.log(e)
if (e === '' || e == null || e === 0) {
PlanInfo.value.max_total = 0
}
@ -536,7 +565,8 @@
PlanInfo.value.qudao_total[index].count = PlanInfo.value.qudao_total[index].count - bodongzhi
}
if (bodongzhi < 0 && index > 0) {
PlanInfo.value.qudao_total[index-1].count = PlanInfo.value.qudao_total[index-1].count -bodongzhi
PlanInfo.value.qudao_total[index - 1].count = PlanInfo.value.qudao_total[index - 1].count -
bodongzhi
}
if (bodongzhi < 0 && index == 0) {
PlanInfo.value.qudao_total[index].count = PlanInfo.value.qudao_total[index].count - bodongzhi
@ -551,7 +581,7 @@
let TimePeriodList = ref([])
const GetEnableTimePeriod = () => {
loading.value = true
TimePeriodGetEnableList().then(res => {
TimePeriodGetEnableList({date_type:searchInfo.value.date_type}).then(res => {
loading.value = false
if (res.status) {
TimePeriodList.value = res.data
@ -688,30 +718,89 @@
let nextRow = tableData.value[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue && prevRow.declareRegion == row.declareRegion) {
bb_countRowspan = countRowspan
return {rowspan:0,colspan:0}
return {
rowspan: 0,
colspan: 0
}
} else {
while(nextRow && nextRow[column.property]===cellValue && nextRow.declareRegion==row.declareRegion){
while (nextRow && nextRow[column.property] === cellValue && nextRow.declareRegion == row
.declareRegion) {
nextRow = tableData.value[++countRowspan + rowIndex]
}
if (countRowspan > 1) {
bb_countRowspan = countRowspan
return {rowspan:countRowspan,colspan:1}
return {
rowspan: countRowspan,
colspan: 1
}
}
}
}
if (columnIndex === 3) {
if(bb_countRowspan>1){
return {rowspan:bb_countRowspan,colspan:1}
}else{
return {rowspan:0,colspan:0}
// if (columnIndex === 3) {
// if (bb_countRowspan > 1) {
// return {
// rowspan: bb_countRowspan,
// colspan: 1
// }
// } else {
// return {
// rowspan: 0,
// colspan: 0
// }
// }
// }
}
//
const CountTypeChange = (e) => {
CountType.value = e
MaxCountChange(0)
TimeLongChange(0)
if (e == 2) {
}
}
//
const TimeLongChange=(timelong)=>{
if (CountType.value == 2) { //
if (PlanInfo.value.begin_time == '' || PlanInfo.value.end_time == '') {
ElMessage.error("请先设置时段")
PlanInfo.value.max_total = 0
return false
}
ComPuteCountByTime(timelong)
}
}
//
const ComPuteCountByTime = (timelong) => {
let count=calculateTimeSegments(PlanInfo.value.begin_time,PlanInfo.value.end_time,timelong)
PlanInfo.value.max_total=count
MaxCountChange(count)
}
//
function calculateTimeSegments(startTime, endTime, span) {
//
function timeToMinutes(timeStr) {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
}
const startMinutes = timeToMinutes(startTime);
const endMinutes = timeToMinutes(endTime);
//
const totalMinutes = endMinutes - startMinutes;
//
const segments = Math.floor(totalMinutes / span);
return segments;
}
onMounted(() => {
searchInfo.value.date_type=1
GetList()
GetDepartmentEnableList()
getEnableResource()

@ -13,6 +13,13 @@
<el-button type="primary" @click="Add()" style="margin-left: 10px;">添加</el-button>
</el-row>
</div>
<el-row>
<el-radio-group style="margin-bottom: 8px;" v-model="searchInfo.date_type"
@change="DateTypeChange()">
<el-radio-button :label="1">工作日</el-radio-button>
<el-radio-button :label="2">节假日</el-radio-button>
</el-radio-group>
</el-row>
<el-table :data="tableData" style="width: 100%;" row-key="id" v-loading="loading">
<el-table-column prop="id" label="Id" width="100" />
<el-table-column prop="department_name" label="科室名称" />
@ -132,7 +139,7 @@
}
PeriodInfo.value.period_begin_time=PeriodInfo.value.timeRange[0]
PeriodInfo.value.period_end_time=PeriodInfo.value.timeRange[1]
PeriodInfo.value.date_type=searchInfo.value.date_type
loading.value = true
TimePeriodSave({PeriodInfo:PeriodInfo.value}).then(res => {
loading.value = false
@ -207,12 +214,14 @@
}
//
const changeTimeRange=()=>{
PeriodInfo.value.period_deadline=PeriodInfo.value.timeRange[1]
}
//
const DateTypeChange=()=>{
GetList()
}
onMounted(()=>{
searchInfo.value.date_type=1
GetList()
GetDepartmentEnableList()
})

Loading…
Cancel
Save