时间段配置剥离。渠道号源只保留医生渠道

dev2
鹿和sa0ChunLuyu 3 hours ago
parent 3db2ba7bd0
commit cefbc90016

@ -16,7 +16,7 @@ public function GetList(){
$list=DB::table('s_list')
->leftJoin('s_period','s_list.reservation_time','=','s_period.id')
->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id')
->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name');
->select('s_list.*',DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),'s_department_resources.department_resources_name');
if ($searchInfo['dateRange']!=null and count($searchInfo['dateRange']) == 2) {
$list = $list->where(function ($q) use($searchInfo) {
$q->whereBetween('s_list.entrust_date', $searchInfo['dateRange'])
@ -85,7 +85,7 @@ public function getMainDetail_duoren()
$allInfo=[];
foreach ($entrustInfos as $key => $entrustInfo) {
$info = DB::table('s_list as a')->where(['a.reg_num' => $entrustInfo['reg_num'], 'a.episodeid'=>$entrustInfo['episodeid'],'a.is_nullify'=>0])
->select('a.*','c.period_begin_time','c.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'))
->leftJoin('s_period as c','a.reservation_time','=','c.id')
->whereIn('a.entrust_id',$entrustInfo['entrustid'])
->get();

@ -175,6 +175,13 @@ public function ChangeInfo(Request $request)
$u1 = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
'status' => $PlanDetaiInfo['status']
]);
// 更新截止时间
$timeUpdated = false;
if (isset($PlanDetaiInfo['end_reservation_time'])) {
$timeUpdated = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
'end_reservation_time' => $PlanDetaiInfo['end_reservation_time']
]) > 0;
}
$i = 0;
foreach ($PlanDetaiInfo['coutsInfo'] as $key => $value) {
$u2 = DB::table('s_source_roster_detail_count')->where(['id' => $value['id']])->update([
@ -183,7 +190,7 @@ public function ChangeInfo(Request $request)
]);
if ($u2) $i++;
}
if ($u1 or $i > 0) {
if ($u1 or $i > 0 or $timeUpdated) {
return \Yz::Return(true, '保存成功', []);
} else {
return \Yz::echoError1('没有数据更新');
@ -881,6 +888,13 @@ public function ChangeInfoAdmin(Request $request)
$u1 = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
'status' => $PlanDetaiInfo['status']
]);
// 更新截止时间
$timeUpdated = false;
if (isset($PlanDetaiInfo['end_reservation_time'])) {
$timeUpdated = DB::table('s_source_roster_detail')->where(['id' => $PlanDetaiInfo['id']])->update([
'end_reservation_time' => $PlanDetaiInfo['end_reservation_time']
]) > 0;
}
$i = 0;
foreach ($PlanDetaiInfo['coutsInfo'] as $key => $value) {
$u2 = DB::table('s_source_roster_detail_count')->where(['id' => $value['id']])->update([
@ -889,7 +903,7 @@ public function ChangeInfoAdmin(Request $request)
]);
if ($u2) $i++;
}
if ($u1 or $i > 0) {
if ($u1 or $i > 0 or $timeUpdated) {
return \Yz::Return(true, '保存成功', []);
} else {
return \Yz::echoError1('没有数据更新');
@ -1179,6 +1193,7 @@ public function BatchChangeCount(Request $request)
$ids = request('ids');
$max_total = request('max_total');
$coutsInfo = request('coutsInfo');
$end_reservation_time = request('end_reservation_time');
if (empty($ids) || empty($coutsInfo)) {
return \Yz::echoError1('参数错误');
}
@ -1197,7 +1212,16 @@ public function BatchChangeCount(Request $request)
WHERE roster_detail_id IN ({$idsStr})
AND appointment_type_id IN ({$atypeIdsStr})";
$u2 = DB::update($sql);
if ($u2 > 0) {
$timeUpdated = false;
// 更新截止时间(同一时间段时传入)
if ($end_reservation_time !== null) {
$timeUpdated = DB::table('s_source_roster_detail')
->whereIn('id', $ids)
->where('department_id', $department_id)
->where('is_del', 0)
->update(['end_reservation_time' => $end_reservation_time]) > 0;
}
if ($u2 > 0 || $timeUpdated) {
return \Yz::Return(true, '批量修改成功', []);
} else {
return \Yz::echoError1('批量修改失败');

@ -558,7 +558,7 @@ public function BatchEnable(Request $request)
}
}
//批量修改计划模板(渠道数量+病人类型)
//批量修改计划模板(渠道数量+病人类型+可选时间字段
public function BatchChange(Request $request)
{
$userid = $request->get('userid');
@ -566,6 +566,9 @@ public function BatchChange(Request $request)
$max_total = request('max_total');
$coutsInfo = request('coutsInfo');
$patientType = request('patientType');
$begin_time = request('begin_time');
$end_time = request('end_time');
$end_reservation_time = request('end_reservation_time');
if (empty($ids) || !is_array($ids)) {
return \Yz::echoError1('请选择要修改的记录');
@ -585,11 +588,19 @@ public function BatchChange(Request $request)
$patient_type_str = !empty($patientType) ? implode(',', $patientType) : '';
foreach ($ids as $id) {
$rosterData = [];
// 更新病人类型
if ($patient_type_str !== '') {
$rosterData['patient_type'] = $patient_type_str;
}
// 更新时间字段(同一时间段时传入)
if ($begin_time !== null) $rosterData['begin_time'] = $begin_time;
if ($end_time !== null) $rosterData['end_time'] = $end_time;
if ($end_reservation_time !== null) $rosterData['end_reservation_time'] = $end_reservation_time;
if (!empty($rosterData)) {
DB::table('s_source_roster')
->where(['id' => $id, 'department_id' => $department_id, 'is_del' => 0])
->update(['patient_type' => $patient_type_str]);
->update($rosterData);
}
// 更新渠道数量
@ -912,7 +923,7 @@ public function BatchEnableAdmin(Request $request)
}
}
//管理员批量修改计划模板(渠道数量+病人类型)
//管理员批量修改计划模板(渠道数量+病人类型+可选时间字段
public function BatchChangeAdmin(Request $request)
{
$department_id = request('department_id');
@ -923,6 +934,9 @@ public function BatchChangeAdmin(Request $request)
$max_total = request('max_total');
$coutsInfo = request('coutsInfo');
$patientType = request('patientType');
$begin_time = request('begin_time');
$end_time = request('end_time');
$end_reservation_time = request('end_reservation_time');
if (empty($ids) || !is_array($ids)) {
return \Yz::echoError1('请选择要修改的记录');
@ -936,11 +950,19 @@ public function BatchChangeAdmin(Request $request)
$patient_type_str = !empty($patientType) ? implode(',', $patientType) : '';
foreach ($ids as $id) {
$rosterData = [];
// 更新病人类型
if ($patient_type_str !== '') {
$rosterData['patient_type'] = $patient_type_str;
}
// 更新时间字段(同一时间段时传入)
if ($begin_time !== null) $rosterData['begin_time'] = $begin_time;
if ($end_time !== null) $rosterData['end_time'] = $end_time;
if ($end_reservation_time !== null) $rosterData['end_reservation_time'] = $end_reservation_time;
if (!empty($rosterData)) {
DB::table('s_source_roster')
->where(['id' => $id, 'department_id' => $department_id, 'is_del' => 0])
->update(['patient_type' => $patient_type_str]);
->update($rosterData);
}
// 更新渠道数量

@ -16,7 +16,7 @@ public function SignIn(Request $request)
$MainListIds = request('MainListIds');
if(empty($MainListIds)) return \Yz::echoError1('id参数不能为空');
$mainInfos=DB::table('s_list as a')
->select('a.*','b.period_begin_time','b.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, b.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, b.period_end_time) as period_end_time'))
->leftJoin('s_period as b','a.reservation_time','=','b.id')
->whereIn('a.id',$MainListIds)->where(['a.is_del'=>0])->get();
//遍历判断所有要预约的医嘱是否符合条件
@ -145,7 +145,7 @@ public function CancelSign(Request $request)
$MainListIds = request('MainListIds');
if(empty($MainListIds)) return \Yz::echoError1('id参数不能为空');
$mainInfos=DB::table('s_list as a')
->select('a.*','b.period_begin_time','b.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, b.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, b.period_end_time) as period_end_time'))
->leftJoin('s_period as b','a.reservation_time','=','b.id')
->whereIn('a.id',$MainListIds)->where(['a.is_del'=>0])->get();
//遍历判断所有要预约的医嘱是否符合条件

@ -28,7 +28,7 @@ public function getMainDetail()
$arrayEntrustids = explode(",", $entrustids);
$info = DB::table('s_list as a')->where(['a.reg_num' => $regnum, 'a.episodeid'=>$episodeid,'a.is_nullify'=>0])
->select('a.*','c.period_begin_time','c.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'))
->leftJoin('s_period as c','a.reservation_time','=','c.id')
->whereIn('a.entrust_id',$arrayEntrustids)
->get();
@ -224,7 +224,7 @@ public function GetList(Request $request)
$list=DB::table('s_list')
->leftJoin('s_period','s_list.reservation_time','=','s_period.id')
->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id')
->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name')
->select('s_list.*',DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),'s_department_resources.department_resources_name')
->where(['s_list.is_del'=>0]);
if($userInfo[0]->group==2){
// $list=$list->whereIn('warddesc', explode(",", $userInfo[0]->ward));
@ -360,7 +360,7 @@ public function GetListByDept(Request $request)
$list = DB::table('s_list')
->leftJoin('s_period', 's_list.reservation_time', '=', 's_period.id')
->leftJoin('s_department_resources', 's_list.reservation_sources', '=', 's_department_resources.id')
->select('s_list.*', 's_period.period_begin_time', 's_period.period_end_time', 's_department_resources.department_resources_name')
->select('s_list.*', DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'), DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'), 's_department_resources.department_resources_name')
->where(['s_list.is_del' => 0, 's_list.is_nullify' => 0]);
// 选中具体科室时,按科室编号过滤
@ -534,7 +534,7 @@ public function CheckIsDaiJian()
$planTime=[$plan->date.' '.$plan->begin_time,$plan->date.' '.$plan->end_time];
$query=DB::table('s_list')->where(['reg_num'=>$reg_num,'list_status'=>1,'is_nullify'=>0])
->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name')
->select('s_list.*',DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),'s_department_resources.department_resources_name')
->leftJoin('s_period','s_list.reservation_time','=','s_period.id')
->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id')
->get();
@ -572,6 +572,9 @@ public function NoPayCancel()
$u_data = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,
@ -631,6 +634,9 @@ public function NoPayCancel()
$u_data = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,
@ -684,7 +690,7 @@ public function GetPersonYuYueList()
$list=DB::table('s_list')
->leftJoin('s_period','s_list.reservation_time','=','s_period.id')
->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id')
->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name')
->select('s_list.*',DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),'s_department_resources.department_resources_name')
->where(['s_list.is_del'=>0,'s_list.is_nullify'=>0])
->where('s_list.reg_num', $reg_num)
->whereIn('list_status',[1,2,3]);

