号源改版,切换科室等

main
yanzai 5 months ago
parent 0d26370a09
commit 1684826234

@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Services\Admin\MenuService;
use App\Services\Admin\UserService;
use Illuminate\Support\Facades\DB;
class BaseInfoController extends Controller
{
@ -35,4 +36,23 @@ class BaseInfoController extends Controller
$s=app()->make(UserService::class);
return $s->CheckMenuAuth(['userid'=>$userid,'group'=>$group,'url'=>$url]);
}
//切换默认科室
public function ChangeDefaultDept(Request $request)
{
$userid = $request->get('userid');//中间件产生的参数
$deptid = request('deptid');
if (!isset($deptid)) return \Yz::echoError1('请选择科室');
$dept = DB::table('s_department')->where(['id' => $deptid])->first();
if (!$dept) return \Yz::echoError1('科室不存在');
$u= DB::table('users')->where('id', $userid)->update([
'department_id' => $deptid,
'updated_at' => date("Y-m-d H:i:s")
]);
if($u){
return \Yz::Return(true,'切换成功',[]);
}else{
return \Yz::echoError1('切换失败');
}
}
}

@ -48,16 +48,18 @@ class PlanListController extends Controller
if (count($checkList) > 0) {
foreach ($models as $model) {
foreach ($checkList as $item) {
$msglist .= $item->date . ' ';
$msgIds .= $item->id . ' ';
if ($item->roster_id == $model->id) {
$msglist .= $item->date . ' ';
$msgIds .= $item->id . ' ';
$msg .= " " . $model->weekname . $model->begin_time . '-' . $model->end_time . " ";
}
}
if ($item->roster_id == $model->id) {
$msg .= " " . $model->weekname . $model->begin_time . '-' . $model->end_time . " ";
}
}
}
return \Yz::Return(false, '已有重复的计划明细,禁止创建!' . $msg . '已存在相同记录,</br>存在于:</br>' . $msglist . '</br>对应记录Id为' . $msgIds . '</br>请先删除后再操作', $checkList);
}
//查询勾选的时间范围内所有的节假日
@ -243,7 +245,7 @@ class PlanListController extends Controller
//匹配渠道数量
$countsInfo = DB::table('s_source_roster_detail_count')
->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
->select('s_source_roster_detail_count.*', 's_appointment_type.name')
->select('s_source_roster_detail_count.*', 's_appointment_type.name','s_appointment_type.jiancheng')
->whereIn('roster_detail_id', $ids)->get();
if (count($countsInfo) > 0) {

@ -60,13 +60,19 @@ class PlanModelController extends Controller
$list = $list->orderBy('s_source_roster.begin_time')->get();
$ids = [];
foreach ($list as $key => $value) {
$patient_arr = explode(',', $value->patient_type);
$p_type=config('app.globals.患者类型');
$type_label = array_map(function($key) use ($p_type) {
return $p_type[$key] ?? null; // 如果 key 不存在,返回 null
}, $patient_arr);
$list[$key]->patient_type_label = $type_label;
$list[$key]->countsInfo = [];
$ids[] = $value->id;
}
//匹配渠道数量
$countsInfo = DB::table('s_source_roster_count')
->leftJoin('s_appointment_type', 's_source_roster_count.appointment_type_id', '=', 's_appointment_type.id')
->select('s_source_roster_count.*', 's_appointment_type.name')
->select('s_source_roster_count.*', 's_appointment_type.name','s_appointment_type.jiancheng')
->whereIn('roster_id', $ids)->get();
if (count($countsInfo) > 0) {

@ -52,7 +52,7 @@ class PacsController extends Controller
"idCardNumber",
"reservation_sources as reservation_sources_id",
)->where(['is_del'=>0,'is_nullify'=>0]);
)->where(['reservation_date'=>date('Y-m-d'),'is_del'=>0,'is_nullify'=>0]);
if(isset($dateRange)){
if(!is_array($dateRange)) return \Yz::JsonError("日期范围必须是数组");
$entrust_list=$entrust_list->whereBetween('entrust_date',[$dateRange[0],$dateRange[1]]);

@ -90,8 +90,29 @@ class UserService
return $result;
}
public function GetDetail($arr){
$c=DB::table('users')->select(['id','cn_name','username','status','group','img',])->where(['id'=>$arr['id']])->whereIn('status',[0,1])->get();
$c=DB::table('users')->select(['id','cn_name','username','department_id','department_ids','status','group','img',])->where(['id'=>$arr['id']])->whereIn('status',[0,1])->get();
if(count($c)){
$ids=[];
if(!empty($c[0]->department_ids)){
$ids= explode(",", $c[0]->department_ids);
}else{
$ids=[$c[0]->department_id];
}
$departments=DB::table('s_department')->whereIn('id',$ids)->get();
$departments_arr=[];
foreach ($departments as $department){
$departments_arr[]=[
'id' => $department->id,
'department_name' => $department->department_name,
'default' => $c[0]->department_id==$department->id,
];
if($c[0]->department_id==$department->id){
$c[0]->department_name= $department->department_name;
}
}
$c[0]->department_info=$departments_arr;
$result['info']=$c;
$result['status']='ok';
$result['msg']='成功';

@ -101,6 +101,7 @@ Route::group(['middleware'=>['checktoken','log'],'prefix'=>'v1'],function () {
Route::post('admin/CancelSign','App\Http\Controllers\API\Admin\YeWu\SignInController@CancelSign');//取消签到
Route::post('admin/countAppointmentType','App\Http\Controllers\API\Admin\YeWu\AppointmentTypeController@countAppointmentType');//预约渠道统计
Route::post('admin/CountMakeList','App\Http\Controllers\API\Admin\YeWu\WorkMainController@CountMakeList');//开单统计
Route::post('admin/ChangeDefaultDept','App\Http\Controllers\API\Admin\BaseInfoController@ChangeDefaultDept');//切换默认科室
});

@ -359,4 +359,16 @@ export const countAppointmentType = (data = {}) => {
//开单统计
export const CountMakeList = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/CountMakeList', data: data })
}
//同步his分类
export const UpdateHisItemClass = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'admin/UpdateItemClass', data: data })
}
//同步his检查项目
export const updateHisCheckItem = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'admin/updateCheckItem', data: data })
}
//切换默认科室
export const ChangeDefaultDept = (data = {}) => {
return axios({ url: import.meta.env.VITE_APP_API + 'v1/admin/ChangeDefaultDept', data: data })
}

@ -21,8 +21,8 @@
<td style="border: none; text-align: left;">
{{printInfo.patient_type_label}}{{printInfo.reg_num}}
</td>
<td style="border: none; text-align: left;">病区{{printInfo.warddesc ?? ''}}</td>
<td style="border: none; text-align: left;">床号{{printInfo.bedno ?? ''}}</td>
<td v-if="printInfo.patient_type==0" style="border: none; text-align: left;">{{printInfo.warddesc ?? ''}}</td>
<td v-if="printInfo.patient_type==0" style="border: none; text-align: left;">{{printInfo.bedno ?? ''}}</td>
<td style="border: none; text-align: left;">联系电话{{printInfo.user_phone}}</td>
</tr>
</table>

@ -99,7 +99,7 @@
<div v-if="selectedRows.length==0">
<el-empty description="请选择项目" />
</div>
<div v-if="selectedRows.length>0 && planTableData.length==0">
<div v-if="selectedRows.length>0 && planTableData.length==0" style="background-color: #fff;">
<el-empty description="暂无号源" />
</div>
</div>
@ -184,12 +184,13 @@
activeZhenShi.value = ''
selectedRows.value = selection;
console.log('11111',selectedRows.value)
selectedRows.value.forEach((v, i) => {
selectedMianListId.value.push(v.id)
selectedEntrustId.value.push(v.entrust_id)
})
// id id.------------vvvv
// id id.------------vvvv
const allPlanIdsSame = selectedRows.value.every(
(v) => v.roster_id === selectedRows.value[0]?.roster_id
);
@ -307,13 +308,14 @@
}
const FindAllMatchItem = () => {
console.log(11111)
let list = []
//selectedRows.value.reverse();
if (selectedRows.value[0].list_status != 0) return false //
let length=selectedRows.value.length
if (selectedRows.value[length-1].list_status != 0) return false //
entrustTableDate.value.forEach((v, i) => {
if (v.list_status == 0 && v.tishi_msg == "") {
if (v.id == selectedRows.value[0].id) {
if (v.id == selectedRows.value[length-1].id) {
list.push({
name: v.entrust,
rowid: i,

@ -0,0 +1,514 @@
<template>
<div>
<div class="head">
<el-row>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.department_id" placeholder="选择科室"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDepartmentList" :key="index"
:label="item.department_name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.resources_id" placeholder="选择资源"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in enableResourceList" :key="index"
:label="item.department_resources_name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.device_id" placeholder="选择服务组"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDeviceList" :key="index" :label="item.device_name"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.xingqi" placeholder="星期"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in xingqi" :key="index" :label="item.label"
:value="item.label" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.status" placeholder="状态"
style="margin-left: 8px;width: 150px;">
<el-option label="正常" value="1" />
<el-option label="关闭" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-date-picker style="margin-left: 8px; width: 300px" v-model="searchInfo.dateRange"
type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-button @click="GetList()" style="margin-left: 10px;">搜索</el-button>
<el-button type="danger" @click="Del()" style="margin-left: 10px;">删除</el-button>
</el-row>
</div>
<el-table :data="tableData" style="width: 100%;" row-key="id" v-loading="loading"
@selection-change="handleSelectionChange">
<el-table-column type="selection" />
<el-table-column prop="id" label="Id" />
<el-table-column prop="date" label="日期" width="100">
<template #default="scope">
<span>{{ scope.row.date.substring(0, 10) }}</span>
</template>
</el-table-column>
<el-table-column prop="weekname" label="星期" />
<el-table-column prop="resources_id" label="" v-if="false" />
<el-table-column prop="department_resources_name" label="资源" />
<el-table-column prop="" label="服务组" show-overflow-tooltip>
<template #default="scope">
<div v-if="scope.row.devices.length>0">
<div v-for="(item,index) in scope.row.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="period_name" label="时段" />
<el-table-column prop="begin_time" label="开始时间" />
<el-table-column prop="end_time" label="结束时间" />
<el-table-column prop="end_reservation_time" label="截止时间" />
<el-table-column prop="" label="类型数量" show-overflow-tooltip width="250">
<template #default="scope">
<div v-if="scope.row.countsInfo.length>0">
<div style="font-weight: 700;color:#999">最大数量:{{ scope.row.countsInfo[0].max_total }}</div>
<div v-for="(item,index) in scope.row.countsInfo" :key="index" style="display: flex;">
<div style="font-weight:700;width: 50px;text-align: right;margin-right: 8px">{{ item.name
}}
</div>
<div>:{{ item.count }} 已用: <span @click="GetMingXi(scope.row,item.appointment_type_id)"
class="yiyong">{{ item.used_count }}</span>
:{{ Number(item.count - item.used_count) }}
</div>
</div>
</div>
</template>
</el-table-column>
<!-- <el-table-column prop="time_unit" label="可用时长" width="80" />-->
<el-table-column prop="roster_status" label="状态">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" class="ml-2" type="success"></el-tag>
<el-tag v-if="scope.row.status === 0" class="ml-2" type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="" label="操作">
<template #default="scope">
<el-button type="primary" @click="getDetail(scope.row.id)" size="small" style="margin-left: 10px;">
修改
</el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
:page-sizes="[15, 50, 100, 200]" layout="total,sizes, prev, pager, next" :total="total"
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
</div>
<!-- 弹窗修改框-->
<el-dialog v-model="PlanDetailDialogVisible" title="修改" width="40%">
<div v-loading="loading">
<el-form v-if="PlanDetaiInfo" label-width="100px" style="padding-right: 40px;">
<el-form-item label="日期:">
{{ PlanDetaiInfo.date }}
</el-form-item>
<el-form-item label="星期:">
{{ PlanDetaiInfo.weekname }}
</el-form-item>
<el-form-item label="科室:">
{{ PlanDetaiInfo.department_name }}
</el-form-item>
<el-form-item label="资源:">
{{ PlanDetaiInfo.resources_name }}
</el-form-item>
<el-form-item label="服务组:">
<el-tag v-for="(item,index) in PlanDetaiInfo.devices" :key="index"
:type="(item.status===1 && item.is_del===0)?'':'danger'" style="margin-left: 8px">
{{ item.device_name }}
</el-tag>
</el-form-item>
<el-form-item label="病人类型:">
<el-checkbox-group disabled v-model="PlanDetaiInfo.patientType">
<el-checkbox label="0">住院</el-checkbox>
<el-checkbox label="1">门诊</el-checkbox>
<el-checkbox label="2">急诊</el-checkbox>
<el-checkbox label="3">体检</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="时间段:">
开始时间<span style="font-weight: 700;display: inline-block;margin-right: 8px">{{ PlanDetaiInfo.begin_time
}} </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-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>
<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, '')" />
</div>
</div>
</div>
</el-form-item>
<el-form-item label="状态:">
<el-switch v-model="PlanDetaiInfo.status" size="large" active-text="" inactive-text=""
:active-value="1" :inactive-value="0" />
</el-form-item>
<el-form-item label="添加时间:">
{{ PlanDetaiInfo.created_at }}
</el-form-item>
</el-form>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="PlanDetailDialogVisible = false">取消</el-button>
<el-button type="primary" @click="SavePlanAction">
确定
</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="MingXiDialogVisible" title="预约明细" width="60%">
<div>
<div style="text-align: center;font-size: 16px; margin-top: -30px;margin-bottom: 10px;">{{selectedPlanRow.department_resources_name}}
<span v-for="(item,index) in selectedPlanRow.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}
</span>
</div>
<el-form-item label="渠道">
<el-select :filterable="true" clearable v-model="selectecQuDaoid" @change="GetMingXi(selectedPlanRow,selectecQuDaoid)" placeholder="选择渠道"
style="margin-left: 8px;width: 150px;">
<el-option label="全部" :value="0" />
<el-option v-for="(item1,index1) in selectedPlanRow.countsInfo" :key="index1"
:label="item1.name" :value="item1.appointment_type_id" />
</el-select>
</el-form-item>
<el-table :data="MingXiList" style="width: 100%;" row-key="id" v-loading="MingXiLoading">
<el-table-column prop="list_status" label="状态" width="100">
<template #default="scope">
<el-tag v-if="scope.row.list_status===0" class="ml-2" type="info"></el-tag>
<el-tag v-if="scope.row.list_status===1" class="ml-2" type="success"></el-tag>
<el-tag v-if="scope.row.list_status===2" class="ml-2"></el-tag>
<el-tag v-if="scope.row.list_status===3" class="ml-2" type="warning"></el-tag>
</template>
</el-table-column>
<el-table-column prop="user_name" label="姓名" />
<el-table-column prop="user_phone" label="电话" />
<el-table-column prop="reg_num" label="登记号" />
<el-table-column prop="reservation_department" label="申请科室" />
<el-table-column prop="entrust" label="项目" />
<el-table-column prop="qudao_name" label="渠道" />
</el-table>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue'
import {
PlanListGetList,
GetEnableDepartmentList,
GetEnableDeviceList,
TimePeriodGetEnableList,
DepartmentResourceGetEnableList,
PlanDetailChangeInfo,
PlanListGetDetail,
PlanDetailPlanListDel,
GetPlanUsedList
} from '@/api/api.js'
import {
ElMessage,
ElMessageBox
} from 'element-plus'
let loading = ref(false)
let tableData = ref([])
let currentPage = ref(1) //
let pageSize = ref(15) //
let total = 0 //
const PageSizeChange = (e) => { //
pageSize.value = e
GetList()
}
const PageCurrentChange = (e) => { //
currentPage.value = e
GetList()
}
let tableSelected = ref([])
const handleSelectionChange = (e) => {
tableSelected.value = e
}
let searchInfo = ref({
department_id: null,
resources_id: null,
device_id: null,
xingqi: null,
status: null,
dateRange: []
})
let PlanDetailDialogVisible = ref(false)
const GetList = () => {
PlanListGetList({
page: currentPage.value,
pageSize: pageSize.value,
searchInfo: searchInfo.value
}).then(res => {
tableData.value = res.data.list
total = res.data.count
})
}
let xingqi = ref([{
label: '星期一',
value: 1
}, {
label: '星期二',
value: 2
}, {
label: '星期三',
value: 3
}, {
label: '星期四',
value: 4
}, {
label: '星期五',
value: 5
}, {
label: '星期六',
value: 6
}, {
label: '星期日',
value: 7
}])
//
let EnableDeviceList = ref([])
const GetEnableDeviceListFunc = () => {
loading.value = true
GetEnableDeviceList().then(res => {
loading.value = false
if (res.status) {
EnableDeviceList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
let EnableDepartmentList = ref([])
const GetDepartmentEnableList = () => {
loading.value = true
GetEnableDepartmentList({}).then(res => {
loading.value = false
if (res.status) {
EnableDepartmentList.value = res.data.list
} else {
ElMessage.error(res.msg)
}
})
}
// //
// let TimePeriodList = ref([])
// const GetEnableTimePeriod = () => {
// loading.value = true
// TimePeriodGetEnableList().then(res => {
// loading.value = false
// if (res.status) {
// TimePeriodList.value = res.data
// } else {
// ElMessage.error(res.msg)
// }
//
// })
// }
//
let enableResourceList = ref([])
const getEnableResource = () => {
loading.value = true
DepartmentResourceGetEnableList().then(res => {
loading.value = false
if (res.status) {
enableResourceList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
let PlanDetaiInfo = ref('')
const getDetail = (id) => {
PlanDetailDialogVisible.value = true
loading.value = true
PlanListGetDetail({
id: id
}).then(res => {
loading.value = false
if (res.status) {
PlanDetaiInfo.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const MaxCountChange = (e) => {
console.log(e)
if (e === '' || e == null || e === 0) {
PlanDetaiInfo.value.max_total = 0
}
let temp = 0
let qudao_count = PlanDetaiInfo.value.coutsInfo.length
for (let i = 0; i < qudao_count; i++) {
if (PlanDetaiInfo.value.coutsInfo[i].ratio === 0) continue
PlanDetaiInfo.value.coutsInfo[i].count = Math.round(PlanDetaiInfo.value.max_total * (PlanDetaiInfo.value
.coutsInfo[i].ratio / 100))
temp = temp + PlanDetaiInfo.value.coutsInfo[i].count
//1
if (i === qudao_count - 1 && temp !== PlanDetaiInfo.value.max_total) {
PlanDetaiInfo.value.coutsInfo[i].count = PlanDetaiInfo.value.coutsInfo[i].count - (temp - PlanDetaiInfo
.value.max_total)
}
}
}
//
const SavePlanAction = () => {
let tempCount = 0
PlanDetaiInfo.value.coutsInfo.forEach((item) => {
tempCount = tempCount + Number(item.count)
})
if (tempCount !== Number(PlanDetaiInfo.value.max_total)) {
ElMessage.error('各个渠道数量之和与当日总量不符')
return false
}
loading.value = true
PlanDetailChangeInfo({
PlanDetaiInfo: PlanDetaiInfo.value
}).then(res => {
loading.value = false
if (res.status) {
PlanDetailDialogVisible.value = false
GetList()
} else {
ElMessage.error(res.msg)
}
})
}
const Del = () => {
if (tableSelected.value.length == 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
let ids = []
tableSelected.value.map((item) => {
ids.push(item.id)
})
ElMessageBox.confirm(
'确定删除吗?',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
loading.value = true
PlanDetailPlanListDel({
ids: ids
}).then(res => {
loading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
GetList()
} else {
ElMessage.error(res.msg)
}
})
})
}
let MingXiDialogVisible = ref(false);
let MingXiLoading = ref(false)
let MingXiList = ref(null);
let selectedPlanRow = ref(null);
let selectecQuDaoid =ref(null);
const GetMingXi = (row, typeid) => {
selectecQuDaoid.value=typeid
selectedPlanRow.value = row
MingXiDialogVisible.value = true
MingXiLoading.value = true
GetPlanUsedList({
planid: row.id,
qudaoid: typeid
}).then(res => {
MingXiLoading.value = false
if (res.status) {
MingXiList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
onMounted(() => {
GetList()
GetDepartmentEnableList()
getEnableResource()
GetEnableDeviceListFunc()
})
</script>
<style scoped>
.type_count {
display: flex;
}
.type_count div {
white-space: nowrap;
margin-right: 10px;
}
.qudao_k {
display: flex;
}
.qudao_k_input {
width: 150px;
}
.hongzi {
color: #b25252;
}
.yiyong {
font-weight: 700;
color: #f5a96c;
cursor: pointer;
}
.yiyong:hover {
color: #666;
}
</style>

@ -2,7 +2,7 @@
<div>
<div class="head">
<el-row>
<el-form-item>
<!-- <el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.department_id" placeholder="选择科室"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDepartmentList" :key="index"
@ -36,7 +36,7 @@
<el-option label="正常" value="1" />
<el-option label="关闭" value="0" />
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-date-picker style="margin-left: 8px; width: 300px" v-model="searchInfo.dateRange"
type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间"
@ -46,67 +46,71 @@
<el-button type="danger" @click="Del()" style="margin-left: 10px;">删除</el-button>
</el-row>
</div>
<el-table :data="tableData" style="width: 100%;" row-key="id" v-loading="loading"
@selection-change="handleSelectionChange">
<el-table-column type="selection" />
<el-table-column prop="id" label="Id" />
<el-table-column prop="date" label="日期" width="100">
<template #default="scope">
<span>{{ scope.row.date.substring(0, 10) }}</span>
</template>
</el-table-column>
<el-table-column prop="weekname" label="星期" />
<el-table-column prop="resources_id" label="" v-if="false" />
<el-table-column prop="department_resources_name" label="资源" />
<el-table-column prop="" label="服务组" show-overflow-tooltip>
<template #default="scope">
<div v-if="scope.row.devices.length>0">
<div v-for="(item,index) in scope.row.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="period_name" label="时段" />
<el-table-column prop="begin_time" label="开始时间" />
<el-table-column prop="end_time" label="结束时间" />
<el-table-column prop="end_reservation_time" label="截止时间" />
<el-table-column prop="" label="类型数量" show-overflow-tooltip width="250">
<template #default="scope">
<div v-if="scope.row.countsInfo.length>0">
<div style="font-weight: 700;color:#999">最大数量:{{ scope.row.countsInfo[0].max_total }}</div>
<div v-for="(item,index) in scope.row.countsInfo" :key="index" style="display: flex;">
<div style="font-weight:700;width: 50px;text-align: right;margin-right: 8px">{{ item.name
}}
<div style="display: flex;" class="planInfo">
<div style=" border-right: 1px solid #dadada;padding-right: 4px;">
<div v-for="(item,index) in enableResourceList" :key="index" @click="zhenshiClick(item.id)"
:class="{'zhenshiButton zhenshiButtonActive':item.id===ResourceActive,'zhenshiButton':item.id !==ResourceActive}">
{{item.department_resources_name}}
</div>
</div>
<div v-loading="loading" style="border: 1px solid #efefef;width: 100%; overflow-x: auto;">
<table class="planTable" v-if="planTableData.length>0">
<tr style="background-color: #f1f1f1;position: relative;">
<td>
<div style="width: 120px;display: flex;font-size: 12px;justify-content: center;align-items: center;">
<div style="margin-left: 30px;margin-right: 6px;">全选</div>
<div :class="{'plan_checkAllbox plan_checkAllbox_active':PlanSelectedAll===1,'plan_checkAllbox ':PlanSelectedAll===0}"
@click="selectedAllPlanFunc()">
<el-icon v-if="PlanSelectedAll===1" color="#ffffff"><Select /></el-icon>
</div>
</div>
<div>:{{ item.count }} 已用: <span @click="GetMingXi(scope.row,item.appointment_type_id)"
class="yiyong">{{ item.used_count }}</span>
:{{ Number(item.count - item.used_count) }}
</td>
<td style="min-width: 90px;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" @mouseover="showTools(item2.id)"
@mouseleave="hideTools(item2.id)">
<div>
<span v-if="index2=='time_range'">{{item2}}</span>
<div v-if="item2.countsInfo && item2.countsInfo.length>0"
:class="{'planInfo_k':item2.status==1,'planInfo_k planInfo_k_disabled':item2.status==0}">
<div v-if="hoverIndex==item2.id" class="hoverTools" >
<div class="icon_k" @click="getDetail(item2.id)">
<el-icon color="#409eff" size="20">
<Edit />
</el-icon>
</div>
<div class="icon_k" @click="GetMingXi(item2,0)">
<el-icon color="#409eff" size="20">
<Document />
</el-icon>
</div>
</div>
<div :class="{'plan_checkbox plan_checkbox_active':isSelected(item2.id),'plan_checkbox':!isSelected(item2.id)}"
@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">
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span><span class="font_color">{{item3.used_count}}</span>/{{item3.count}} </span>
</div>
</div>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<!-- <el-table-column prop="time_unit" label="可用时长" width="80" />-->
<el-table-column prop="roster_status" label="状态">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" class="ml-2" type="success"></el-tag>
<el-tag v-if="scope.row.status === 0" class="ml-2" type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="" label="操作">
<template #default="scope">
<el-button type="primary" @click="getDetail(scope.row.id)" size="small" style="margin-left: 10px;">
修改
</el-button>
</template>
</el-table-column>
</el-table>
<div class="page">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
:page-sizes="[15, 50, 100, 200]" layout="total,sizes, prev, pager, next" :total="total"
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
</td>
</tr>
</table>
<div v-if="planTableData.length==0" style="width: 100%;background-color: #fff;">
<el-empty description="暂无号源" />
</div>
</div>
</div>
<!-- 弹窗修改框-->
<el-dialog v-model="PlanDetailDialogVisible" title="修改" width="40%">
@ -184,15 +188,17 @@
</el-dialog>
<el-dialog v-model="MingXiDialogVisible" title="预约明细" width="60%">
<div>
<div style="text-align: center;font-size: 16px; margin-top: -30px;margin-bottom: 10px;">{{selectedPlanRow.department_resources_name}}
<div style="text-align: center;font-size: 16px; margin-top: -30px;margin-bottom: 10px;">
{{selectedPlanRow.department_resources_name}}
<span v-for="(item,index) in selectedPlanRow.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}
</span>
</div>
<el-form-item label="渠道">
<el-select :filterable="true" clearable v-model="selectecQuDaoid" @change="GetMingXi(selectedPlanRow,selectecQuDaoid)" placeholder="选择渠道"
<el-select :filterable="true" clearable v-model="selectecQuDaoid"
@change="GetMingXi(selectedPlanRow,selectecQuDaoid)" placeholder="选择渠道"
style="margin-left: 8px;width: 150px;">
<el-option label="全部" :value="0" />
<el-option label="全部" :value="0" />
<el-option v-for="(item1,index1) in selectedPlanRow.countsInfo" :key="index1"
:label="item1.name" :value="item1.appointment_type_id" />
</el-select>
@ -238,24 +244,15 @@
ElMessageBox
} from 'element-plus'
let planTableData = ref([])
let loading = ref(false)
let tableData = ref([])
let currentPage = ref(1) //
let pageSize = ref(15) //
let pageSize = ref(9999) //
let total = 0 //
const PageSizeChange = (e) => { //
pageSize.value = e
GetList()
}
const PageCurrentChange = (e) => { //
currentPage.value = e
GetList()
}
let tableSelected = ref([])
const handleSelectionChange = (e) => {
tableSelected.value = e
}
let selectedPlanArr = ref([])
let date_list = ref([])
let PlanSelectedAll = ref(0)
let searchInfo = ref({
department_id: null,
resources_id: null,
@ -266,16 +263,120 @@
})
let PlanDetailDialogVisible = ref(false)
const GetList = () => {
searchInfo.value.resources_id = ResourceActive.value
date_list.value = getAllDatesBetweenDates(searchInfo.value.dateRange)
loading.value=true
PlanListGetList({
page: currentPage.value,
pageSize: pageSize.value,
searchInfo: searchInfo.value
}).then(res => {
tableData.value = res.data.list
total = res.data.count
loading.value=false
if (res.status) {
planTableData.value = []
selectedPlanArr.value = []
let plans = res.data.list
if (plans.length > 0) {
const timeSlotsSet = new Set();
plans.forEach(v => {
if (v.resources_id == ResourceActive.value) {
const timeRange =
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}`;
timeSlotsSet.add(timeRange);
}
});
const timeSlots = Array.from(timeSlotsSet).sort(); //
// Step 2:
timeSlots.forEach(timeRange => {
const row = {
time_range: timeRange
};
date_list.value.forEach(date => {
const matchingPlan = plans.find(
v =>
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}` ===
timeRange && v.date === date && v.resources_id ==
ResourceActive.value
);
let plan_enable = false
if (matchingPlan) {
row[date] = {
countsInfo: matchingPlan.countsInfo,
patient_type_label: matchingPlan.patient_type_label,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id: matchingPlan.resources_id
};
}else{
row[date] = {
countsInfo:null,
patient_type_label:null,
status: null,
id:null,
resources_id:null
};
}
});
planTableData.value.push(row);
});
}
} else {
ElMessage.error(res.msg)
}
})
}
const selectedAllPlanFunc = () => {
PlanSelectedAll.value = PlanSelectedAll.value === 0 ? 1 : 0;
if (PlanSelectedAll.value === 0) {
selectedPlanArr.value = []
}
if (PlanSelectedAll.value === 1) {
planTableData.value.forEach((v, i) => {
console.log(v)
for (let key in v) {
if (key != 'time_range') {
selectedPlanArr.value.push(v[key].id)
}
}
})
}
}
const checkBoxCheckFunc = (id) => {
const index = selectedPlanArr.value.indexOf(id);
if (index === -1) {
selectedPlanArr.value.push(id);
} else {
selectedPlanArr.value = selectedPlanArr.value.filter(item => item !== id);
}
};
let hoverIndex = ref(null)
const showTools = (index) => {
hoverIndex.value = index
}
const hideTools = (index) => {
hoverIndex.value = null
}
const zhenshiClick = (zhenshi) => {
ResourceActive.value = zhenshi
PlanSelectedAll.value = 0
selectedPlanArr.value = []
GetList()
}
const isSelected = (id) => {
return selectedPlanArr.value.includes(id)
}
let xingqi = ref([{
label: '星期一',
value: 1
@ -341,12 +442,18 @@
// }
//
let enableResourceList = ref([])
let ResourceActive = ref(0)
const getEnableResource = () => {
loading.value = true
DepartmentResourceGetEnableList().then(res => {
loading.value = false
if (res.status) {
enableResourceList.value = res.data
if (enableResourceList.value.length > 0 && ResourceActive.value == '') {
ResourceActive.value = enableResourceList.value[0].id
GetList()
}
} else {
ElMessage.error(res.msg)
}
@ -416,14 +523,11 @@
})
}
const Del = () => {
if (tableSelected.value.length == 0) {
if (selectedPlanArr.value.length == 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
let ids = []
tableSelected.value.map((item) => {
ids.push(item.id)
})
ElMessageBox.confirm(
'确定删除吗?',
'提示', {
@ -434,7 +538,7 @@
).then(() => {
loading.value = true
PlanDetailPlanListDel({
ids: ids
ids: selectedPlanArr.value
}).then(res => {
loading.value = false
if (res.status) {
@ -453,9 +557,9 @@
let MingXiLoading = ref(false)
let MingXiList = ref(null);
let selectedPlanRow = ref(null);
let selectecQuDaoid =ref(null);
let selectecQuDaoid = ref(null);
const GetMingXi = (row, typeid) => {
selectecQuDaoid.value=typeid
selectecQuDaoid.value = typeid
selectedPlanRow.value = row
MingXiDialogVisible.value = true
MingXiLoading.value = true
@ -473,14 +577,66 @@
})
}
function formatDateLocal(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
function getAllDatesBetweenDates(dateArray) {
// Date
const sortedDates = dateArray
.map(dateStr => new Date(dateStr))
.sort((a, b) => a - b);
const startDate = sortedDates[0];
const endDate = sortedDates[sortedDates.length - 1];
const dateList = [];
let currentDate = new Date(startDate);
while (currentDate <= endDate) {
dateList.push(currentDate.toISOString().split('T')[0]); // YYYY-MM-DD
currentDate.setDate(currentDate.getDate() + 1);
}
return dateList;
}
function getWeekday(dateString) {
const date = new Date(dateString);
if (isNaN(date)) {
return "无效日期";
}
const weekdays = [
"周日",
"周一",
"周二",
"周三",
"周四",
"周五",
"周六"
];
return weekdays[date.getDay()];
}
onMounted(() => {
GetList()
const today = new Date();
const todayStr = formatDateLocal(today);
// 15
const fifteenDaysLater = new Date(today);
fifteenDaysLater.setDate(today.getDate() + 14);
const fifteenDaysLaterStr = formatDateLocal(fifteenDaysLater);
searchInfo.value.dateRange = [todayStr, fifteenDaysLaterStr]
GetDepartmentEnableList()
getEnableResource()
GetEnableDeviceListFunc()
})
</script>
<style scoped>
<style lang="scss" scoped>
.type_count {
display: flex;
}
@ -511,4 +667,168 @@
.yiyong:hover {
color: #666;
}
.zhenshiButton {
width: 150px;
line-height: 36px;
height: 36px;
border: 1px solid #e8e8e8;
text-align: center;
margin-top: 4px;
border-radius: 4px;
cursor: default;
}
.zhenshiButtonActive {
background-color: #5bc0de;
color: #fff;
}
.plan_checkAllbox {
height: 20px;
width: 20px;
border: 1px solid #7cccc7;
border-radius: 4px;
}
.plan_checkAllbox_active {
background-color: #409eff;
justify-content: center;
align-items: center;
display: flex;
}
.planInfo_k_disabled{
background-color: #ffd6d2;
}
.planInfo_k {
font-size: 14px;
color: #333;
position: relative;
padding-top: 6px;
padding-bottom: 10px;
padding-right: 8px;
.zong_row{
text-align: right;
.qudao_title_zong {
font-weight: 600;
span {
font-weight: 500;
}
}
}
.plan_checkbox {
position: absolute;
top: 2px;
left: 2px;
height: 16px;
width: 16px;
border: 1px solid #98c4cc;
border-radius: 4px;
}
.plan_checkbox_active {
background-color: #409eff;
justify-content: center;
align-items: center;
display: flex;
}
.hoverTools {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
border-radius: 4px;
.icon_k {
height: 30px;
width: 30px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ccc;
background-color: #fff;
margin-left: 6px;
}
}
.qudao_count_row {
display: flex;
div {
margin-left: 6px;
}
}
}
.planInfo {
.planTable {
width: 100%;
background-color: #fff;
text-align: center;
border: 1px solid #f1f1f1;
border-collapse: collapse;
/* 合并边框 */
color: #333;
td {
border: 1px solid #f1f1f1;
// padding: 6px;
}
td:first-child,
th:first-child {
position: sticky;
left: 0;
background-color: #fafafa;
z-index: 1;
}
}
.table_plan_row td:first-child {
background-color: #f1f1f1;
border-bottom: 1px solid #e8e8e8;
}
.table_plan_row> :not(:first-child):hover {
background-color: #aeebf0;
cursor: pointer;
color: #fff;
}
.planActive {
background-color: #5bc0de;
color: #fff;
}
.plandisable {
pointer-events: none;
opacity: 0.4;
}
.shuxian {
border-left: 1px solid #dfdfdf;
margin-left: 40px;
margin-right: 40px;
}
.do_button {
width: 100px;
}
}
.yellow{
color:#ffaa7f;
}
.red{
color:#c81e00;
}
</style>

@ -0,0 +1,835 @@
<template>
<div>
<div class="head">
<el-row>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.department_id" placeholder="选择科室"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDepartmentList" :key="index"
:label="item.department_name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.resources_id" placeholder="选择资源"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in enableResourceList" :key="index"
:label="item.department_resources_name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.device_id" placeholder="选择服务组"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDeviceList" :key="index" :label="item.device_name"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.xingqi" placeholder="星期"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in xingqi" :key="index" :label="item.label"
:value="item.label" />
</el-select>
</el-form-item>
<el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.status" placeholder="状态"
style="margin-left: 8px;width: 150px;">
<el-option label="正常" value="1" />
<el-option label="关闭" value="0" />
</el-select>
</el-form-item>
<el-button @click="GetList()" style="margin-left: 10px;">搜索</el-button>
<el-button type="primary" @click="Add()" style="margin-left: 10px;">添加</el-button>
<el-button type="danger" @click="Del()" style="margin-left: 10px;">删除</el-button>
<el-button type="success" @click="CreatedPlanClick()" style="margin-left: 20px;">生成选中的计划</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" :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" 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">
<template #default="scope">
<div class="type_count" v-if="scope.row.devices.length>0">
<div v-for="(item,index) in scope.row.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="period_name" label="时段" width="100" />
<el-table-column prop="begin_time" label="开始时间" width="100" />
<el-table-column prop="end_time" label="结束时间" width="100" />
<el-table-column prop="" label="类型数量" show-overflow-tooltip>
<template #default="scope">
<div class="type_count" v-if="scope.row.countsInfo.length>0">
<div style="font-weight: 700">最大数量:{{ scope.row.countsInfo[0].max_total }}</div>
<div v-for="(item,index) in scope.row.countsInfo" :key="index">{{ item.name }}:{{ item.count
}}
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="end_reservation_time" label="预约截止时间" width="120" />
<!-- <el-table-column prop="time_unit" label="可用时长" width="80" /> -->
<el-table-column prop="roster_status" label="状态" width="80">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" class="ml-2" type="success"></el-tag>
<el-tag v-if="scope.row.status === 0" class="ml-2" type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="" label="操作" width="80">
<template #default="scope">
<el-button type="primary" @click="Add(scope.row)" size="small" style="margin-left: 10px;">修改
</el-button>
</template>
</el-table-column>
</el-table>
<!-- <div class="page">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
:page-sizes="[15, 50, 100, 200]" layout="total,sizes, prev, pager, next" :total="total"
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
</div> -->
<el-dialog v-model="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" 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"
:label="item.label">{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<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="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>
<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="1"
placeholder="0" oninput="value=value.replace(/^0|[^0-9]/g, '')" />
<div style="margin-left: 4px; color: #ccc;">{{item.ratio}}%</div>
</div>
</div>
</div>
</el-form-item>
<el-form-item label="时间设置:">
<div>选择时段:
<el-select :filterable="true" clearable v-model="PlanInfo.period_id" @change="timePeriodChange"
placeholder="选择时段" style="width: 200px;margin-left: 8px;margin-bottom: 4px">
<el-option v-for="(item,index) in TimePeriodList" :key="index" :label="item.period_name"
:value="item.id" />
</el-select>
<div style="display:flex;">
<div>
<div style="display:flex;">
<div style="width: 70px">开始时间:</div>
<div class="qudao_k_input">
<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="结束时间" />
</div>
</div>
</div>
<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="停止预约时间" />
</div>
</div>
<div style="display:flex;">
<div style="width: 90px">可用时间长度:</div>
<div class="qudao_k_input">
<el-input v-model="PlanInfo.time_unit" placeholder="可用时间长度" />
</div>
</div>
</div>
</div>
</div>
</el-form-item>
<el-form-item label="资源:">
<el-select :filterable="true" clearable v-model="PlanInfo.resources_id" @change="resourceChange"
placeholder="选择资源" style="width: 200px;margin-left: 8px;margin-bottom: 4px">
<el-option v-for="(item,index) in enableResourceList" :key="index"
:label="item.department_resources_name" :value="item.id" />
</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>
<el-checkbox-group v-model="PlanInfo.devices">
<el-checkbox v-for="(item,index) in devicesList" :key="index"
:label="item.id">{{ item.device_name }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="病人类型:">
<el-checkbox-group v-model="PlanInfo.patientType">
<el-checkbox label="0">住院</el-checkbox>
<el-checkbox label="1">门诊</el-checkbox>
<el-checkbox label="2">急诊</el-checkbox>
<el-checkbox label="3">体检</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="状态:">
<el-switch v-model="PlanInfo.status" size="large" active-text="" inactive-text=""
:active-value="1" :inactive-value="0" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="Save">
确定
</el-button>
</span>
</template>
</el-dialog>
<!-- 生成时选择时间段-->
<el-dialog v-model="CreatePlanDialogVisible" title="生成计划" width="50%">
<el-form label-width="100px" v-loading="loading" style="padding-right: 40px;">
<el-form-item label="选择时间范围:">
<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">
<el-button @click="CreatePlanDialogVisible = false">取消</el-button>
<el-button type="primary" @click="CreatedPlanAction">
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue'
import {
PlanModelSave,
PlanModelGetList,
GetEnableDepartmentList,
GetAppointmentRatio,
TimePeriodGetEnableList,
TimePeriodGetDetail,
DepartmentResourceGetEnableList,
ResourceGetBindDeviceList,
GetPlanModelDetailInfo,
PlanModelDel,
GetEnableDeviceList,
CreatePlanList,
GetServiceDateTime
} from '@/api/api.js'
import {
ElMessage,
ElMessageBox
} from 'element-plus'
let CountType = ref("1"); //
let loading = ref(false)
let tableData = ref([])
let currentPage = ref(1) //
let pageSize = ref(15) //
let total = 0 //
const PageSizeChange = (e) => { //
pageSize.value = e
GetList()
}
const PageCurrentChange = (e) => { //
currentPage.value = e
GetList()
}
let tableSelected = ref([])
const handleSelectionChange = (e) => {
tableSelected.value = e
}
let dateRange = ref([]) //
let CreatePlanDialogVisible = ref(false)
const CreatedPlanClick = () => { //
if (tableSelected.value.length === 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
CreatePlanDialogVisible.value = true;
}
const CreatedPlanAction = () => { //
if (dateRange.value.length === 0) {
ElMessage.error("请选择日期范围")
return false;
}
let ids = [];
tableSelected.value.forEach((v, i) => {
ids.push(v.id)
})
CreatePlanList({
dateRange: dateRange.value,
ids: ids,
HolidayEnable:HolidayEnable.value,
date_type:searchInfo.value.date_type
}).then(res => {
if (res.status) {
CreatePlanDialogVisible.value = false;
ElMessage({
message: res.msg,
type: 'success',
})
} else {
ElMessageBox.alert(res.msg, '提示', {
// if you want to disable its autofocus
// autofocus: false,
confirmButtonText: '确定',
dangerouslyUseHTMLString: true,
})
}
})
}
let searchInfo = ref({
department_id: null,
resources_id: null,
device_id: null,
xingqi: null,
status: null,
})
let HolidayEnable=ref(1)
let date_type_name =ref('工作日')
let dialogVisible = ref(false)
const GetList = () => {
PlanModelGetList({
page: currentPage.value,
pageSize: pageSize.value,
searchInfo: searchInfo.value
}).then(res => {
tableData.value = res.data.list
total = res.data.count
})
}
let xingqi = ref([{
label: '星期一',
value: 1
}, {
label: '星期二',
value: 2
}, {
label: '星期三',
value: 3
}, {
label: '星期四',
value: 4
}, {
label: '星期五',
value: 5
}, {
label: '星期六',
value: 6
}, {
label: '星期日',
value: 7
}])
let PlanInfoForm = ref(null)
const DataDefault = () => {
return {
id: 0,
xingqi: [],
max_total: 0,
qudao_total: [],
period_id: null,
begin_time: '',
end_time: '',
end_reservation_time: '',
time_unit: 0, //
resources_id: null,
devices: [],
patientType: [],
status: 1
}
}
let PlanInfo = ref(DataDefault())
const Add = (row = null) => {
devicesList.value=[]
CheckedAll.value = false
dialogVisible.value = true
PlanInfo.value = DataDefault()
GetRatio()
GetEnableTimePeriod()
getEnableResource()
if (row) {
PlanInfo.value.resources_id = row.resources_id
resourceChange()
setTimeout(() => {
console.log('编辑')
GetDetailInfo(row.id)
}, 500)
}
}
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)
//
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
}
ElMessageBox.confirm(
'确定保存吗?',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
loading.value = true
PlanModelSave({
date_type:searchInfo.value.date_type,
planInfo: PlanInfo.value
}).then(res => {
loading.value = false
if (res.status) {
dialogVisible.value = false
GetList()
} else {
ElMessage.error(res.msg)
}
})
})
}
const Del = () => {
if (tableSelected.value.length == 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
let ids = []
tableSelected.value.map((item) => {
ids.push(item.id)
})
ElMessageBox.confirm(
'确定删除吗?',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
loading.value = true
PlanModelDel({
ids: ids
}).then(res => {
loading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
GetList()
} else {
ElMessage.error(res.msg)
}
})
})
}
//
let EnableDeviceList = ref([])
const GetEnableDeviceListFunc = () => {
loading.value = true
GetEnableDeviceList().then(res => {
loading.value = false
if (res.status) {
EnableDeviceList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
let EnableDepartmentList = ref([])
const GetDepartmentEnableList = () => {
loading.value = true
GetEnableDepartmentList({}).then(res => {
loading.value = false
if (res.status) {
EnableDepartmentList.value = res.data.list
} else {
ElMessage.error(res.msg)
}
})
}
//
const GetRatio = () => {
loading.value = true
GetAppointmentRatio({}).then(res => {
loading.value = false
if (res.status) {
PlanInfo.value.qudao_total = res.data
PlanInfo.value.qudao_total.forEach((v, i) => {
PlanInfo.value.qudao_total[i].count = 0
})
// console.log(PlanInfo.value)
} else {
ElMessage.error(res.msg)
}
})
}
//
const MaxCountChange = (e) => {
if (e === '' || e == null || e === 0) {
PlanInfo.value.max_total = 0
}
let temp = 0
let qudao_count = PlanInfo.value.qudao_total.length
console.log(PlanInfo.value.qudao_total)
for (let i = 0; i < qudao_count; i++) {
if (PlanInfo.value.qudao_total[i].ratio === 0) continue;
PlanInfo.value.qudao_total[i].count = Math.round(PlanInfo.value.max_total * (PlanInfo.value.qudao_total[i]
.ratio / 100))
temp = temp + PlanInfo.value.qudao_total[i].count
//1
if (i === qudao_count - 1 && temp !== PlanInfo.value.max_total) {
let bodongzhi = temp - PlanInfo.value.max_total;
// PlanInfo.value.qudao_total[i].count = PlanInfo.value.qudao_total[i].count - (temp - PlanInfo.value.max_total)
// if(PlanInfo.value.qudao_total[i].count<0) {
// PlanInfo.value.qudao_total[i].count=0
// }
PlanInfo.value.qudao_total.sort((a, b) => a.ratio - b.ratio);
//
let minRatioItem = null;
for (let ii = 0; ii < PlanInfo.value.qudao_total.length; ii++) {
if (PlanInfo.value.qudao_total[ii].count !== 0) {
minRatioItem = PlanInfo.value.qudao_total[ii];
break;
}
}
//
let index = PlanInfo.value.qudao_total.indexOf(minRatioItem);
console.log("最小且非零项在原数组中的位置:", index);
console.log(bodongzhi);
if (bodongzhi > 0) {
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
}
if (bodongzhi < 0 && index == 0) {
PlanInfo.value.qudao_total[index].count = PlanInfo.value.qudao_total[index].count - bodongzhi
}
PlanInfo.value.qudao_total.sort((a, b) => b.ratio - a.ratio);
}
}
}
//
let TimePeriodList = ref([])
const GetEnableTimePeriod = () => {
loading.value = true
TimePeriodGetEnableList({date_type:searchInfo.value.date_type}).then(res => {
loading.value = false
if (res.status) {
TimePeriodList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const timePeriodChange = () => {
loading.value = true
TimePeriodGetDetail({
id: PlanInfo.value.period_id
}).then(res => {
loading.value = false
if (res.status) {
PlanInfo.value.begin_time = res.data.period_begin_time
PlanInfo.value.end_time = res.data.period_end_time
PlanInfo.value.end_reservation_time = res.data.period_deadline
} else {
ElMessage.error(res.msg)
}
})
}
//
const GetDetailInfo = (id) => {
loading.value = true
GetPlanModelDetailInfo({
id: id
}).then(res => {
loading.value = false
if (res.status) {
PlanInfo.value = res.data
PlanInfo.value.max_total = res.data.qudao_total[0].max_total
PlanInfo.value.xingqi = [res.data.weekname]
PlanInfo.value.devices = res.data.devices
} else {
ElMessage.error(res.msg)
}
})
}
//
let enableResourceList = ref([])
const getEnableResource = () => {
loading.value = true
DepartmentResourceGetEnableList().then(res => {
loading.value = false
if (res.status) {
enableResourceList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
let devicesList = ref([])
const resourceChange = () => {
PlanInfo.value.devices = [];
loading.value = true
ResourceGetBindDeviceList({
resource_id: PlanInfo.value.resources_id
}).then(res => {
loading.value = false
if (res.status) {
devicesList.value = res.data
} else {
ElMessage.error(res.msg)
}
})
}
//
const setMonthRange = () => {
GetServiceDateTime().then(res => {
if (res.status) {
let currentdate = res.data.datetime.substring(0, 10)
var date = new Date(currentdate);
// JavaScript0
var currentMonth = date.getMonth();
// 121
var nextMonthMonth = (currentMonth + 1) % 12;
var nextMonthYear = date.getFullYear() + ((currentMonth + 1) / 12 | 0); //
//
var currentDay = date.getDate();
//
var nextMonthSameDay = new Date(nextMonthYear, nextMonthMonth, currentDay);
// 331431
if (nextMonthSameDay.getMonth() !== nextMonthMonth) {
//
nextMonthSameDay = new Date(nextMonthYear, nextMonthMonth, 0);
}
//
let nextMonth = nextMonthSameDay.toISOString().split('T')[0]; // YYYY-MM-DD
dateRange.value = [currentdate, nextMonth];
}
})
}
let CheckedAll = ref(false);
//
const CheckedAllFunc = (e) => {
if (e) {
PlanInfo.value.xingqi = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
} else {
PlanInfo.value.xingqi = []
}
}
//
let bb_countRowspan = 1;
const arraySpanMethod = ({
row,
column,
rowIndex,
columnIndex,
}) => {
const fields = ['weekname']
const cellValue = row[column.property]
let countRowspan = 1
if (cellValue && fields.includes(column.property)) {
const prevRow = tableData.value[rowIndex - 1]
let nextRow = tableData.value[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue && prevRow.declareRegion == row.declareRegion) {
bb_countRowspan = countRowspan
return {
rowspan: 0,
colspan: 0
}
} else {
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
}
}
}
}
// 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()
GetEnableDeviceListFunc()
setMonthRange()
})
</script>
<style scoped>
.type_count {
display: flex;
}
.type_count div {
white-space: nowrap;
margin-right: 10px;
}
.qudao_k {
display: flex;
}
.qudao_k_input {
width: 150px;
}
.hongzi {
color: #b25252;
}
</style>

@ -1,8 +1,8 @@
<template>
<div>
<div class="head">
<el-row>
<el-form-item>
<el-row style="display: flex; justify-content: end;">
<!-- <el-form-item>
<el-select :filterable="true" clearable v-model="searchInfo.department_id" placeholder="选择科室"
style="margin-left: 8px;width: 150px;">
<el-option v-for="(item,index) in EnableDepartmentList" :key="index"
@ -37,68 +37,76 @@
<el-option label="关闭" value="0" />
</el-select>
</el-form-item>
<el-button @click="GetList()" style="margin-left: 10px;">搜索</el-button>
<el-button @click="GetList()" style="margin-left: 10px;">搜索</el-button> -->
<el-button type="primary" @click="Add()" style="margin-left: 10px;">添加</el-button>
<el-button type="danger" @click="Del()" style="margin-left: 10px;">删除</el-button>
<el-button type="success" @click="CreatedPlanClick()" style="margin-left: 20px;">生成选中的计划</el-button>
</el-row>
</div>
<el-row>
<el-radio-group style="margin-bottom: 8px;" v-model="searchInfo.date_type"
@change="DateTypeChange()">
<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" 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">
<template #default="scope">
<div class="type_count" v-if="scope.row.devices.length>0">
<div v-for="(item,index) in scope.row.devices" :key="index"
:class="(item.status==1 && item.is_del==0) ? '':'hongzi'">{{ item.device_name }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="period_name" label="时段" width="100" />
<el-table-column prop="begin_time" label="开始时间" width="100" />
<el-table-column prop="end_time" label="结束时间" width="100" />
<el-table-column prop="" label="类型数量" show-overflow-tooltip>
<template #default="scope">
<div class="type_count" v-if="scope.row.countsInfo.length>0">
<div style="font-weight: 700">最大数量:{{ scope.row.countsInfo[0].max_total }}</div>
<div v-for="(item,index) in scope.row.countsInfo" :key="index">{{ item.name }}:{{ item.count
}}
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="end_reservation_time" label="预约截止时间" width="120" />
<!-- <el-table-column prop="time_unit" label="可用时长" width="80" /> -->
<el-table-column prop="roster_status" label="状态" width="80">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" class="ml-2" type="success"></el-tag>
<el-tag v-if="scope.row.status === 0" class="ml-2" type="danger"></el-tag>
</template>
</el-table-column>
<el-table-column prop="" label="操作" width="80">
<template #default="scope">
<el-button type="primary" @click="Add(scope.row)" size="small" style="margin-left: 10px;">修改
</el-button>
</template>
</el-table-column>
</el-table>
<!-- <div class="page">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
:page-sizes="[15, 50, 100, 200]" layout="total,sizes, prev, pager, next" :total="total"
@size-change="PageSizeChange" @current-change="PageCurrentChange" />
</div> -->
<div style="display: flex;" class="planInfo">
<div style=" border-right: 1px solid #dadada;padding-right: 4px;">
<div v-for="(item,index) in zhenShiList" :key="index" @click="zhenshiClick(item.resources_name)"
:class="{'zhenshiButton zhenshiButtonActive':item.resources_name===activeZhenShi,'zhenshiButton':item.resources_name !==activeZhenShi}">
{{item.resources_name}}
</div>
</div>
<div v-loading="loading" style="border: 1px solid #efefef;width: 100%;">
<table class="planTable" v-if="planTableData.length>0" >
<tr style="background-color: #f1f1f1;position: relative;">
<td style="width: 120px;display: flex;font-size: 12px;">
<div style="margin-left: 30px;margin-right: 6px;">全选</div>
<div :class="{'plan_checkAllbox plan_checkAllbox_active':PlanSelectedAll===1,'plan_checkAllbox ':PlanSelectedAll===0}"
@click="selectedAllPlanFunc()">
<el-icon v-if="PlanSelectedAll===1" color="#ffffff"><Select /></el-icon>
</div>
</td>
<td style="font-weight: 700;" v-for="(item,index) in xingqi">{{item.label}}</td>
</tr>
<tr v-for="(item,index) in planTableData" :key="index">
<td v-for="(item2,index2) in item" :key="index2" @mouseover="showTools(item2.id)"
@mouseleave="hideTools(item2.id)">
<span v-if="index2=='time_range'">{{item2}}</span>
<div v-if="item2.countsInfo && item2.countsInfo.length>0" :class="{'planInfo_k':item2.status==1,'planInfo_k planInfo_k_disabled':item2.status==0}">
<div v-if="hoverIndex==item2.id" class="hoverTools">
<div class="icon_k" @click="Add(item2)">
<el-icon color="#409eff" size="20">
<Edit />
</el-icon>
</div>
</div>
<div :class="{'plan_checkbox plan_checkbox_active':isSelected(item2.id),'plan_checkbox':!isSelected(item2.id)}"
@click="checkBoxCheckFunc(item2.id)">
<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}}
</div>
<div v-for="(item3,index3) in item2.countsInfo" :key="index3">
<span> {{item3.jiancheng}}</span><span>{{item3.count}} </span>
</div>
</div>
<div class="patient_type_row">
<div class="tps" v-for="(item3,index3) in item2.patient_type_label">
{{item3}}
</div>
</div>
</div>
</td>
</tr>
</table>
<div v-if="planTableData.length==0" style="width: 100%;background-color: #fff;">
<el-empty description="暂无" />
</div>
</div>
</div>
<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;">
@ -125,8 +133,8 @@
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, '')" />
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>
@ -226,8 +234,8 @@
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-switch v-model="HolidayEnable" size="large" active-text="" inactive-text="" :active-value="1"
:inactive-value="0" />
</el-form-item>
</el-form>
<template #footer>
@ -268,10 +276,14 @@
} from 'element-plus'
let CountType = ref("1"); //
let loading = ref(false)
let tableData = ref([])
let currentPage = ref(1) //
let pageSize = ref(15) //
let total = 0 //
let zhenShiList = ref([])
let activeZhenShi = ref('');
let planTableData = ref([])
let selectedPlanArr = ref([]) //id
let PlanSelectedAll = ref(0)
const PageSizeChange = (e) => { //
pageSize.value = e
GetList()
@ -280,33 +292,69 @@
currentPage.value = e
GetList()
}
let tableSelected = ref([])
const handleSelectionChange = (e) => {
tableSelected.value = e
}
let dateRange = ref([]) //
let CreatePlanDialogVisible = ref(false)
const CreatedPlanClick = () => { //
if (tableSelected.value.length === 0) {
if (selectedPlanArr.value.length === 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
CreatePlanDialogVisible.value = true;
}
const zhenshiClick = (zhenshi) => {
activeZhenShi.value = zhenshi
PlanSelectedAll.value = 0
selectedPlanArr.value = []
GetList()
}
const selectedAllPlanFunc = () => {
PlanSelectedAll.value = PlanSelectedAll.value === 0 ? 1 : 0;
if (PlanSelectedAll.value === 0) {
selectedPlanArr.value = []
}
if (PlanSelectedAll.value === 1) {
planTableData.value.forEach((v, i) => {
console.log(v)
for (let key in v) {
if (key != 'time_range') {
selectedPlanArr.value.push(v[key].id)
}
}
})
}
}
let hoverIndex = ref(null)
const showTools = (index) => {
hoverIndex.value = index
}
const hideTools = (index) => {
hoverIndex.value = null
}
const isSelected = (id) => {
return selectedPlanArr.value.includes(id)
}
const checkBoxCheckFunc = (id) => {
const index = selectedPlanArr.value.indexOf(id);
if (index === -1) {
selectedPlanArr.value.push(id);
} else {
selectedPlanArr.value = selectedPlanArr.value.filter(item => item !== id);
}
};
const CreatedPlanAction = () => { //
if (dateRange.value.length === 0) {
ElMessage.error("请选择日期范围")
return false;
}
let ids = [];
tableSelected.value.forEach((v, i) => {
ids.push(v.id)
})
CreatePlanList({
dateRange: dateRange.value,
ids: ids,
HolidayEnable:HolidayEnable.value,
date_type:searchInfo.value.date_type
ids: selectedPlanArr.value,
HolidayEnable: HolidayEnable.value,
date_type: searchInfo.value.date_type
}).then(res => {
if (res.status) {
CreatePlanDialogVisible.value = false;
@ -331,17 +379,86 @@
xingqi: null,
status: null,
})
let HolidayEnable=ref(1)
let date_type_name =ref('工作日')
let HolidayEnable = ref(1)
let date_type_name = ref('工作日')
let dialogVisible = ref(false)
const GetList = () => {
loading.value=true
PlanModelGetList({
page: currentPage.value,
pageSize: pageSize.value,
searchInfo: searchInfo.value
}).then(res => {
tableData.value = res.data.list
total = res.data.count
loading.value=false
if (res.status) {
planTableData.value = []
selectedPlanArr.value = []
let plans = res.data.list
if (plans.length > 0) {
if (activeZhenShi.value == '') activeZhenShi.value = plans[0].department_resources_name
const timeSlotsSet = new Set();
const uniqueMap = new Map();
plans.forEach((v, i) => {
if (v.department_resources_name == activeZhenShi.value) {
const timeRange =
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}`;
timeSlotsSet.add(timeRange);
}
const key = v.resources_id; //
if (!uniqueMap.has(key)) {
uniqueMap.set(key, {
resources_id: v.resources_id,
resources_name: v.department_resources_name
});
}
})
zhenShiList.value = Array.from(uniqueMap.values());
const timeSlots = Array.from(timeSlotsSet).sort(); //
// Step 2:
timeSlots.forEach(timeRange => {
const row = {
time_range: timeRange
};
xingqi.value.forEach(xingqi => {
const matchingPlan = plans.find(
v =>
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}` ===
timeRange && v.weekname === xingqi.label && v
.department_resources_name == activeZhenShi.value
);
let plan_enable = false
if (matchingPlan) {
row[xingqi.label] = {
countsInfo: matchingPlan.countsInfo,
patient_type_label: matchingPlan.patient_type_label,
status: matchingPlan.status,
id: matchingPlan.id,
resources_id:matchingPlan.resources_id
};
}else{
row[xingqi.label] = {
countsInfo: null,
patient_type_label: null,
status: null,
id: null,
resources_id:null
};
}
});
planTableData.value.push(row);
});
}
}
})
}
@ -388,6 +505,7 @@
let PlanInfo = ref(DataDefault())
const Add = (row = null) => {
devicesList.value=[]
CheckedAll.value = false
dialogVisible.value = true
PlanInfo.value = DataDefault()
@ -406,9 +524,9 @@
}
}
const DateTypeChange=()=>{
if(searchInfo.value.date_type==1) date_type_name.value='工作日'
if(searchInfo.value.date_type==2) date_type_name.value='节假日'
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 = () => {
@ -433,7 +551,7 @@
.then(() => {
loading.value = true
PlanModelSave({
date_type:searchInfo.value.date_type,
date_type: searchInfo.value.date_type,
planInfo: PlanInfo.value
}).then(res => {
loading.value = false
@ -448,14 +566,11 @@
}
const Del = () => {
if (tableSelected.value.length == 0) {
if (selectedPlanArr.value.length == 0) {
ElMessage.error("请至少勾选1条记录")
return false
}
let ids = []
tableSelected.value.map((item) => {
ids.push(item.id)
})
ElMessageBox.confirm(
'确定删除吗?',
'提示', {
@ -466,7 +581,7 @@
).then(() => {
loading.value = true
PlanModelDel({
ids: ids
ids: selectedPlanArr.value
}).then(res => {
loading.value = false
if (res.status) {
@ -581,7 +696,9 @@
let TimePeriodList = ref([])
const GetEnableTimePeriod = () => {
loading.value = true
TimePeriodGetEnableList({date_type:searchInfo.value.date_type}).then(res => {
TimePeriodGetEnableList({
date_type: searchInfo.value.date_type
}).then(res => {
loading.value = false
if (res.status) {
TimePeriodList.value = res.data
@ -700,60 +817,7 @@
PlanInfo.value.xingqi = []
}
}
//
let bb_countRowspan = 1;
const arraySpanMethod = ({
row,
column,
rowIndex,
columnIndex,
}) => {
const fields = ['weekname']
const cellValue = row[column.property]
let countRowspan = 1
if (cellValue && fields.includes(column.property)) {
const prevRow = tableData.value[rowIndex - 1]
let nextRow = tableData.value[rowIndex + 1]
if (prevRow && prevRow[column.property] === cellValue && prevRow.declareRegion == row.declareRegion) {
bb_countRowspan = countRowspan
return {
rowspan: 0,
colspan: 0
}
} else {
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
}
}
}
}
// 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
@ -764,7 +828,7 @@
}
}
//
const TimeLongChange=(timelong)=>{
const TimeLongChange = (timelong) => {
if (CountType.value == 2) { //
if (PlanInfo.value.begin_time == '' || PlanInfo.value.end_time == '') {
ElMessage.error("请先设置时段")
@ -776,31 +840,31 @@
}
//
const ComPuteCountByTime = (timelong) => {
let count=calculateTimeSegments(PlanInfo.value.begin_time,PlanInfo.value.end_time,timelong)
PlanInfo.value.max_total=count
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;
//
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
searchInfo.value.date_type = 1
GetList()
GetDepartmentEnableList()
getEnableResource()
@ -810,7 +874,7 @@
})
</script>
<style scoped>
<style lang="scss" scoped>
.type_count {
display: flex;
}
@ -831,4 +895,168 @@
.hongzi {
color: #b25252;
}
.planInfo {
.planTable {
width: 100%;
background-color: #fff;
text-align: center;
border: 1px solid #f1f1f1;
border-collapse: collapse;
/* 合并边框 */
color: #333;
td {
border: 1px solid #f1f1f1;
// padding: 6px;
}
}
.table_plan_row td:first-child {
background-color: #f1f1f1;
border-bottom: 1px solid #e8e8e8;
}
.table_plan_row> :not(:first-child):hover {
background-color: #aeebf0;
cursor: pointer;
color: #fff;
}
.planActive {
background-color: #5bc0de;
color: #fff;
}
.plandisable {
pointer-events: none;
opacity: 0.4;
}
.shuxian {
border-left: 1px solid #dfdfdf;
margin-left: 40px;
margin-right: 40px;
}
.do_button {
width: 100px;
}
}
.zhenshiButton {
width: 150px;
line-height: 36px;
height: 36px;
border: 1px solid #e8e8e8;
text-align: center;
margin-top: 4px;
border-radius: 4px;
cursor: default;
}
.zhenshiButtonActive {
background-color: #5bc0de;
color: #fff;
}
.planInfo_k_disabled{
background-color: #ffd6d2;
}
.planInfo_k {
font-size: 14px;
color: #333;
position: relative;
padding-top: 18px;
padding-bottom: 10px;
.plan_checkbox {
position: absolute;
top: 2px;
left: 2px;
height: 16px;
width: 16px;
border: 1px solid #98c4cc;
border-radius: 4px;
}
.plan_checkbox_active {
background-color: #409eff;
justify-content: center;
align-items: center;
display: flex;
}
.qudao_count_row {
display: flex;
div {
margin-left: 6px;
}
.qudao_title_zong {
font-weight: 700;
span {
font-weight: 700;
}
}
}
.patient_type_row {
display: flex;
margin-top: 4px;
justify-content: center;
.tps {
background-color: #ebfff4;
border: 1px solid #9fdebc;
color: #83b69a;
font-size: 12px;
padding: 1px 2px;
border-radius: 4px;
margin-left: 4px;
}
}
.hoverTools {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
border-radius: 4px;
.icon_k {
height: 30px;
width: 30px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ccc;
background-color: #fff;
}
}
}
.plan_checkAllbox {
height: 20px;
width: 20px;
border: 1px solid #7cccc7;
border-radius: 4px;
}
.plan_checkAllbox_active {
background-color: #409eff;
justify-content: center;
align-items: center;
display: flex;
}
</style>

@ -4,7 +4,7 @@
<el-header>
<el-row>
<el-col :span="3" class="logo" style="min-width: 250px;">
<div><img :src="configInfo.站点图片"/></div>
<div><img :src="configInfo.站点图片" /></div>
<div>
<div style="font-size: 16px;">秦皇岛市中医医院</div>
<div>{{configInfo.站点名称}}</div>
@ -27,23 +27,45 @@
inactive-action-icon="Sunny" @change="toggleDark" />
</div>
<div>
<el-popover placement="bottom" :width="150" trigger="hover">
<template #reference>
<div class="top_user">
<div style="margin-top: 7px;">
<el-avatar :size="40" :src="BaseUserInfo.img" />
<div class="top_user">
<div style="margin-top: 7px;">
<el-avatar :size="40" :src="BaseUserInfo.img" />
</div>
<div v-if="BaseUserInfo.cn_name">
<el-dropdown @command="DepartmentHandleCommand">
<span class="el-dropdown-link">
{{BaseUserInfo.department_name}}
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="(d_item,d_index) in BaseUserInfo.department_info"
:key="d_index" :command="d_item.id">
{{d_item.department_name}}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-popover placement="bottom" :width="150" trigger="hover">
<template #reference>
<div style="font-size: 14px;">{{BaseUserInfo.cn_name}}</div>
</template>
<div style="display: flex; cursor: pointer;" @click="to('login')">
<div style="margin-top: 2px;margin-right: 5px;"><el-icon>
<SwitchButton />
</el-icon> </div>
<div> 退出</div>
</div>
<div>{{BaseUserInfo.cn_name}}</div>
</div>
</template>
<div style="display: flex; cursor: pointer;" @click="to('login')">
<div style="margin-top: 2px;margin-right: 5px;"><el-icon>
<SwitchButton />
</el-icon> </div>
<div> 退出</div>
</el-popover>
</div>
</el-popover>
</div>
</div>
</el-col>
@ -52,8 +74,8 @@
</el-header>
<el-container>
<el-aside>
<el-menu class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :default-active="activeMenu"
:collapse="isCollapse" >
<el-menu class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"
:default-active="activeMenu" :collapse="isCollapse">
<el-menu-item index="2-222" @click="to('dashboard')" style="display: none;">
<el-icon>
<Menu />
@ -112,7 +134,8 @@
<script setup>
import {
ref,
onMounted,watch
onMounted,
watch
} from 'vue';
import {
usePinia
@ -120,7 +143,7 @@
import {
GetAdminBaseMenuList,
GetBaseAdminUserInfo,
GetConfigInfo
GetConfigInfo,ChangeDefaultDept
} from '@/api/api.js'
import {
useToggle
@ -128,18 +151,21 @@
import {
useDark
} from "@vueuse/core";
import userjpg from '@/assets/user.jpg'
import userjpg from '@/assets/user.jpg'
import { useRoute,useRouter } from "vue-router"
import {
useRoute,
useRouter
} from "vue-router"
const route = useRoute()
const router = useRouter()
watch(()=>router.currentRoute.value,(newVal,oldVal)=>{
activeMenu.value=newVal.path
console.log( activeMenu.value)
})
watch(() => router.currentRoute.value, (newVal, oldVal) => {
activeMenu.value = newVal.path
console.log(activeMenu.value)
})
const isDark = useDark()
@ -156,11 +182,11 @@ watch(()=>router.currentRoute.value,(newVal,oldVal)=>{
}
const to = (url) => {
if(url=='login'){
sessionStorage.clear()
if (url == 'login') {
sessionStorage.clear()
}
console.log(url)
activeMenu.value=url
activeMenu.value = url
window.location.href = "./#/" + url
}
const menuList = () => { //
@ -185,7 +211,7 @@ watch(()=>router.currentRoute.value,(newVal,oldVal)=>{
})
menuFuList.value = fulist
console.log(menuFuList.value)
})
}
let BaseUserInfo = ref({
@ -194,39 +220,48 @@ watch(()=>router.currentRoute.value,(newVal,oldVal)=>{
const getBaseAdminUserInfo = () => {
GetBaseAdminUserInfo().then(res => {
BaseUserInfo.value = res.info[0]
sessionStorage.setItem('LoginUserInfo',JSON.stringify(res.info[0]))
BaseUserInfo.value.img=import.meta.env.VITE_APP_FILE+BaseUserInfo.value.img
sessionStorage.setItem('LoginUserInfo', JSON.stringify(res.info[0]))
BaseUserInfo.value.img = import.meta.env.VITE_APP_FILE + BaseUserInfo.value.img
console.log(route.path)
let BingQu=[2]; //
let QiTa=[3]; //
let Guanli=[1,5];//
if(QiTa.includes(res.info[0].group) && route.path=='/dashboard'){
let BingQu = [2]; //
let QiTa = [3]; //
let Guanli = [1, 5]; //
if (QiTa.includes(res.info[0].group) && route.path == '/dashboard') {
window.location.href = "./#/yewu/mainList"
}
if(BingQu.includes(res.info[0].group) && route.path=='/dashboard'){
if (BingQu.includes(res.info[0].group) && route.path == '/dashboard') {
window.location.href = "./#/yewu/MainList_ZhuYuan"
}
if(Guanli.includes(res.info[0].group) && route.path=='/dashboard'){
if (Guanli.includes(res.info[0].group) && route.path == '/dashboard') {
window.location.href = "./#/yewu/departmentResources"
}
})
}
let configInfo=ref('');
const GetConfig=()=>{
let configInfo = ref('');
const GetConfig = () => {
GetConfigInfo().then(res => {
if(res.status){
configInfo.value=res.data
configInfo.value.站点图片=import.meta.env.VITE_APP_FILE+configInfo.value.站点图片
}
if (res.status) {
configInfo.value = res.data
configInfo.value.站点图片 = import.meta.env.VITE_APP_FILE + configInfo.value.站点图片
}
})
}
let activeMenu=ref('');
const DepartmentHandleCommand = (e) => {
ChangeDefaultDept({deptid:e}).then(res => {
if (res.status) {
location.reload();
}
})
}
let activeMenu = ref('');
onMounted(() => {
menuList()
GetConfig()
getBaseAdminUserInfo()
activeMenu.value=router.currentRoute.value.path
activeMenu.value = router.currentRoute.value.path
})
</script>
@ -331,7 +366,8 @@ watch(()=>router.currentRoute.value,(newVal,oldVal)=>{
font-weight: 700;
color: var(--color-text);
}
.logo img{
.logo img {
margin-top: 10px;
margin-right: 10px;
width: 40px;

@ -21,6 +21,8 @@
<el-input v-model="searchInfo.name" placeholder="请输入检查项目名称" style="margin-left: 10px;" />
</el-form-item>
<el-button type="primary" @click="GetItemList()" style="margin-left: 10px;">查询</el-button>
<el-button type="warning" @click="GetHisItemClass()" style="margin-left: 10px; margin-left: 40px;">同步分类</el-button>
<el-button type="warning" @click="GetHisCheckItem()" style="margin-left: 10px;">同步检查项目</el-button>
</el-row>
</div>
<el-table :data="tableData" style="width: 100%;" row-key="id">
@ -230,7 +232,9 @@
SaveItemInfo,
SetHuChi,
DelHuChi,
GetHuChiList
GetHuChiList,
UpdateHisItemClass,
updateHisCheckItem
} from '@/api/api.js'
import {
ElMessage,
@ -577,6 +581,60 @@
})
}
//his
const GetHisItemClass=()=>{
ElMessageBox.confirm(
'确定从his同步分类吗',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
loading.value = true
UpdateHisItemClass().then(res => {
loading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
GetItemClassList();
} else {
ElMessage.error(res.msg)
}
})
})
}
//his
const GetHisCheckItem=()=>{
ElMessageBox.confirm(
'确定从his同步检查项目吗',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
loading.value = true
updateHisCheckItem({termClassId:155}).then(res => {
loading.value = false
if (res.status) {
ElMessage({
message: res.msg,
type: 'success',
})
GetItemList();
} else {
ElMessage.error(res.msg)
}
})
})
}
onMounted(() => {
GetItemClassList()
GetDeviceList()

@ -34,8 +34,9 @@
// episode_id.value='111043531'
// appointment_type.value=4
// dotype.value=1
console.log(route.query.regnum)
reg_num.value=decodeURIComponent(route.query.regnum)
console.log(reg_num.value)
entrust_ids.value=decodeURIComponent(route.query.entrustid)
episode_id.value=decodeURIComponent(route.query.episodeid)
appointment_type.value=4

Loading…
Cancel
Save