@ -18,8 +18,8 @@ public function GetList(Request $request)
->leftJoin('s_department_resources', 's_list.reservation_sources', '=', 's_department_resources.id')
->select(
's_list.*',
's_period.period_begin_time',
's_period.period_end_time',
DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),
DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),
's_department_resources.department_resources_name'
)
->where(['s_list.is_del' => 0, 's_list.is_nullify' => 0])
@ -45,7 +45,7 @@ public function GetDetail(Request $request)
$id = request('id');
$userid = $request->get('userid');//中间件产生的参数
$info = DB::table('s_list as a')->where(['a.id'=>$id,'a.reg_num' => $userid])
->select('a.*','c.period_begin_time','c.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'))
->leftJoin('s_period as c','a.reservation_time','=','c.id')
->first();
if($info){

@ -118,8 +118,8 @@ public function GetCheckPdf()
$list = DB::table('s_list as a')
->select(
'a.*',
'c.period_begin_time',
'c.period_end_time',
DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),
DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'),
'b.department_resources_name',
'b.department_resources_addr'
)
@ -431,7 +431,7 @@ public function CreateJianChaShenQingDanPdf()
$successCount=0;
foreach ($OrderNoList as $orderNo) {
$entrustInfo=DB::table('s_list as a')->where(['a.entrust_id'=>$orderNo,'a.list_status'=>1,'a.is_nullify'=>0])
->select('a.*','c.period_begin_time','c.period_end_time')
->select('a.*',DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'))
->leftJoin('s_period as c','a.reservation_time','=','c.id')
->first();
if(!$entrustInfo) continue;
@ -499,8 +499,8 @@ public function GenerateGroupedCheckPdf()
$list = DB::table('s_list as a')
->select(
'a.*',
'c.period_begin_time',
'c.period_end_time',
DB::raw('COALESCE(a.reservation_begin_time, c.period_begin_time) as period_begin_time'),
DB::raw('COALESCE(a.reservation_end_time, c.period_end_time) as period_end_time'),
'b.department_resources_name',
'b.department_resources_addr'
)
@ -745,7 +745,7 @@ public function PrintMainList()
$list = DB::table('s_list')
->leftJoin('s_period','s_list.reservation_time','=','s_period.id')
->leftJoin('s_department_resources','s_list.reservation_sources','=','s_department_resources.id')
->select('s_list.*','s_period.period_begin_time','s_period.period_end_time','s_department_resources.department_resources_name','s_department_resources.department_resources_addr')
->select('s_list.*',DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as period_begin_time'),DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as period_end_time'),'s_department_resources.department_resources_name','s_department_resources.department_resources_addr')
->where(['s_list.is_del'=>0,'s_list.is_nullify'=>0]);
if($userInfo->group==2){

@ -343,6 +343,9 @@ public function CancelApply ($orderNo)
$clearData = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,

@ -51,8 +51,8 @@ public function GetEntrustInfo(){
"episodeid",
"RISRAcceptDeptCode",
"reservation_date",
's_period.period_begin_time as reservation_time',
's_period.period_end_time as reservation_end_time',
DB::raw('COALESCE(s_list.reservation_begin_time, s_period.period_begin_time) as reservation_time'),
DB::raw('COALESCE(s_list.reservation_end_time, s_period.period_end_time) as reservation_end_time'),
"canel_time as cancel_time",
"warddesc",
"wardcode",

@ -1113,7 +1113,7 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
//遍历多个s_list表id,前端多选,一次预约多个检查项目
foreach ($mainlistids as $key_m => $mainlistid) {
$mainInfo = DB::table('s_list as a')
->select('a.*', 'b.period_begin_time', 'b.period_end_time')
->select('a.*', DB::raw('COALESCE(a.reservation_begin_time, b.period_begin_time) as period_begin_time'), DB::raw('COALESCE(a.reservation_end_time, b.period_end_time) as period_end_time'))
->leftJoin('s_period as b', 'a.reservation_time', '=', 'b.id')
->where(['a.id' => $mainlistid])->first();
$oldMainInfos[] = $mainInfo;
@ -1760,6 +1760,9 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme
$u_data = [
'list_status' => 1,
'reservation_date' => $planInfo->date,
'reservation_begin_time' => $planInfo->begin_time,
'reservation_end_time' => $planInfo->end_time,
'reservation_deadline_time' => $planInfo->end_reservation_time,
'reservation_time' => $planInfo->period_id,
'reservation_sources' => $planInfo->resources_id,
'services_group' => $planInfo->device_id,
@ -1959,6 +1962,9 @@ public function CancelYuYue($MainListId, $reg_num,$do_user=null)
$u_data = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,
@ -2031,6 +2037,9 @@ public function BatchCancelYuYue($ids, $reg_num, $do_user = null)
$u_data = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,
@ -2744,7 +2753,7 @@ public function SendMsg($infos,$dotype=1)
$s=new SendMessgeService();
foreach ($infos as $key => $info) {
$mainInfo = DB::table('s_list as a')
->select('a.*', 'b.period_begin_time', 'b.period_end_time')
->select('a.*', DB::raw('COALESCE(a.reservation_begin_time, b.period_begin_time) as period_begin_time'), DB::raw('COALESCE(a.reservation_end_time, b.period_end_time) as period_end_time'))
->leftJoin('s_period as b', 'a.reservation_time', '=', 'b.id')
->where(['a.id' => $info->id])->first();
$s->sendMessage($info->user_phone,'测试短信,项目:'.$mainInfo->entrust.',时间:'.$mainInfo->reservation_date.' '.substr($mainInfo->period_begin_time,0,5).'-'.substr($mainInfo->period_end_time,0,5));

@ -150,6 +150,9 @@ public function UpdateStatus($result, $jsonData)
$clearData = [
'list_status' => 0,
'reservation_date' => null,
'reservation_begin_time' => null,
'reservation_end_time' => null,
'reservation_deadline_time' => null,
'reservation_time' => null,
'reservation_sources' => null,
'services_group' => null,

@ -73,7 +73,7 @@
</div>
</div>
</td>
<td style="min-width: 120px;font-size: 14px;" v-for="(item,index) in date_list">{{item.substring(5,10)}} {{getWeekday(item)}}</td>
<td style="min-width: 150px;font-size: 14px;" v-for="(item,index) in date_list">{{item.substring(5,10)}} {{getWeekday(item)}}</td>
</tr>
<tr v-for="(item,index) in planTableData" :key="index">
<td v-for="(item2,index2) in item" :key="index2"
@ -110,14 +110,29 @@
@click="checkBoxCheckFunc(item2.id)">
<el-icon v-if="isSelected(item2.id)" color="#ffffff"><Select /></el-icon>
</div>
<div class="zong_row"><div class="qudao_title_zong"><span>总数:</span>{{item2.countsInfo[0].max_total}}</div></div>
<div class="qudao_count_row">
<template v-for="(item3,index3) in item2.countsInfo" :key="index3">
<div v-if="item3 && !(item3.count===0 && item3.used_count===0)">
<span> {{item3.jiancheng}}</span><span><span :class="{'yellow bold-text': item3.locked_count > 0}">{{ item3.locked_count != null ? item3.locked_count : 0 }}</span><span>/</span><span class="font_color">{{item3.used_count}}</span>/{{item3.count}} </span>
<!-- 模式A只有医生渠道有数量 -->
<template v-if="!hasOtherChannelCount(item2.countsInfo)">
<div class="qudao_count_row qudao_count_row_simple">
<div style="display: flex; gap: 12px; justify-content: center;">
<span class="card_locked"> {{getTotalLocked(item2.countsInfo)}}</span>
<span class="font_color"> {{getTotalUsed(item2.countsInfo)}}</span>
</div>
</template>
</div>
<div style="display: flex; justify-content: center; width: 100%; margin-top: 4px;">
<span class="card_total"> {{item2.countsInfo[0].max_total}}</span>
</div>
</div>
</template>
<!-- 模式B多渠道有数量 -->
<template v-else>
<div class="zong_row"><div class="qudao_title_zong"><span>总数:</span>{{item2.countsInfo[0].max_total}}</div></div>
<div class="qudao_count_row">
<template v-for="(item3,index3) in item2.countsInfo" :key="index3">
<div v-if="item3 && !(item3.count===0 && item3.used_count===0 && item3.locked_count===0)">
<span> {{item3.jiancheng}}</span><span><span :class="{'yellow bold-text': item3.locked_count > 0}">{{ item3.locked_count != null ? item3.locked_count : 0 }}</span><span>/</span><span class="font_color">{{item3.used_count}}</span>/{{item3.count}} </span>
</div>
</template>
</div>
</template>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
@ -170,25 +185,20 @@
}} </span> 结束时间<span
style="font-weight: 700;display: inline-block;margin-right: 8px">{{ PlanDetaiInfo.end_time }}
</span>
停止预约时间<span style="font-weight: 700">{{ PlanDetaiInfo.end_reservation_time }}</span>
停止预约时间<el-input v-model="PlanDetaiInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px; display: inline-block;" />
</el-form-item>
<el-form-item label="渠道名额:" v-if="PlanDetaiInfo.coutsInfo">
<div style="margin-right: 16px">
<div>当日总量</div>
<div class="qudao_k_input">
<el-input @input="MaxCountChange" type="number" v-model="PlanDetaiInfo.max_total"
:min="1" placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
</div>
<div style="font-size: 12px;color: #999">设置渠道比例可自动分配</div>
</div>
<el-form-item label="号源数量:" v-if="PlanDetaiInfo.coutsInfo">
<div>
<div class="qudao_k" v-for="(item,index) in PlanDetaiInfo.coutsInfo" :key="index">
<div style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input">
<el-input type="number" v-model="PlanDetaiInfo.coutsInfo[index].count" :min="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
<template v-for="(item,index) in PlanDetaiInfo.coutsInfo" :key="index">
<div class="qudao_k"
v-if="visibleChannelIds.has(item.appointment_type_id || item.id)">
<div v-if="visibleChannelIds.size > 1" style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input">
<el-input type="number" v-model="PlanDetaiInfo.coutsInfo[index].count" :min="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
</div>
</div>
</div>
</template>
</div>
</el-form-item>
<el-form-item label="状态:">
@ -269,9 +279,9 @@
<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">
<template v-if="ZhanWeiInfo.coutsInfo && ZhanWeiInfo.coutsInfo.length > 0">
<template v-for="(item,index) in ZhanWeiInfo.coutsInfo" :key="index">
<div v-if="item && !(item.count===0 && item.used_count===0)"
<div v-if="item && !(item.count===0 && item.used_count===0 && item.locked_count===0)"
style="display: flex; align-items: center; gap: 10px;">
<div style="width: 80px;">{{ item.name }}</div>
<div v-if="visibleZhanWeiChannelIds.size > 1" style="width: 80px;">{{ item.name }}</div>
<div style="flex: 1;">
<el-input type="number" v-model="ZhanWeiInfo.coutsInfo[index].locked_count" placeholder="占位数量" min="0"
oninput="value=value.replace(/[^0-9]/g,'')" />
@ -313,22 +323,27 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">数量</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')" />
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">数量: {{ batchTotalCount }}</el-col>
</el-row>
<el-form-item label="号源数量:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="ch.id === 1 || visibleBatchChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
</template>
</div>
</el-form-item>
</el-form>
<div v-if="batchSameTimeSlot" style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">时间段设置</div>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<div style="display: flex; align-items: center;">
<div style="width: 90px">停止预约时间:</div>
<el-input v-model="batchTimeInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px;" />
</div>
</div>
</div>
</div>
<template #footer>
<el-button @click="BatchModifyDialogVisible = false" :disabled="batchModifyRunning">取消</el-button>
@ -340,28 +355,21 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">占用数量</el-col>
<el-col :span="8">提示</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
</el-col>
<el-col :span="8" style="line-height: 32px; font-size: 12px; color: #999;">
<template v-if="batchOccupyLimits[ch.id]?.maxValue !== null">
最大可占: {{ batchOccupyLimits[ch.id].maxValue }}
</template>
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">占用: {{ batchOccupyTotalLocked }}</el-col>
</el-row>
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="visibleBatchOccupyChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchOccupyChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
<span style="color: #999; font-size: 12px;">
最大可占: {{ batchOccupyLimits[ch.id]?.maxValue }}
</span>
</div>
</template>
</div>
</el-form-item>
<el-form-item label="占位备注:" style="margin-top: 10px;">
<el-input
type="textarea"
@ -453,6 +461,7 @@
dateRange: []
})
let PlanDetailDialogVisible = ref(false)
let visibleChannelIds = ref(new Set())
const GetList = () => {
searchInfo.value.resources_id = ResourceActive.value
date_list.value = getAllDatesBetweenDates(searchInfo.value.dateRange)
@ -501,8 +510,10 @@
patient_type_label: matchingPlan.patient_type_label,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id: matchingPlan.resources_id
resources_id: matchingPlan.resources_id,
begin_time: matchingPlan.begin_time,
end_time: matchingPlan.end_time,
end_reservation_time: matchingPlan.end_reservation_time
};
}else{
row[date] = {
@ -750,6 +761,12 @@
loading.value = false
if (res.status) {
PlanDetaiInfo.value = res.data
// id=1 count>0 locked_count>0
visibleChannelIds.value = new Set(
PlanDetaiInfo.value.coutsInfo
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0 || Number(item.locked_count) > 0)
.map(item => item.appointment_type_id || item.id)
)
} else {
ElMessage.error(res.msg)
}
@ -786,10 +803,7 @@
PlanDetaiInfo.value.coutsInfo.forEach((item) => {
tempCount = tempCount + Number(item.count)
})
if (tempCount !== Number(PlanDetaiInfo.value.max_total)) {
ElMessage.error('各个渠道数量之和与当日总量不符')
return false
}
PlanDetaiInfo.value.max_total = tempCount
loading.value = true
PlanDetailChangeInfo({
PlanDetaiInfo: PlanDetaiInfo.value
@ -797,6 +811,7 @@
loading.value = false
if (res.status) {
PlanDetailDialogVisible.value = false
ElMessage.success('保存成功')
GetList()
} else {
ElMessage.error(res.msg)
@ -911,6 +926,10 @@
{ name: '自助机', id: 3 }
]
let batchForm = ref([])
let batchSameTimeSlot = ref(false)
let batchTimeInfo = ref({ begin_time: '', end_time: '', end_reservation_time: '' })
let visibleBatchChannelIds = ref(new Set())
let visibleBatchOccupyChannelIds = ref(new Set())
const initBatchForm = () => {
batchForm.value = batchChannels.map(ch => ({
appointment_type_id: ch.id,
@ -927,22 +946,27 @@
return
}
initBatchForm()
// planTableData count
// planTableData count locked_count
const selectedIds = new Set(selectedPlanArr.value)
const channelValues = {}
batchChannels.forEach(ch => {
channelValues[ch.id] = { count: [] }
channelValues[ch.id] = { count: [], locked_count: [] }
})
const selectedCells = []
planTableData.value.forEach(row => {
for (const key in row) {
if (key === 'time_range') continue
const cell = row[key]
if (cell && cell.id && selectedIds.has(cell.id) && cell.countsInfo) {
cell.countsInfo.forEach(ci => {
if (channelValues[ci.appointment_type_id]) {
channelValues[ci.appointment_type_id].count.push(ci.count)
}
})
if (cell && cell.id && selectedIds.has(cell.id)) {
selectedCells.push(cell)
if (cell.countsInfo) {
cell.countsInfo.forEach(ci => {
if (channelValues[ci.appointment_type_id]) {
channelValues[ci.appointment_type_id].count.push(ci.count)
channelValues[ci.appointment_type_id].locked_count.push(Number(ci.locked_count) || 0)
}
})
}
}
}
})
@ -955,6 +979,53 @@
count: vals.count.length > 0 && allSame(vals.count) ? vals.count[0] : ''
}
})
// count>0 locked_count>0
visibleBatchChannelIds.value = new Set(
batchChannels
.filter(ch => {
if (ch.id === 1) return true
const vals = channelValues[ch.id]
if (vals.count.some(v => v > 0)) return true
if (vals.locked_count.some(v => v > 0)) return true
return false
})
.map(ch => ch.id)
)
//
if (selectedCells.length > 0) {
const firstBegin = selectedCells[0].begin_time
const firstEnd = selectedCells[0].end_time
const allSameTime = selectedCells.every(c => c.begin_time === firstBegin && c.end_time === firstEnd)
batchSameTimeSlot.value = allSameTime
if (allSameTime) {
//
const deadlineCount = {}
selectedCells.forEach(c => {
const v = c.end_reservation_time
if (v !== null && v !== undefined) {
deadlineCount[v] = (deadlineCount[v] || 0) + 1
}
})
let bestDeadline = selectedCells[0].end_reservation_time
let maxFreq = 0
for (const [v, freq] of Object.entries(deadlineCount)) {
if (freq > maxFreq) {
maxFreq = freq
bestDeadline = v
}
}
batchTimeInfo.value = {
begin_time: firstBegin,
end_time: firstEnd,
end_reservation_time: bestDeadline
}
} else {
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
} else {
batchSameTimeSlot.value = false
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
batchProgress.value = 0
batchCurrent.value = 0
batchTotal.value = selectedPlanArr.value.length
@ -996,12 +1067,16 @@
appointment_type_id: item.appointment_type_id,
count: Number(item.count) || 0
}))
const batchParams = {
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo
}
if (batchSameTimeSlot.value) {
batchParams.end_reservation_time = batchTimeInfo.value.end_reservation_time
}
try {
const res = await PlanListBatchChangeCount({
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo
})
const res = await PlanListBatchChangeCount(batchParams)
batchModifyRunning.value = false
if (res && res.status) {
BatchModifyDialogVisible.value = false
@ -1049,8 +1124,10 @@
// planTableData count - used_count
const selectedIds = new Set(selectedPlanArr.value)
const channelRemaining = {} // { [appointment_type_id]: number[] }
const channelLocked = {} // { [appointment_type_id]: number[] }
batchChannels.forEach(ch => {
channelRemaining[ch.id] = []
channelLocked[ch.id] = []
})
planTableData.value.forEach(row => {
for (const key in row) {
@ -1060,6 +1137,7 @@
cell.countsInfo.forEach(ci => {
if (channelRemaining[ci.appointment_type_id]) {
channelRemaining[ci.appointment_type_id].push(ci.count - ci.used_count)
channelLocked[ci.appointment_type_id].push(Number(ci.locked_count) || 0)
}
})
}
@ -1080,6 +1158,19 @@
}
})
batchOccupyLimits.value = limits
// maxValue>0
visibleBatchOccupyChannelIds.value = new Set(
batchChannels
.filter(ch => {
if (ch.id === 1) return true
if (limits[ch.id]?.maxValue > 0) return true
//
const maxLocked = Math.max(...(channelLocked[ch.id] || [0]))
if (maxLocked > 0) return true
return false
})
.map(ch => ch.id)
)
batchOccupyRunning.value = false
BatchOccupyDialogVisible.value = true
}
@ -1142,6 +1233,7 @@
}
//
let ZhanWeiDialogVisible = ref(false)
let visibleZhanWeiChannelIds = ref(new Set())
let ZhanWeiInfo = ref(null)
const OpenZhanWeiDialog = (row) => {
ZhanWeiDialogVisible.value = true
@ -1157,6 +1249,12 @@
item.locked_count = 0
}
})
// id=1 count>0 locked_count>0
visibleZhanWeiChannelIds.value = new Set(
ZhanWeiInfo.value.coutsInfo
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0 || Number(item.locked_count) > 0)
.map(item => item.appointment_type_id || item.id)
)
} else {
ElMessage.error(res.msg)
}
@ -1206,6 +1304,17 @@
return total + (Number(item.locked_count) || 0)
}, 0)
}
const getTotalUsed = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return 0
return countsInfo.reduce((total, item) => {
return total + (Number(item.used_count) || 0)
}, 0)
}
//
const hasOtherChannelCount = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return false
return countsInfo.some(ci => ci.appointment_type_id !== 1 && (Number(ci.count) > 0 || Number(ci.locked_count) > 0))
}
function formatDateLocal(date) {
const year = date.getFullYear();
@ -1418,7 +1527,43 @@
margin-left: 6px;
}
&.qudao_count_row_simple {
flex-direction: column;
align-items: center;
gap: 4px;
.card_total {
display: block;
width: 100%;
background: #409eff;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
text-align: center;
}
.card_locked {
display: inline-block;
background: #e6a23c;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
.font_color {
display: inline-block;
background: #67c23a;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
}
}
}
.planInfo {
@ -1435,7 +1580,7 @@
td {
border: 1px solid #f1f1f1;
// padding: 6px;
padding: 8px 6px;
}
td:first-child,
th:first-child {

@ -73,7 +73,7 @@
</div>
</div>
</td>
<td style="min-width: 120px;font-size: 14px;" v-for="(item,index) in date_list">{{item.substring(5,10)}} {{getWeekday(item)}}</td>
<td style="min-width: 150px;font-size: 14px;" v-for="(item,index) in date_list">{{item.substring(5,10)}} {{getWeekday(item)}}</td>
</tr>
<tr v-for="(item,index) in planTableData" :key="index">
<td v-for="(item2,index2) in item" :key="index2"
@ -110,14 +110,29 @@
@click="checkBoxCheckFunc(item2.id)">
<el-icon v-if="isSelected(item2.id)" color="#ffffff"><Select /></el-icon>
</div>
<div class="zong_row"><div class="qudao_title_zong"><span>总数:</span>{{item2.countsInfo[0].max_total}}</div></div>
<div class="qudao_count_row">
<template v-for="(item3,index3) in item2.countsInfo" :key="index3">
<div v-if="item3 && !(item3.count===0 && item3.used_count===0)">
<span> {{item3.jiancheng}}</span><span><span :class="{'yellow bold-text': item3.locked_count > 0}">{{ item3.locked_count != null ? item3.locked_count : 0 }}</span><span>/</span><span class="font_color">{{item3.used_count}}</span>/{{item3.count}} </span>
<!-- 模式A只有医生渠道有数量 -->
<template v-if="!hasOtherChannelCount(item2.countsInfo)">
<div class="qudao_count_row qudao_count_row_simple">
<div style="display: flex; gap: 12px; justify-content: center;">
<span class="card_locked"> {{getTotalLocked(item2.countsInfo)}}</span>
<span class="font_color"> {{getTotalUsed(item2.countsInfo)}}</span>
</div>
</template>
</div>
<div style="display: flex; justify-content: center; width: 100%; margin-top: 4px;">
<span class="card_total"> {{item2.countsInfo[0].max_total}}</span>
</div>
</div>
</template>
<!-- 模式B多渠道有数量 -->
<template v-else>
<div class="zong_row"><div class="qudao_title_zong"><span>总数:</span>{{item2.countsInfo[0].max_total}}</div></div>
<div class="qudao_count_row">
<template v-for="(item3,index3) in item2.countsInfo" :key="index3">
<div v-if="item3 && !(item3.count===0 && item3.used_count===0 && item3.locked_count===0)">
<span> {{item3.jiancheng}}</span><span><span :class="{'yellow bold-text': item3.locked_count > 0}">{{ item3.locked_count != null ? item3.locked_count : 0 }}</span><span>/</span><span class="font_color">{{item3.used_count}}</span>/{{item3.count}} </span>
</div>
</template>
</div>
</template>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
@ -170,25 +185,20 @@
}} </span> 结束时间<span
style="font-weight: 700;display: inline-block;margin-right: 8px">{{ PlanDetaiInfo.end_time }}
</span>
停止预约时间<span style="font-weight: 700">{{ PlanDetaiInfo.end_reservation_time }}</span>
停止预约时间<el-input v-model="PlanDetaiInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px; display: inline-block;" />
</el-form-item>
<el-form-item label="渠道名额:" v-if="PlanDetaiInfo.coutsInfo">
<div style="margin-right: 16px">
<div>当日总量</div>
<div class="qudao_k_input">
<el-input @input="MaxCountChange" type="number" v-model="PlanDetaiInfo.max_total"
:min="1" placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
</div>
<div style="font-size: 12px;color: #999">设置渠道比例可自动分配</div>
</div>
<el-form-item label="号源数量:" v-if="PlanDetaiInfo.coutsInfo">
<div>
<div class="qudao_k" v-for="(item,index) in PlanDetaiInfo.coutsInfo" :key="index">
<div style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input">
<el-input type="number" v-model="PlanDetaiInfo.coutsInfo[index].count" :min="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
<template v-for="(item,index) in PlanDetaiInfo.coutsInfo" :key="index">
<div class="qudao_k"
v-if="visibleChannelIds.has(item.appointment_type_id || item.id)">
<div v-if="visibleChannelIds.size > 1" style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input">
<el-input type="number" v-model="PlanDetaiInfo.coutsInfo[index].count" :min="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
</div>
</div>
</div>
</template>
</div>
</el-form-item>
<el-form-item label="状态:">
@ -269,9 +279,9 @@
<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">
<template v-if="ZhanWeiInfo.coutsInfo && ZhanWeiInfo.coutsInfo.length > 0">
<template v-for="(item,index) in ZhanWeiInfo.coutsInfo" :key="index">
<div v-if="item && !(item.count===0 && item.used_count===0)"
<div v-if="item && !(item.count===0 && item.used_count===0 && item.locked_count===0)"
style="display: flex; align-items: center; gap: 10px;">
<div style="width: 80px;">{{ item.name }}</div>
<div v-if="visibleZhanWeiChannelIds.size > 1" style="width: 80px;">{{ item.name }}</div>
<div style="flex: 1;">
<el-input type="number" v-model="ZhanWeiInfo.coutsInfo[index].locked_count" placeholder="占位数量" min="0"
oninput="value=value.replace(/[^0-9]/g,'')" />
@ -313,22 +323,27 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">数量</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')" />
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">数量: {{ batchTotalCount }}</el-col>
</el-row>
<el-form-item label="号源数量:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="ch.id === 1 || visibleBatchChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
</template>
</div>
</el-form-item>
</el-form>
<div v-if="batchSameTimeSlot" style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">时间段设置</div>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<div style="display: flex; align-items: center;">
<div style="width: 90px">停止预约时间:</div>
<el-input v-model="batchTimeInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px;" />
</div>
</div>
</div>
</div>
<template #footer>
<el-button @click="BatchModifyDialogVisible = false" :disabled="batchModifyRunning">取消</el-button>
@ -340,28 +355,21 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">占用数量</el-col>
<el-col :span="8">提示</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
</el-col>
<el-col :span="8" style="line-height: 32px; font-size: 12px; color: #999;">
<template v-if="batchOccupyLimits[ch.id]?.maxValue !== null">
最大可占: {{ batchOccupyLimits[ch.id].maxValue }}
</template>
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">占用: {{ batchOccupyTotalLocked }}</el-col>
</el-row>
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="visibleBatchOccupyChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchOccupyChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
<span style="color: #999; font-size: 12px;">
最大可占: {{ batchOccupyLimits[ch.id]?.maxValue }}
</span>
</div>
</template>
</div>
</el-form-item>
<el-form-item label="占位备注:" style="margin-top: 10px;">
<el-input
type="textarea"
@ -453,6 +461,7 @@
dateRange: []
})
let PlanDetailDialogVisible = ref(false)
let visibleChannelIds = ref(new Set())
const GetList = () => {
searchInfo.value.resources_id = ResourceActive.value
date_list.value = getAllDatesBetweenDates(searchInfo.value.dateRange)
@ -501,8 +510,10 @@
patient_type_label: matchingPlan.patient_type_label,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id: matchingPlan.resources_id
resources_id: matchingPlan.resources_id,
begin_time: matchingPlan.begin_time,
end_time: matchingPlan.end_time,
end_reservation_time: matchingPlan.end_reservation_time
};
}else{
row[date] = {
@ -760,6 +771,12 @@
loading.value = false
if (res.status) {
PlanDetaiInfo.value = res.data
// id=1 count>0 locked_count>0
visibleChannelIds.value = new Set(
PlanDetaiInfo.value.coutsInfo
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0 || Number(item.locked_count) > 0)
.map(item => item.appointment_type_id || item.id)
)
} else {
ElMessage.error(res.msg)
}
@ -796,10 +813,7 @@
PlanDetaiInfo.value.coutsInfo.forEach((item) => {
tempCount = tempCount + Number(item.count)
})
if (tempCount !== Number(PlanDetaiInfo.value.max_total)) {
ElMessage.error('各个渠道数量之和与当日总量不符')
return false
}
PlanDetaiInfo.value.max_total = tempCount
loading.value = true
PlanDetailChangeInfoAdmin({
PlanDetaiInfo: PlanDetaiInfo.value,
@ -808,6 +822,7 @@
loading.value = false
if (res.status) {
PlanDetailDialogVisible.value = false
ElMessage.success('保存成功')
GetList()
} else {
ElMessage.error(res.msg)
@ -925,6 +940,10 @@
{ name: '自助机', id: 3 }
]
let batchForm = ref([])
let batchSameTimeSlot = ref(false)
let batchTimeInfo = ref({ begin_time: '', end_time: '', end_reservation_time: '' })
let visibleBatchChannelIds = ref(new Set())
let visibleBatchOccupyChannelIds = ref(new Set())
const initBatchForm = () => {
batchForm.value = batchChannels.map(ch => ({
appointment_type_id: ch.id,
@ -941,22 +960,27 @@
return
}
initBatchForm()
// planTableData count
// planTableData count locked_count
const selectedIds = new Set(selectedPlanArr.value)
const channelValues = {}
batchChannels.forEach(ch => {
channelValues[ch.id] = { count: [] }
channelValues[ch.id] = { count: [], locked_count: [] }
})
const selectedCells = []
planTableData.value.forEach(row => {
for (const key in row) {
if (key === 'time_range') continue
const cell = row[key]
if (cell && cell.id && selectedIds.has(cell.id) && cell.countsInfo) {
cell.countsInfo.forEach(ci => {
if (channelValues[ci.appointment_type_id]) {
channelValues[ci.appointment_type_id].count.push(ci.count)
}
})
if (cell && cell.id && selectedIds.has(cell.id)) {
selectedCells.push(cell)
if (cell.countsInfo) {
cell.countsInfo.forEach(ci => {
if (channelValues[ci.appointment_type_id]) {
channelValues[ci.appointment_type_id].count.push(ci.count)
channelValues[ci.appointment_type_id].locked_count.push(Number(ci.locked_count) || 0)
}
})
}
}
}
})
@ -969,6 +993,53 @@
count: vals.count.length > 0 && allSame(vals.count) ? vals.count[0] : ''
}
})
// count>0 locked_count>0
visibleBatchChannelIds.value = new Set(
batchChannels
.filter(ch => {
if (ch.id === 1) return true
const vals = channelValues[ch.id]
if (vals.count.some(v => v > 0)) return true
if (vals.locked_count.some(v => v > 0)) return true
return false
})
.map(ch => ch.id)
)
//
if (selectedCells.length > 0) {
const firstBegin = selectedCells[0].begin_time
const firstEnd = selectedCells[0].end_time
const allSameTime = selectedCells.every(c => c.begin_time === firstBegin && c.end_time === firstEnd)
batchSameTimeSlot.value = allSameTime
if (allSameTime) {
//
const deadlineCount = {}
selectedCells.forEach(c => {
const v = c.end_reservation_time
if (v !== null && v !== undefined) {
deadlineCount[v] = (deadlineCount[v] || 0) + 1
}
})
let bestDeadline = selectedCells[0].end_reservation_time
let maxFreq = 0
for (const [v, freq] of Object.entries(deadlineCount)) {
if (freq > maxFreq) {
maxFreq = freq
bestDeadline = v
}
}
batchTimeInfo.value = {
begin_time: firstBegin,
end_time: firstEnd,
end_reservation_time: bestDeadline
}
} else {
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
} else {
batchSameTimeSlot.value = false
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
batchProgress.value = 0
batchCurrent.value = 0
batchTotal.value = selectedPlanArr.value.length
@ -1010,13 +1081,17 @@
appointment_type_id: item.appointment_type_id,
count: Number(item.count) || 0
}))
const batchParams = {
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
department_id: searchInfo.value.department_id
}
if (batchSameTimeSlot.value) {
batchParams.end_reservation_time = batchTimeInfo.value.end_reservation_time
}
try {
const res = await PlanListBatchChangeCount({
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
department_id: searchInfo.value.department_id
})
const res = await PlanListBatchChangeCount(batchParams)
batchModifyRunning.value = false
if (res && res.status) {
BatchModifyDialogVisible.value = false
@ -1064,8 +1139,10 @@
// planTableData count - used_count
const selectedIds = new Set(selectedPlanArr.value)
const channelRemaining = {} // { [appointment_type_id]: number[] }
const channelLocked = {} // { [appointment_type_id]: number[] }
batchChannels.forEach(ch => {
channelRemaining[ch.id] = []
channelLocked[ch.id] = []
})
planTableData.value.forEach(row => {
for (const key in row) {
@ -1075,6 +1152,7 @@
cell.countsInfo.forEach(ci => {
if (channelRemaining[ci.appointment_type_id]) {
channelRemaining[ci.appointment_type_id].push(ci.count - ci.used_count)
channelLocked[ci.appointment_type_id].push(Number(ci.locked_count) || 0)
}
})
}
@ -1095,6 +1173,19 @@
}
})
batchOccupyLimits.value = limits
// maxValue>0
visibleBatchOccupyChannelIds.value = new Set(
batchChannels
.filter(ch => {
if (ch.id === 1) return true
if (limits[ch.id]?.maxValue > 0) return true
//
const maxLocked = Math.max(...(channelLocked[ch.id] || [0]))
if (maxLocked > 0) return true
return false
})
.map(ch => ch.id)
)
batchOccupyRunning.value = false
BatchOccupyDialogVisible.value = true
}
@ -1158,6 +1249,7 @@
}
//
let ZhanWeiDialogVisible = ref(false)
let visibleZhanWeiChannelIds = ref(new Set())
let ZhanWeiInfo = ref(null)
const OpenZhanWeiDialog = (row) => {
ZhanWeiDialogVisible.value = true
@ -1173,6 +1265,12 @@
item.locked_count = 0
}
})
// id=1 count>0 locked_count>0
visibleZhanWeiChannelIds.value = new Set(
ZhanWeiInfo.value.coutsInfo
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0 || Number(item.locked_count) > 0)
.map(item => item.appointment_type_id || item.id)
)
} else {
ElMessage.error(res.msg)
}
@ -1222,6 +1320,17 @@
return total + (Number(item.locked_count) || 0)
}, 0)
}
const getTotalUsed = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return 0
return countsInfo.reduce((total, item) => {
return total + (Number(item.used_count) || 0)
}, 0)
}
//
const hasOtherChannelCount = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return false
return countsInfo.some(ci => ci.appointment_type_id !== 1 && (Number(ci.count) > 0 || Number(ci.locked_count) > 0))
}
function formatDateLocal(date) {
const year = date.getFullYear();
@ -1434,7 +1543,43 @@
margin-left: 6px;
}
&.qudao_count_row_simple {
flex-direction: column;
align-items: center;
gap: 4px;
.card_total {
display: block;
width: 100%;
background: #409eff;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
text-align: center;
}
.card_locked {
display: inline-block;
background: #e6a23c;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
.font_color {
display: inline-block;
background: #67c23a;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
}
}
}
.planInfo {
@ -1451,7 +1596,7 @@
td {
border: 1px solid #f1f1f1;
// padding: 6px;
padding: 8px 6px;
}
td:first-child,
th:first-child {

@ -105,21 +105,31 @@
<el-icon v-if="isSelected(item2.id)" color="#ffffff"><Select /></el-icon>
</div>
<div class="qudao_count_row">
<div class="qudao_title_zong"><span></span>{{item2.countsInfo[0].max_total}}
<!-- 模式A只有医生渠道有数量 -->
<template v-if="!hasOtherChannelCount(item2.countsInfo)">
<div class="qudao_count_row qudao_count_row_simple">
<span class="card_total"> {{item2.countsInfo[0].max_total}}</span>
<span v-if="getTotalLocked(item2.countsInfo) > 0" class="card_locked"> {{getTotalLocked(item2.countsInfo)}}</span>
</div>
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span>{{item3.count}} </span>
</template>
<!-- 模式B多渠道有数量 -->
<template v-else>
<div class="qudao_count_row">
<div class="qudao_title_zong"><span></span>{{item2.countsInfo[0].max_total}}
</div>
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span>{{item3.count}} </span>
</div>
</div>
</div>
<div v-if="getTotalLocked(item2.countsInfo) > 0" class="locked_count_row">
:{{getTotalLocked(item2.countsInfo)}}
</div>
</template>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
</div>
</div>
<div v-if="getTotalLocked(item2.countsInfo) > 0" class="locked_count_row">
:{{getTotalLocked(item2.countsInfo)}}
</div>
</div>
</td>
</tr>
@ -187,32 +197,18 @@
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="渠道名额">
<el-form-item label="号源数量">
<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 v-if="CountType==1" style="width: 220px;" @input="MaxCountChange" type="number"
v-model="PlanInfo.max_total" :min="0" placeholder="0"
oninput="value=value.replace(/[^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>
<div>
<div class="qudao_k" v-for="(item,index) in PlanInfo.qudao_total" :key="index">
<div style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input" style="display: flex;">
<el-input type="number" v-model="PlanInfo.qudao_total[index].count" :min="0"
placeholder="0" oninput="value=value.replace(/[^0-9]/g, '')" />
<div style="margin-left: 4px; color: #ccc;">{{item.ratio}}%</div>
</div>
<template v-for="(item,index) in PlanInfo.qudao_total" :key="index">
<div class="qudao_k" v-if="visibleChannelIds.has(item.id || item.appointment_type_id)">
<div v-if="visibleChannelIds.size > 1" style="width: 60px">{{ item.name }}</div>
<div class="qudao_k_input" style="display: flex;">
<el-input type="number" v-model="PlanInfo.qudao_total[index].count" :min="0"
placeholder="0" oninput="value=value.replace(/[^0-9]/g, '')" />
</div>
</div>
</template>
</div>
</div>
</el-form-item>
@ -228,13 +224,13 @@
<div style="display:flex;">
<div style="width: 70px">开始时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.begin_time" placeholder="开始时间" disabled />
<el-input v-model="PlanInfo.begin_time" placeholder="开始时间" />
</div>
</div>
<div style="display:flex;">
<div style="width: 70px">结束时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.end_time" placeholder="结束时间" disabled />
<el-input v-model="PlanInfo.end_time" placeholder="结束时间" />
</div>
</div>
</div>
@ -242,13 +238,7 @@
<div style="display:flex;">
<div style="width: 90px">停止预约时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.end_reservation_time" placeholder="停止预约时间" disabled />
</div>
</div>
<div style="display:flex;">
<div style="width: 90px">可用时间长度:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.time_unit" placeholder="可用时间长度" disabled />
<el-input v-model="PlanInfo.end_reservation_time" placeholder="停止预约时间" />
</div>
</div>
</div>
@ -356,17 +346,16 @@
<el-form-item label="星期:">
{{ ZhanWeiInfo.weekname }}
</el-form-item>
<el-form-item label="渠道占位:">
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">
<template v-if="ZhanWeiInfo.qudao_total && ZhanWeiInfo.qudao_total.length > 0">
<template v-for="(item,index) in ZhanWeiInfo.qudao_total" :key="index">
<div v-if="item && !(item.count===0)"
<div v-if="visibleZhanWeiChannelIds.has(item.appointment_type_id || item.id)"
style="display: flex; align-items: center; gap: 10px;">
<div style="width: 80px;">{{ item.name }}</div>
<div style="flex: 1;">
<el-input type="number" v-model="ZhanWeiInfo.qudao_total[index].locked_count" placeholder="占位数量" min="0"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
<div v-if="visibleZhanWeiChannelIds.size > 1" style="width: 80px;">{{ item.name }}</div>
<el-input type="number" v-model="ZhanWeiInfo.qudao_total[index].locked_count" placeholder="占位数量" min="0"
style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
<div style="color: #999; font-size: 12px;">
可用: {{ item.count }}
</div>
@ -394,22 +383,35 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">数量</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')" />
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">数量: {{ batchTotalCount }}</el-col>
</el-row>
<el-form-item label="号源数量:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="visibleBatchChannelIds.has(ch.id || ch.appointment_type_id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
</template>
</div>
</el-form-item>
</el-form>
<div v-if="batchSameTimeSlot" style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">时间段设置</div>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<div style="display: flex; align-items: center;">
<div style="width: 70px">开始时间:</div>
<el-input v-model="batchTimeInfo.begin_time" placeholder="开始时间" style="width: 120px;" />
</div>
<div style="display: flex; align-items: center;">
<div style="width: 70px">结束时间:</div>
<el-input v-model="batchTimeInfo.end_time" placeholder="结束时间" style="width: 120px;" />
</div>
<div style="display: flex; align-items: center;">
<div style="width: 90px">停止预约时间:</div>
<el-input v-model="batchTimeInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px;" />
</div>
</div>
</div>
<div style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">病人类型</div>
<el-checkbox-group v-model="batchPatientType">
@ -430,28 +432,21 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">占用数量</el-col>
<el-col :span="8">提示</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchOccupyChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
</el-col>
<el-col :span="8" style="line-height: 32px; font-size: 12px; color: #999;">
<template v-if="batchOccupyLimits[ch.id]?.maxValue !== null">
最大可占: {{ batchOccupyLimits[ch.id].maxValue }}
</template>
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">占用: {{ batchOccupyTotalLocked }}</el-col>
</el-row>
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchOccupyChannels" :key="ci">
<div v-if="visibleBatchOccupyChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchOccupyChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
<span style="color: #999; font-size: 12px;">
最大可占: {{ batchOccupyLimits[ch.id]?.maxValue }}
</span>
</div>
</template>
</div>
</el-form-item>
</el-form>
</div>
<template #footer>
@ -494,7 +489,6 @@
ElMessageBox
} from 'element-plus'
let CountType = ref("1"); //
let loading = ref(false)
let currentPage = ref(1) //
let pageSize = ref(15) //
@ -666,10 +660,12 @@
let batchModifyRunning = ref(false)
let batchChannels = ref([])
let batchForm = ref([])
let visibleBatchChannelIds = ref(new Set())
let visibleZhanWeiChannelIds = ref(new Set())
let visibleBatchOccupyChannelIds = ref(new Set())
let batchSameTimeSlot = ref(false)
let batchTimeInfo = ref({ begin_time: '', end_time: '', end_reservation_time: '' })
let batchPatientType = ref([])
const batchTotalCount = computed(() => {
return batchForm.value.reduce((s, item) => s + (Number(item.count) || 0), 0)
})
//
let BatchOccupyDialogVisible = ref(false)
let batchOccupyRunning = ref(false)
@ -773,14 +769,16 @@
channelMap.set(ci.appointment_type_id, {
name: ci.name,
jiancheng: ci.jiancheng,
counts: []
counts: [],
locked_counts: []
})
}
channelMap.get(ci.appointment_type_id).counts.push(ci.count)
channelMap.get(ci.appointment_type_id).locked_counts.push(Number(ci.locked_count) || 0)
})
//
if (cell.patient_type) {
patientTypeSets.push(new Set(cell.patient_type))
patientTypeSets.push(new Set(cell.patient_type.split(',').filter(v => v !== '')))
}
}
}
@ -796,6 +794,19 @@
count: allSame ? info.counts[0] : ''
})
}
// id=1 count>0
visibleBatchChannelIds.value = new Set(
batchForm.value
.filter((item, ci) => {
const ch = batchChannels.value[ci]
const chId = ch.id || ch.appointment_type_id
return chId === 1 || Number(item.count) > 0 || channelMap.get(chId)?.locked_counts?.some(v => v > 0)
})
.map((item, ci) => {
const ch = batchChannels.value[ci]
return ch.id || ch.appointment_type_id
})
)
//
if (patientTypeSets.length > 0) {
const commonTypes = patientTypeSets.reduce((acc, set) => {
@ -811,6 +822,51 @@
}
batchModifyRunning.value = false
BatchModifyDialogVisible.value = true
// selectedIds
const selectedCells = []
planTableData.value.forEach(row => {
for (const key in row) {
if (key === 'time_range') continue
const cell = row[key]
if (cell && cell.id && selectedIds.has(cell.id)) {
selectedCells.push(cell)
}
}
})
if (selectedCells.length > 0) {
const firstBegin = selectedCells[0].begin_time
const firstEnd = selectedCells[0].end_time
const allSameTime = selectedCells.every(c => c.begin_time === firstBegin && c.end_time === firstEnd)
batchSameTimeSlot.value = allSameTime
if (allSameTime) {
//
const deadlineCount = {}
selectedCells.forEach(c => {
const v = c.end_reservation_time
if (v !== null && v !== undefined) {
deadlineCount[v] = (deadlineCount[v] || 0) + 1
}
})
let bestDeadline = selectedCells[0].end_reservation_time
let maxFreq = 0
for (const [v, freq] of Object.entries(deadlineCount)) {
if (freq > maxFreq) {
maxFreq = freq
bestDeadline = v
}
}
batchTimeInfo.value = {
begin_time: firstBegin,
end_time: firstEnd,
end_reservation_time: bestDeadline
}
} else {
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
} else {
batchSameTimeSlot.value = false
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
}
const execBatchModify = async () => {
//
@ -820,20 +876,26 @@
return
}
}
const maxTotal = batchTotalCount.value
const maxTotal = batchForm.value.reduce((s, item) => s + (Number(item.count) || 0), 0)
batchModifyRunning.value = true
const ids = [...selectedPlanArr.value]
const coutsInfo = batchForm.value.map(item => ({
appointment_type_id: item.appointment_type_id,
count: Number(item.count) || 0
}))
const batchParams = {
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
patientType: batchPatientType.value
}
if (batchSameTimeSlot.value) {
batchParams.begin_time = batchTimeInfo.value.begin_time
batchParams.end_time = batchTimeInfo.value.end_time
batchParams.end_reservation_time = batchTimeInfo.value.end_reservation_time
}
try {
const res = await PlanModelBatchChange({
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
patientType: batchPatientType.value
})
const res = await PlanModelBatchChange(batchParams)
batchModifyRunning.value = false
if (res && res.status) {
BatchModifyDialogVisible.value = false
@ -947,9 +1009,13 @@
row[xingqi.label] = {
countsInfo: matchingPlan.countsInfo,
patient_type_label: matchingPlan.patient_type_label,
patient_type: matchingPlan.patient_type,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id:matchingPlan.resources_id
resources_id: matchingPlan.resources_id,
begin_time: matchingPlan.begin_time,
end_time: matchingPlan.end_time,
end_reservation_time: matchingPlan.end_reservation_time
};
}else{
@ -1008,7 +1074,6 @@
begin_time: '',
end_time: '',
end_reservation_time: '',
time_unit: 0, //
resources_id: null,
devices: [],
patientType: [],
@ -1016,6 +1081,7 @@
}
}
let PlanInfo = ref(DataDefault())
let visibleChannelIds = ref(new Set())
let selectedResourceTimeMode = ref(0) // 0-1-
const Add = (row = null) => {
@ -1061,15 +1127,12 @@
GetList()
}
const Save = () => {
//
// max_total count
let tempCount = 0
PlanInfo.value.qudao_total.forEach((item) => {
tempCount = tempCount + Number(item.count)
})
if (tempCount !== Number(PlanInfo.value.max_total)) {
ElMessage.error('各个渠道数量之和与当日总量不符')
return false
}
PlanInfo.value.max_total = tempCount
ElMessageBox.confirm(
'确定保存吗?',
@ -1159,10 +1222,12 @@
if (!channelMap.has(ci.appointment_type_id)) {
channelMap.set(ci.appointment_type_id, {
name: ci.name,
counts: []
counts: [],
locked_counts: []
})
}
channelMap.get(ci.appointment_type_id).counts.push(ci.count)
channelMap.get(ci.appointment_type_id).locked_counts.push(Number(ci.locked_count) || 0)
})
}
}
@ -1177,6 +1242,22 @@
}
batchOccupyLimits.value = limits
initBatchOccupyForm()
// id=1 maxValue>0
visibleBatchOccupyChannelIds.value = new Set(
batchOccupyChannels.value
.filter(ch => {
if (ch.id === 1) return true
if (batchOccupyLimits.value[ch.id]?.maxValue > 0) return true
//
const ci = batchOccupyChannels.value.findIndex(c => c.id === ch.id)
if (ci >= 0) {
const maxLocked = Math.max(...channelMap.get(ch.id)?.locked_counts || [0])
if (maxLocked > 0) return true
}
return false
})
.map(ch => ch.id)
)
batchOccupyRunning.value = false
BatchOccupyDialogVisible.value = true
}
@ -1249,7 +1330,12 @@
PlanInfo.value.qudao_total.forEach((v, i) => {
PlanInfo.value.qudao_total[i].count = 0
})
// console.log(PlanInfo.value)
//
visibleChannelIds.value = new Set(
PlanInfo.value.qudao_total
.filter(item => item.id === 1 || item.appointment_type_id === 1)
.map(item => item.id || item.appointment_type_id)
)
} else {
ElMessage.error(res.msg)
}
@ -1354,6 +1440,12 @@
PlanInfo.value.max_total = res.data.qudao_total[0].max_total
PlanInfo.value.xingqi = [res.data.weekname]
PlanInfo.value.devices = res.data.devices
// id=1 count>0
visibleChannelIds.value = new Set(
PlanInfo.value.qudao_total
.filter(item => item.id === 1 || item.appointment_type_id === 1 || Number(item.count) > 0)
.map(item => item.id || item.appointment_type_id)
)
//
const selectedResource = enableResourceList.value.find(r => r.id === PlanInfo.value.resources_id);
selectedResourceTimeMode.value = selectedResource ? (selectedResource.time_mode || 0) : 0;
@ -1458,15 +1550,6 @@
}
}
//
const CountTypeChange = (e) => {
CountType.value = e
MaxCountChange(0)
TimeLongChange(0)
if (e == 2) {
}
}
const handleSelectionChange = (e) => {
selectedPlanArr.value=[]
e.forEach((v,i)=>{
@ -1476,42 +1559,6 @@
console.log(selectedPlanArr.value)
}
//
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;
}
//
const getTotalLocked = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return 0
@ -1519,6 +1566,11 @@
return total + (Number(item.locked_count) || 0)
}, 0)
}
//
const hasOtherChannelCount = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return false
return countsInfo.some(ci => ci.appointment_type_id !== 1 && (Number(ci.count) > 0 || Number(ci.locked_count) > 0))
}
// -
const OpenZhanWeiDialog = (row) => {
ZhanWeiDialogVisible.value = true
@ -1542,6 +1594,12 @@
item.locked_count = 0
}
})
// id=1 count>0
visibleZhanWeiChannelIds.value = new Set(
ZhanWeiInfo.value.qudao_total
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0 || Number(item.locked_count) > 0)
.map(item => item.appointment_type_id || item.id)
)
}
} else {
ElMessage.error(res.msg)
@ -1726,6 +1784,31 @@
margin-left: 6px;
}
.card_total {
display: inline-block;
background: #409eff;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
.card_locked {
display: inline-block;
background: #e6a23c;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
&.qudao_count_row_simple {
justify-content: center;
gap: 12px;
}
.qudao_title_zong {
font-weight: 700;

@ -105,21 +105,31 @@
<el-icon v-if="isSelected(item2.id)" color="#ffffff"><Select /></el-icon>
</div>
<div class="qudao_count_row">
<div class="qudao_title_zong"><span></span>{{item2.countsInfo[0].max_total}}
<!-- 模式A只有医生渠道有数量 -->
<template v-if="!hasOtherChannelCount(item2.countsInfo)">
<div class="qudao_count_row qudao_count_row_simple">
<span class="card_total"> {{item2.countsInfo[0].max_total}}</span>
<span v-if="getTotalLocked(item2.countsInfo) > 0" class="card_locked"> {{getTotalLocked(item2.countsInfo)}}</span>
</div>
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span>{{item3.count}} </span>
</template>
<!-- 模式B多渠道有数量 -->
<template v-else>
<div class="qudao_count_row">
<div class="qudao_title_zong"><span></span>{{item2.countsInfo[0].max_total}}
</div>
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span>{{item3.count}} </span>
</div>
</div>
</div>
<div v-if="getTotalLocked(item2.countsInfo) > 0" class="locked_count_row">
:{{getTotalLocked(item2.countsInfo)}}
</div>
</template>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
</div>
</div>
<div v-if="getTotalLocked(item2.countsInfo) > 0" class="locked_count_row">
:{{getTotalLocked(item2.countsInfo)}}
</div>
</div>
</td>
</tr>
@ -187,32 +197,18 @@
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="渠道名额">
<el-form-item label="号源数量">
<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 v-if="CountType==1" style="width: 220px;" @input="MaxCountChange" type="number"
v-model="PlanInfo.max_total" :min="0" placeholder="0"
oninput="value=value.replace(/[^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>
<div>
<div class="qudao_k" v-for="(item,index) in PlanInfo.qudao_total" :key="index">
<div style="width: 50px">{{ item.name }}</div>
<div class="qudao_k_input" style="display: flex;">
<el-input type="number" v-model="PlanInfo.qudao_total[index].count" :min="0"
placeholder="0" oninput="value=value.replace(/[^0-9]/g, '')" />
<div style="margin-left: 4px; color: #ccc;">{{item.ratio}}%</div>
</div>
<template v-for="(item,index) in PlanInfo.qudao_total" :key="index">
<div class="qudao_k" v-if="visibleChannelIds.has(item.id || item.appointment_type_id)">
<div v-if="visibleChannelIds.size > 1" style="width: 60px">{{ item.name }}</div>
<div class="qudao_k_input" style="display: flex;">
<el-input type="number" v-model="PlanInfo.qudao_total[index].count" :min="0"
placeholder="0" oninput="value=value.replace(/[^0-9]/g, '')" />
</div>
</div>
</template>
</div>
</div>
</el-form-item>
@ -228,27 +224,21 @@
<div style="display:flex;">
<div style="width: 70px">开始时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.begin_time" placeholder="开始时间" disabled />
<el-input v-model="PlanInfo.begin_time" placeholder="开始时间" />
</div>
</div>
<div style="display:flex;">
<div style="width: 70px">结束时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.end_time" placeholder="结束时间" disabled />
<el-input v-model="PlanInfo.end_time" placeholder="结束时间" />
</div>
</div>
</div>
<div style="margin-left: 8px">
<div style="margin-left: 8px">
<div style="display:flex;">
<div style="width: 90px">停止预约时间:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.end_reservation_time" placeholder="停止预约时间" disabled />
</div>
</div>
<div style="display:flex;">
<div style="width: 90px">可用时间长度:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.time_unit" placeholder="可用时间长度" disabled />
<el-input v-model="PlanInfo.end_reservation_time" placeholder="停止预约时间" />
</div>
</div>
</div>
@ -356,17 +346,16 @@
<el-form-item label="星期:">
{{ ZhanWeiInfo.weekname }}
</el-form-item>
<el-form-item label="渠道占位:">
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px; width: 100%;">
<template v-if="ZhanWeiInfo.qudao_total && ZhanWeiInfo.qudao_total.length > 0">
<template v-for="(item,index) in ZhanWeiInfo.qudao_total" :key="index">
<div v-if="item && !(item.count===0)"
<div v-if="visibleZhanWeiChannelIds.has(item.appointment_type_id || item.id)"
style="display: flex; align-items: center; gap: 10px;">
<div style="width: 80px;">{{ item.name }}</div>
<div style="flex: 1;">
<el-input type="number" v-model="ZhanWeiInfo.qudao_total[index].locked_count" placeholder="占位数量" min="0"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
<div v-if="visibleZhanWeiChannelIds.size > 1" style="width: 80px;">{{ item.name }}</div>
<el-input type="number" v-model="ZhanWeiInfo.qudao_total[index].locked_count" placeholder="占位数量" min="0"
style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
<div style="color: #999; font-size: 12px;">
可用: {{ item.count }}
</div>
@ -394,22 +383,35 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">数量</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')" />
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">数量: {{ batchTotalCount }}</el-col>
</el-row>
<el-form-item label="号源数量:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchChannels" :key="ci">
<div v-if="visibleBatchChannelIds.has(ch.id || ch.appointment_type_id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchForm[ci].count" placeholder="数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')" />
</div>
</template>
</div>
</el-form-item>
</el-form>
<div v-if="batchSameTimeSlot" style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">时间段设置</div>
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
<div style="display: flex; align-items: center;">
<div style="width: 70px">开始时间:</div>
<el-input v-model="batchTimeInfo.begin_time" placeholder="开始时间" style="width: 120px;" />
</div>
<div style="display: flex; align-items: center;">
<div style="width: 70px">结束时间:</div>
<el-input v-model="batchTimeInfo.end_time" placeholder="结束时间" style="width: 120px;" />
</div>
<div style="display: flex; align-items: center;">
<div style="width: 90px">停止预约时间:</div>
<el-input v-model="batchTimeInfo.end_reservation_time" placeholder="停止预约时间" style="width: 120px;" />
</div>
</div>
</div>
<div style="margin-top: 16px; padding-top: 12px; border-top: 1px solid #eee;">
<div style="margin-bottom: 8px; font-weight: 600; color: #333; font-size: 13px;">病人类型</div>
<el-checkbox-group v-model="batchPatientType">
@ -430,28 +432,21 @@
<div>
<div style="margin-bottom: 16px; color: #666;">已选 {{ selectedPlanArr.length }} 条号源明细</div>
<el-form label-width="100px">
<el-row :gutter="10" style="margin-bottom: 6px; font-weight: 600; color: #333; font-size: 13px;">
<el-col :span="6">渠道名称</el-col>
<el-col :span="8">占用数量</el-col>
<el-col :span="8">提示</el-col>
</el-row>
<el-row v-for="(ch, ci) in batchOccupyChannels" :key="ci" :gutter="10" style="margin-bottom: 10px;">
<el-col :span="6" style="line-height: 32px;">{{ ch.name }}</el-col>
<el-col :span="8">
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
</el-col>
<el-col :span="8" style="line-height: 32px; font-size: 12px; color: #999;">
<template v-if="batchOccupyLimits[ch.id]?.maxValue !== null">
最大可占: {{ batchOccupyLimits[ch.id].maxValue }}
</template>
</el-col>
</el-row>
<el-row :gutter="10" style="border-top: 1px solid #eee; padding-top: 10px;">
<el-col :span="6" style="line-height: 32px; font-weight: 600;">合计</el-col>
<el-col :span="8" style="line-height: 32px; font-weight: 600;">占用: {{ batchOccupyTotalLocked }}</el-col>
</el-row>
<el-form-item label="号源占位:">
<div style="display: flex; flex-direction: column; gap: 10px;">
<template v-for="(ch, ci) in batchOccupyChannels" :key="ci">
<div v-if="visibleBatchOccupyChannelIds.has(ch.id)" style="display: flex; align-items: center; gap: 8px; margin-bottom: 10px;">
<span v-if="visibleBatchOccupyChannelIds.size > 1" style="width: 60px; color: #666;">{{ ch.name }}</span>
<el-input v-model.number="batchOccupyForm[ci].locked_count" placeholder="占用数量" size="default" style="width: 220px;"
oninput="value=value.replace(/[^0-9]/g,'')"
@input="onOccupyInput(ci, $event)" />
<span style="color: #999; font-size: 12px;">
最大可占: {{ batchOccupyLimits[ch.id]?.maxValue }}
</span>
</div>
</template>
</div>
</el-form-item>
</el-form>
</div>
<template #footer>
@ -494,7 +489,6 @@
ElMessageBox
} from 'element-plus'
let CountType = ref("1"); //
let loading = ref(false)
let currentPage = ref(1) //
let pageSize = ref(15) //
@ -666,10 +660,12 @@
let batchModifyRunning = ref(false)
let batchChannels = ref([])
let batchForm = ref([])
let visibleBatchChannelIds = ref(new Set())
let visibleZhanWeiChannelIds = ref(new Set())
let visibleBatchOccupyChannelIds = ref(new Set())
let batchSameTimeSlot = ref(false)
let batchTimeInfo = ref({ begin_time: '', end_time: '', end_reservation_time: '' })
let batchPatientType = ref([])
const batchTotalCount = computed(() => {
return batchForm.value.reduce((s, item) => s + (Number(item.count) || 0), 0)
})
//
let BatchOccupyDialogVisible = ref(false)
let batchOccupyRunning = ref(false)
@ -777,10 +773,11 @@
})
}
channelMap.get(ci.appointment_type_id).counts.push(ci.count)
channelMap.get(ci.appointment_type_id).locked_counts.push(Number(ci.locked_count) || 0)
})
//
if (cell.patient_type) {
patientTypeSets.push(new Set(cell.patient_type))
patientTypeSets.push(new Set(cell.patient_type.split(',').filter(v => v !== '')))
}
}
}
@ -796,6 +793,19 @@
count: allSame ? info.counts[0] : ''
})
}
// id=1 count>0
visibleBatchChannelIds.value = new Set(
batchForm.value
.filter((item, ci) => {
const ch = batchChannels.value[ci]
const chId = ch.id || ch.appointment_type_id
return chId === 1 || Number(item.count) > 0
})
.map((item, ci) => {
const ch = batchChannels.value[ci]
return ch.id || ch.appointment_type_id
})
)
//
if (patientTypeSets.length > 0) {
const commonTypes = patientTypeSets.reduce((acc, set) => {
@ -811,6 +821,51 @@
}
batchModifyRunning.value = false
BatchModifyDialogVisible.value = true
//
const selectedCells = []
planTableData.value.forEach(row => {
for (const key in row) {
if (key === 'time_range') continue
const cell = row[key]
if (cell && cell.id && selectedIds.has(cell.id)) {
selectedCells.push(cell)
}
}
})
if (selectedCells.length > 0) {
const firstBegin = selectedCells[0].begin_time
const firstEnd = selectedCells[0].end_time
const allSameTime = selectedCells.every(c => c.begin_time === firstBegin && c.end_time === firstEnd)
batchSameTimeSlot.value = allSameTime
if (allSameTime) {
//
const deadlineCount = {}
selectedCells.forEach(c => {
const v = c.end_reservation_time
if (v !== null && v !== undefined) {
deadlineCount[v] = (deadlineCount[v] || 0) + 1
}
})
let bestDeadline = firstBegin ? selectedCells[0].end_reservation_time : ''
let maxFreq = 0
for (const [v, freq] of Object.entries(deadlineCount)) {
if (freq > maxFreq) {
maxFreq = freq
bestDeadline = v
}
}
batchTimeInfo.value = {
begin_time: firstBegin,
end_time: firstEnd,
end_reservation_time: bestDeadline
}
} else {
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
} else {
batchSameTimeSlot.value = false
batchTimeInfo.value = { begin_time: '', end_time: '', end_reservation_time: '' }
}
}
const execBatchModify = async () => {
//
@ -820,20 +875,26 @@
return
}
}
const maxTotal = batchTotalCount.value
const maxTotal = batchForm.value.reduce((s, item) => s + (Number(item.count) || 0), 0)
batchModifyRunning.value = true
const ids = [...selectedPlanArr.value]
const coutsInfo = batchForm.value.map(item => ({
appointment_type_id: item.appointment_type_id,
count: Number(item.count) || 0
}))
const batchParams = {
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
patientType: batchPatientType.value
}
if (batchSameTimeSlot.value) {
batchParams.begin_time = batchTimeInfo.value.begin_time
batchParams.end_time = batchTimeInfo.value.end_time
batchParams.end_reservation_time = batchTimeInfo.value.end_reservation_time
}
try {
const res = await PlanModelBatchChangeAdmin({
ids: ids,
max_total: maxTotal,
coutsInfo: coutsInfo,
patientType: batchPatientType.value
})
const res = await PlanModelBatchChangeAdmin(batchParams)
batchModifyRunning.value = false
if (res && res.status) {
BatchModifyDialogVisible.value = false
@ -948,9 +1009,13 @@
row[xingqi.label] = {
countsInfo: matchingPlan.countsInfo,
patient_type_label: matchingPlan.patient_type_label,
patient_type: matchingPlan.patient_type,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id:matchingPlan.resources_id
resources_id: matchingPlan.resources_id,
begin_time: matchingPlan.begin_time,
end_time: matchingPlan.end_time,
end_reservation_time: matchingPlan.end_reservation_time
};
}else{
@ -1009,7 +1074,6 @@
begin_time: '',
end_time: '',
end_reservation_time: '',
time_unit: 0, //
resources_id: null,
devices: [],
patientType: [],
@ -1017,6 +1081,7 @@
}
}
let PlanInfo = ref(DataDefault())
let visibleChannelIds = ref(new Set())
let selectedResourceTimeMode = ref(0) // 0-1-
const Add = (row = null) => {
@ -1062,15 +1127,12 @@
GetList()
}
const Save = () => {
//
// max_total count
let tempCount = 0
PlanInfo.value.qudao_total.forEach((item) => {
tempCount = tempCount + Number(item.count)
})
if (tempCount !== Number(PlanInfo.value.max_total)) {
ElMessage.error('各个渠道数量之和与当日总量不符')
return false
}
PlanInfo.value.max_total = tempCount
ElMessageBox.confirm(
'确定保存吗?',
@ -1162,10 +1224,12 @@
if (!channelMap.has(ci.appointment_type_id)) {
channelMap.set(ci.appointment_type_id, {
name: ci.name,
counts: []
counts: [],
locked_counts: []
})
}
channelMap.get(ci.appointment_type_id).counts.push(ci.count)
channelMap.get(ci.appointment_type_id).locked_counts.push(Number(ci.locked_count) || 0)
})
}
}
@ -1180,6 +1244,22 @@
}
batchOccupyLimits.value = limits
initBatchOccupyForm()
// id=1 maxValue>0
visibleBatchOccupyChannelIds.value = new Set(
batchOccupyChannels.value
.filter(ch => {
if (ch.id === 1) return true
if (batchOccupyLimits.value[ch.id]?.maxValue > 0) return true
//
const ci = batchOccupyChannels.value.findIndex(c => c.id === ch.id)
if (ci >= 0) {
const maxLocked = Math.max(...channelMap.get(ch.id)?.locked_counts || [0])
if (maxLocked > 0) return true
}
return false
})
.map(ch => ch.id)
)
batchOccupyRunning.value = false
BatchOccupyDialogVisible.value = true
}
@ -1262,7 +1342,12 @@
PlanInfo.value.qudao_total.forEach((v, i) => {
PlanInfo.value.qudao_total[i].count = 0
})
// console.log(PlanInfo.value)
//
visibleChannelIds.value = new Set(
PlanInfo.value.qudao_total
.filter(item => item.id === 1 || item.appointment_type_id === 1)
.map(item => item.id || item.appointment_type_id)
)
} else {
ElMessage.error(res.msg)
}
@ -1368,6 +1453,12 @@
PlanInfo.value.max_total = res.data.qudao_total[0].max_total
PlanInfo.value.xingqi = [res.data.weekname]
PlanInfo.value.devices = res.data.devices
// id=1 count>0
visibleChannelIds.value = new Set(
PlanInfo.value.qudao_total
.filter(item => item.id === 1 || item.appointment_type_id === 1 || Number(item.count) > 0)
.map(item => item.id || item.appointment_type_id)
)
//
const selectedResource = enableResourceList.value.find(r => r.id === PlanInfo.value.resources_id);
selectedResourceTimeMode.value = selectedResource ? (selectedResource.time_mode || 0) : 0;
@ -1473,15 +1564,6 @@
}
}
//
const CountTypeChange = (e) => {
CountType.value = e
MaxCountChange(0)
TimeLongChange(0)
if (e == 2) {
}
}
const handleSelectionChange = (e) => {
selectedPlanArr.value=[]
e.forEach((v,i)=>{
@ -1491,42 +1573,6 @@
console.log(selectedPlanArr.value)
}
//
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;
}
//
const getTotalLocked = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return 0
@ -1534,6 +1580,11 @@
return total + (Number(item.locked_count) || 0)
}, 0)
}
//
const hasOtherChannelCount = (countsInfo) => {
if (!countsInfo || !Array.isArray(countsInfo)) return false
return countsInfo.some(ci => ci.appointment_type_id !== 1 && Number(ci.count) > 0)
}
// -
const OpenZhanWeiDialog = (row) => {
ZhanWeiDialogVisible.value = true
@ -1557,6 +1608,12 @@
item.locked_count = 0
}
})
// id=1 count>0
visibleZhanWeiChannelIds.value = new Set(
ZhanWeiInfo.value.qudao_total
.filter(item => item.appointment_type_id === 1 || item.id === 1 || Number(item.count) > 0)
.map(item => item.appointment_type_id || item.id)
)
}
} else {
ElMessage.error(res.msg)
@ -1740,6 +1797,31 @@
margin-left: 6px;
}
.card_total {
display: inline-block;
background: #409eff;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
.card_locked {
display: inline-block;
background: #e6a23c;
color: #fff;
font-size: 16px;
font-weight: 700;
padding: 2px 10px;
border-radius: 4px;
}
&.qudao_count_row_simple {
justify-content: center;
gap: 12px;
}
.qudao_title_zong {
font-weight: 700;

Loading…
Cancel
Save