权益生成待办功能完成
This commit is contained in:
parent
8daf6ce4e5
commit
1e0cd71432
@ -368,6 +368,16 @@ function markDone() {
|
||||
const result = String(form.result || '').trim() || '已完成';
|
||||
const r = await api('setTodoStatus', { corpId, id: taskId.value, eventStatus: 'treated', result, userId, todoMethod: methodValue });
|
||||
if (!r?.success) return toast(r?.message || '操作失败');
|
||||
if (todo.value?.benefitDeductOnComplete && todo.value?.benefitRecordId) {
|
||||
const deductRes = await api('completeBenefitTodo', {
|
||||
corpId,
|
||||
todoId: taskId.value,
|
||||
treatmentRecordId: todo.value.benefitRecordId,
|
||||
executorUserId: userId,
|
||||
completedAt: Date.now(),
|
||||
});
|
||||
if (!deductRes?.success) return toast(deductRes?.message || '待办已完成,但权益自动核销失败');
|
||||
}
|
||||
toast('操作成功');
|
||||
uni.$emit('archive-detail:followup-changed');
|
||||
setTimeout(() => uni.navigateBack(), 300);
|
||||
|
||||
@ -83,6 +83,17 @@
|
||||
<view class="field-label">有效期</view>
|
||||
<view class="valid-time-picker" @tap="prepareValidTimePicker(projectEntry)"><picker mode="multiSelector" :range="validTimeRange" :value="validTimeIndex" @columnchange="onValidTimeColumnChange" @change="changeValidTime($event, projectEntry)"><view class="picker-value value-text">{{ projectEntry.validTime }}</view></picker></view>
|
||||
</view>
|
||||
<view v-if="projectEntry.selected" class="todo-switch-row">
|
||||
<text>生成待办</text>
|
||||
<switch :checked="projectEntry.todoEnabled" color="#0877f1" @change="toggleTodo($event, projectEntry)" />
|
||||
</view>
|
||||
<view v-if="projectEntry.selected && projectEntry.todoEnabled" class="todo-config-card">
|
||||
<input v-model="projectEntry.todoConfig.taskContent" class="todo-input" placeholder="任务内容" />
|
||||
<picker :range="todoTypeOptions" range-key="label" @change="changeTodoType($event, projectEntry)"><view class="project-input"><text>类型:{{ getTodoTypeLabel(projectEntry.todoConfig.eventType) }}</text><uni-icons type="right" size="16" color="#999" /></view></picker>
|
||||
<view class="field-row"><view class="field-block"><view class="field-label">回访日期</view><view class="valid-time-picker" @tap="prepareTodoDatePicker(projectEntry, 'planDate')"><picker mode="multiSelector" :range="validTimeRange" :value="validTimeIndex" @columnchange="onValidTimeColumnChange" @change="changeTodoDate($event)"><view class="picker-value value-text">{{ projectEntry.todoConfig.planDate }}</view></picker></view></view><view class="field-block"><view class="field-label">截止日期</view><view class="valid-time-picker" @tap="prepareTodoDatePicker(projectEntry, 'expireDate')"><picker mode="multiSelector" :range="validTimeRange" :value="validTimeIndex" @columnchange="onValidTimeColumnChange" @change="changeTodoDate($event)"><view class="picker-value value-text">{{ projectEntry.todoConfig.expireDate }}</view></picker></view></view></view>
|
||||
<view class="project-input" @tap="openTodoExecutorPicker(projectEntry)"><text :class="projectEntry.todoConfig.executorUserId ? 'value-text' : 'placeholder-text'">{{ projectEntry.todoConfig.executorName || '请选择团队和处理人' }}</text><uni-icons type="right" size="16" color="#999" /></view>
|
||||
<view class="todo-deduct-row"><text>完成关联核销权益</text><switch :checked="projectEntry.todoConfig.deductBenefit" color="#0877f1" @change="projectEntry.todoConfig.deductBenefit = $event.detail.value" /></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="remove-entry" @click="removeEntry(index)">删除套餐</view>
|
||||
</template>
|
||||
@ -185,6 +196,17 @@
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view v-if="entry.project?._id" class="todo-switch-row">
|
||||
<text>生成待办</text>
|
||||
<switch :checked="entry.todoEnabled" color="#0877f1" @change="toggleTodo($event, entry)" />
|
||||
</view>
|
||||
<view v-if="entry.project?._id && entry.todoEnabled" class="todo-config-card">
|
||||
<input v-model="entry.todoConfig.taskContent" class="todo-input" placeholder="任务内容" />
|
||||
<picker :range="todoTypeOptions" range-key="label" @change="changeTodoType($event, entry)"><view class="project-input"><text>类型:{{ getTodoTypeLabel(entry.todoConfig.eventType) }}</text><uni-icons type="right" size="16" color="#999" /></view></picker>
|
||||
<view class="field-row"><view class="field-block"><view class="field-label">回访日期</view><view class="valid-time-picker" @tap="prepareTodoDatePicker(entry, 'planDate')"><picker mode="multiSelector" :range="validTimeRange" :value="validTimeIndex" @columnchange="onValidTimeColumnChange" @change="changeTodoDate($event)"><view class="picker-value value-text">{{ entry.todoConfig.planDate }}</view></picker></view></view><view class="field-block"><view class="field-label">截止日期</view><view class="valid-time-picker" @tap="prepareTodoDatePicker(entry, 'expireDate')"><picker mode="multiSelector" :range="validTimeRange" :value="validTimeIndex" @columnchange="onValidTimeColumnChange" @change="changeTodoDate($event)"><view class="picker-value value-text">{{ entry.todoConfig.expireDate }}</view></picker></view></view></view>
|
||||
<view class="project-input" @tap="openTodoExecutorPicker(entry)"><text :class="entry.todoConfig.executorUserId ? 'value-text' : 'placeholder-text'">{{ entry.todoConfig.executorName || '请选择团队和处理人' }}</text><uni-icons type="right" size="16" color="#999" /></view>
|
||||
<view class="todo-deduct-row"><text>完成关联核销权益</text><switch :checked="entry.todoConfig.deductBenefit" color="#0877f1" @change="entry.todoConfig.deductBenefit = $event.detail.value" /></view>
|
||||
</view>
|
||||
|
||||
<view class="field-group">
|
||||
<view class="field-label">计划治疗医生</view>
|
||||
@ -211,6 +233,22 @@
|
||||
<text>添加权益项目</text>
|
||||
</view>
|
||||
|
||||
<view v-if="todoExecutorPickerVisible" class="picker-mask" @click="closeTodoExecutorPicker">
|
||||
<view class="todo-executor-picker" @click.stop>
|
||||
<view class="picker-header"><text class="picker-title">请选择团队和处理人</text><uni-icons type="closeempty" size="22" color="#666" @click="closeTodoExecutorPicker" /></view>
|
||||
<scroll-view scroll-y class="todo-executor-list">
|
||||
<view v-for="team in todoTeams" :key="team.teamId" class="todo-team-group">
|
||||
<view class="todo-team-title">{{ team.name }}</view>
|
||||
<view v-for="member in getTodoExecutorsForTeam(team)" :key="member.userid" class="todo-executor-item" @tap="selectTodoExecutor(member, team)">
|
||||
<text>{{ member.name }}</text><text v-if="isSelectedTodoExecutor(member, team)" class="todo-selected">已选择</text>
|
||||
</view>
|
||||
<view v-if="!getTodoExecutorsForTeam(team).length" class="todo-empty">暂无团队成员</view>
|
||||
</view>
|
||||
<view v-if="!todoTeams.length" class="todo-empty">暂无可选团队</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="projectPickerVisible" class="picker-mask" @click="closeProjectPicker">
|
||||
<view class="project-picker" @click.stop>
|
||||
<view class="picker-header">
|
||||
@ -254,11 +292,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, ref } from "vue";
|
||||
import { computed, nextTick, ref } from "vue";
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import api from "@/utils/api.js";
|
||||
import useAccountStore from "@/store/account.js";
|
||||
import fullPage from "@/components/full-page.vue";
|
||||
import { TODO_EVENT_TYPE_LABELS } from "@/utils/todo-const.js";
|
||||
|
||||
const PENDING_FOLLOWUP_SEND_STORAGE_KEY = "ykt_followup_pending_send";
|
||||
|
||||
@ -287,6 +326,12 @@ const projectPageSize = 30;
|
||||
const VALID_YEAR_SPAN = 50;
|
||||
const validTimeRange = ref([[], [], []]);
|
||||
const validTimeIndex = ref([0, 0, 0]);
|
||||
const todoDateTarget = ref(null);
|
||||
const teamMembers = ref([]);
|
||||
const todoTeams = ref([]);
|
||||
const todoExecutorPickerVisible = ref(false);
|
||||
const todoExecutorTarget = ref(null);
|
||||
const todoTypeOptions = Object.entries(TODO_EVENT_TYPE_LABELS).map(([value, label]) => ({ value, label }));
|
||||
let searchTimer = null;
|
||||
let entryKey = 0;
|
||||
|
||||
@ -397,6 +442,8 @@ function createEntry() {
|
||||
dept: null,
|
||||
treatmentDoctorUserId: "",
|
||||
treatmentDoctorName: "",
|
||||
todoEnabled: false,
|
||||
todoConfig: null,
|
||||
};
|
||||
}
|
||||
|
||||
@ -419,6 +466,7 @@ onLoad((options = {}) => {
|
||||
loadTeamContext().then(() => {
|
||||
loadCorpSettings();
|
||||
loadStaffList();
|
||||
loadTodoTeams();
|
||||
});
|
||||
});
|
||||
|
||||
@ -428,6 +476,9 @@ async function loadTeamContext() {
|
||||
const res = await api("getTeamData", { teamId: teamId.value, corpId: corpId.value }, false);
|
||||
const team = res?.data || {};
|
||||
if (team.corpId && team.corpId !== corpId.value) corpId.value = team.corpId;
|
||||
teamMembers.value = Array.isArray(team.memberList) ? team.memberList.map((member) => (
|
||||
typeof member === "string" ? { userid: member, name: member } : member
|
||||
)) : [];
|
||||
} catch (error) {
|
||||
console.error("加载服务团队失败", error);
|
||||
}
|
||||
@ -441,12 +492,41 @@ async function loadStaffList() {
|
||||
staffList.value = Array.isArray(list)
|
||||
? list.filter((staff) => staff?.userid).map((staff) => ({ ...staff, anotherName: staff.anotherName || staff.name || staff.userid }))
|
||||
: [];
|
||||
const staffMap = new Map(staffList.value.map((staff) => [staff.userid, staff]));
|
||||
teamMembers.value = teamMembers.value.map((member) => ({ ...member, ...(staffMap.get(member.userid) || {}) }));
|
||||
todoTeams.value = todoTeams.value.map((team) => ({
|
||||
...team,
|
||||
memberList: (team.memberList || []).map((member) => {
|
||||
const userid = typeof member === "string" ? member : member?.userid;
|
||||
return { ...(typeof member === "object" ? member : {}), ...(staffMap.get(userid) || {}), userid };
|
||||
}),
|
||||
}));
|
||||
} catch (error) {
|
||||
staffList.value = [];
|
||||
console.error("加载机构员工失败", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTodoTeams() {
|
||||
const userId = accountStore.doctorInfo?.userid || accountStore.account?.userid || "";
|
||||
if (!corpId.value || !userId) return;
|
||||
try {
|
||||
const res = await api("getTeamBymember", { corpId: corpId.value, corpUserId: userId }, false);
|
||||
const list = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
|
||||
const baseTeams = list.length ? list : [{ teamId: teamId.value, name: teamName.value, memberList: teamMembers.value }];
|
||||
const details = await Promise.all(baseTeams.map(async (team) => {
|
||||
const currentTeamId = team.teamId || team._id || team.id;
|
||||
if (!currentTeamId) return null;
|
||||
const detailRes = await api("getTeamData", { corpId: corpId.value, teamId: currentTeamId }, false);
|
||||
const detail = detailRes?.data || {};
|
||||
return { teamId: currentTeamId, name: detail.name || team.name || team.teamName || "未命名团队", memberList: detail.memberList || team.memberList || [] };
|
||||
}));
|
||||
todoTeams.value = details.filter(Boolean);
|
||||
} catch (error) {
|
||||
todoTeams.value = teamId.value ? [{ teamId: teamId.value, name: teamName.value, memberList: teamMembers.value }] : [];
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCorpSettings() {
|
||||
if (!corpId.value) return;
|
||||
try {
|
||||
@ -627,6 +707,7 @@ function createPackageProjectEntry(project = {}, packageItem = {}) {
|
||||
project: normalizedProject,
|
||||
price: Number(normalizedProject.price ?? project.price ?? 0),
|
||||
usageCount: Number(project.number || 1),
|
||||
packageUnitUsageCount: Number(project.number || 1),
|
||||
discount: packageItem.packageType === "free" ? 10 : Number(project.discount || 10),
|
||||
totalPrice: Number(project.totalPrice || 0),
|
||||
selected: packageItem.packageType === "fixed" || project.required === true,
|
||||
@ -694,6 +775,7 @@ function togglePackageProject(entry, projectEntry) {
|
||||
return;
|
||||
}
|
||||
projectEntry.selected = !projectEntry.selected;
|
||||
if (projectEntry.selected) projectEntry.usageCount = Number(entry.usageCount || 1) * Number(projectEntry.packageUnitUsageCount || 1);
|
||||
syncPackageSelection(entry);
|
||||
syncPackageTotals(entry);
|
||||
}
|
||||
@ -702,9 +784,103 @@ function calculatePackageTotal(entry) {
|
||||
entry.usageCount = Math.max(1, Number(entry.usageCount || 1));
|
||||
entry.discount = clampNumber(toNumber(entry.discount, 10), 0, 10);
|
||||
entry.totalPrice = toFixedNumber(Number(entry.price || 0) * entry.usageCount * entry.discount / 10, 2);
|
||||
entry.projects.filter((project) => project.selected).forEach((project) => {
|
||||
project.usageCount = entry.usageCount * Number(project.packageUnitUsageCount || 1);
|
||||
});
|
||||
syncPackageTotals(entry);
|
||||
}
|
||||
|
||||
function getDefaultTodoConfig(entry) {
|
||||
const planDate = formatDate(new Date());
|
||||
return {
|
||||
taskContent: entry.project?.projectName || "",
|
||||
eventType: "benefitExecution",
|
||||
planDate,
|
||||
expireDate: entry.validTime || formatDate(new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)),
|
||||
executorUserId: "",
|
||||
executorName: "",
|
||||
executeTeamId: "",
|
||||
executeTeamName: "",
|
||||
deductBenefit: false,
|
||||
};
|
||||
}
|
||||
|
||||
function toggleTodo(event, entry) {
|
||||
entry.todoEnabled = Boolean(event.detail.value);
|
||||
if (entry.todoEnabled) entry.todoConfig = entry.todoConfig || getDefaultTodoConfig(entry);
|
||||
}
|
||||
|
||||
function getTodoTypeLabel(value) {
|
||||
return TODO_EVENT_TYPE_LABELS[value] || "请选择类型";
|
||||
}
|
||||
|
||||
function changeTodoType(event, entry) {
|
||||
entry.todoConfig.eventType = todoTypeOptions[Number(event.detail.value)]?.value || "benefitExecution";
|
||||
}
|
||||
|
||||
function getTodoExecutors(entry) {
|
||||
const team = todoTeams.value.find((item) => String(item.teamId) === String(entry.todoConfig?.executeTeamId));
|
||||
return (team?.memberList || []).map((member) => {
|
||||
const userid = typeof member === "string" ? member : member?.userid;
|
||||
const staff = staffList.value.find((item) => item.userid === userid);
|
||||
return { userid, name: staff?.anotherName || staff?.name || member?.anotherName || member?.name || userid };
|
||||
}).filter((member) => member.userid);
|
||||
}
|
||||
|
||||
function openTodoExecutorPicker(entry) {
|
||||
todoExecutorTarget.value = entry;
|
||||
todoExecutorPickerVisible.value = true;
|
||||
}
|
||||
|
||||
function closeTodoExecutorPicker() {
|
||||
todoExecutorPickerVisible.value = false;
|
||||
todoExecutorTarget.value = null;
|
||||
}
|
||||
|
||||
function getTodoExecutorsForTeam(team) {
|
||||
return (team?.memberList || []).map((member) => {
|
||||
const userid = typeof member === "string" ? member : member?.userid;
|
||||
const staff = staffList.value.find((item) => item.userid === userid);
|
||||
return { userid, name: staff?.anotherName || staff?.name || member?.anotherName || member?.name || userid };
|
||||
}).filter((member) => member.userid);
|
||||
}
|
||||
|
||||
function selectTodoExecutor(member, team) {
|
||||
const entry = todoExecutorTarget.value;
|
||||
if (!entry?.todoConfig) return;
|
||||
entry.todoConfig.executeTeamId = team.teamId;
|
||||
entry.todoConfig.executeTeamName = team.name;
|
||||
entry.todoConfig.executorUserId = member.userid;
|
||||
entry.todoConfig.executorName = member.name;
|
||||
closeTodoExecutorPicker();
|
||||
}
|
||||
|
||||
function isSelectedTodoExecutor(member, team) {
|
||||
const config = todoExecutorTarget.value?.todoConfig;
|
||||
return config?.executeTeamId === team.teamId && config?.executorUserId === member.userid;
|
||||
}
|
||||
|
||||
function prepareTodoDatePicker(entry, field) {
|
||||
todoDateTarget.value = { entry, field };
|
||||
prepareValidTimePicker({ validTime: entry.todoConfig[field] });
|
||||
}
|
||||
|
||||
function changeTodoDate(event) {
|
||||
const target = todoDateTarget.value;
|
||||
if (!target) return;
|
||||
const [yearIndex, monthIndex, dayIndex] = event.detail.value || validTimeIndex.value;
|
||||
const year = Number(validTimeRange.value[0][yearIndex].replace("年", ""));
|
||||
const month = Number(validTimeRange.value[1][monthIndex].replace("月", ""));
|
||||
const day = Number(validTimeRange.value[2][dayIndex].replace("日", ""));
|
||||
const selectedDate = `${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
||||
target.entry.todoConfig[target.field] = selectedDate;
|
||||
validTimeIndex.value = [yearIndex, monthIndex, dayIndex];
|
||||
if (target.field === "planDate" && !target.entry.validTime) {
|
||||
target.entry.todoConfig.expireDate = formatDate(new Date(new Date(`${target.entry.todoConfig.planDate}T00:00:00`).getTime() + 7 * 24 * 60 * 60 * 1000));
|
||||
}
|
||||
todoDateTarget.value = null;
|
||||
}
|
||||
|
||||
function syncPackageTotals(entry) {
|
||||
const selected = entry.projects.filter((item) => item.selected);
|
||||
const baseTotal = selected.reduce((sum, item) => sum + Number(item.price || 0) * Number(item.usageCount || 1), 0);
|
||||
@ -794,6 +970,8 @@ function validateEntries() {
|
||||
for (const projectEntry of selectedProjects) {
|
||||
if (!projectEntry.dept?._id) return `${projectEntry.project.projectName}请选择治疗科室`;
|
||||
if (projectEntry.hasValidDays && !projectEntry.validTime) return `${projectEntry.project.projectName}请选择有效日期`;
|
||||
const todoError = validateTodo(projectEntry);
|
||||
if (todoError) return todoError;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -804,11 +982,82 @@ function validateEntries() {
|
||||
if (!Number.isFinite(Number(entry.totalPrice)) || Number(entry.totalPrice) < 0) return `${label}总价不能小于0`;
|
||||
if (!Number(entry.usageCount) || Number(entry.usageCount) <= 0) return `${label}数量必须大于0`;
|
||||
if (!entry.dept?._id) return `${label}请选择治疗科室`;
|
||||
const todoError = validateTodo(entry);
|
||||
if (todoError) return todoError;
|
||||
}
|
||||
if (!patientId.value) return "当前会话缺少患者档案关联";
|
||||
return "";
|
||||
}
|
||||
|
||||
function validateTodo(entry) {
|
||||
if (!entry.todoEnabled) return "";
|
||||
const config = entry.todoConfig || {};
|
||||
if (!String(config.taskContent || "").trim()) return `${entry.project?.projectName || "权益项目"}请填写待办内容`;
|
||||
if (!config.eventType) return `${entry.project?.projectName || "权益项目"}请选择待办类型`;
|
||||
if (!config.planDate || !config.expireDate || config.expireDate < config.planDate) return `${entry.project?.projectName || "权益项目"}待办日期不正确`;
|
||||
if (!config.executeTeamId) return `${entry.project?.projectName || "权益项目"}请选择处理团队`;
|
||||
if (!config.executorUserId) return `${entry.project?.projectName || "权益项目"}请选择待办处理人`;
|
||||
return "";
|
||||
}
|
||||
|
||||
function getResponseId(data) {
|
||||
if (typeof data === "string") return data;
|
||||
if (!data || typeof data !== "object") return "";
|
||||
return data._id || data.id || getResponseId(data.data);
|
||||
}
|
||||
|
||||
async function linkBenefitTodos(entry, treatmentRecordId, userId) {
|
||||
if (!entry.todoEnabled) return;
|
||||
const config = entry.todoConfig;
|
||||
const todoIds = [];
|
||||
const quantity = Math.max(1, Number(entry.usageCount || 1));
|
||||
for (let sequence = 1; sequence <= quantity; sequence += 1) {
|
||||
const res = await api("createTodo", {
|
||||
corpId: corpId.value,
|
||||
params: {
|
||||
corpId: corpId.value,
|
||||
customerId: patientId.value,
|
||||
customerName: patientName.value,
|
||||
taskContent: String(config.taskContent).trim(),
|
||||
eventType: config.eventType,
|
||||
eventStatus: "untreated",
|
||||
executeMethod: "todo",
|
||||
plannedExecutionTime: new Date(`${config.planDate}T00:00:00`).getTime(),
|
||||
expireTime: new Date(`${config.expireDate}T23:59:59`).getTime(),
|
||||
executorUserId: config.executorUserId,
|
||||
executeTeamId: config.executeTeamId,
|
||||
executeTeamName: config.executeTeamName,
|
||||
creatorUserId: userId,
|
||||
benefitRecordId: treatmentRecordId,
|
||||
benefitProjectId: entry.project._id,
|
||||
benefitUsageCount: 1,
|
||||
benefitTotalUsageCount: quantity,
|
||||
taskQuantity: 1,
|
||||
taskSequence: sequence,
|
||||
benefitDeductOnComplete: Boolean(config.deductBenefit),
|
||||
},
|
||||
}, false);
|
||||
if (!res?.success) throw new Error(res?.message || "待办生成失败");
|
||||
const todoId = getResponseId(res?.data || res);
|
||||
if (!todoId) throw new Error("待办生成成功但未返回待办ID");
|
||||
todoIds.push(todoId);
|
||||
}
|
||||
const updateRes = await api("updateTreatmentRecord", {
|
||||
corpId: corpId.value,
|
||||
id: treatmentRecordId,
|
||||
params: {
|
||||
benefitTodoId: todoIds[0],
|
||||
benefitTodoIds: todoIds,
|
||||
benefitTodoConfig: {
|
||||
benefitDeductOnComplete: Boolean(config.deductBenefit),
|
||||
plannedExecutionTime: new Date(`${config.planDate}T00:00:00`).getTime(),
|
||||
expireTime: new Date(`${config.expireDate}T23:59:59`).getTime(),
|
||||
},
|
||||
},
|
||||
}, false);
|
||||
if (!updateRes?.success) throw new Error(updateRes?.message || "权益待办关联失败");
|
||||
}
|
||||
|
||||
function buildBenefitMessage(createdEntries) {
|
||||
const items = createdEntries.map((entry) => ({
|
||||
projectId: entry.project._id,
|
||||
@ -907,8 +1156,11 @@ async function submitEntries() {
|
||||
teamId: teamId.value,
|
||||
corpId: corpId.value,
|
||||
};
|
||||
const res = await api("addTreatmentRecord", { userId, operationSource: "wxApp", params: treatmentData }, false);
|
||||
const res = await api("addTreatmentRecord", { corpId: corpId.value, userId, operationSource: "wxApp", params: treatmentData }, false);
|
||||
if (!res?.success) throw new Error(res?.message || "权益录入失败");
|
||||
const treatmentRecordId = getResponseId(res?.data || res);
|
||||
if (!treatmentRecordId) throw new Error("权益录入成功但未返回权益记录ID");
|
||||
await linkBenefitTodos(entry, treatmentRecordId, userId);
|
||||
createdEntries.push(entry);
|
||||
}
|
||||
queueBenefitMessage(createdEntries);
|
||||
@ -1107,6 +1359,93 @@ async function submitEntries() {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.todo-switch-row,
|
||||
.todo-deduct-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 20rpx;
|
||||
color: #374151;
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.todo-config-card {
|
||||
margin-top: 16rpx;
|
||||
padding: 20rpx;
|
||||
border: 1rpx solid #dbe5f0;
|
||||
border-radius: 14rpx;
|
||||
background: #f7f9fc;
|
||||
}
|
||||
|
||||
.todo-config-card .project-input {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.todo-input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 76rpx;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20rpx;
|
||||
border: 1rpx solid #d1d5db;
|
||||
border-radius: 12rpx;
|
||||
background: #fff;
|
||||
color: #111827;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.todo-executor-picker {
|
||||
width: 100%;
|
||||
max-height: 72vh;
|
||||
box-sizing: border-box;
|
||||
padding: 24rpx;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.todo-executor-list {
|
||||
max-height: 58vh;
|
||||
}
|
||||
|
||||
.todo-team-group {
|
||||
margin-top: 16rpx;
|
||||
border: 1rpx solid #e5e7eb;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.todo-team-title {
|
||||
padding: 16rpx 20rpx;
|
||||
background: #f3f6fa;
|
||||
color: #374151;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.todo-executor-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
min-height: 76rpx;
|
||||
padding: 0 20rpx;
|
||||
border-top: 1rpx solid #f0f2f5;
|
||||
color: #1f2937;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.todo-selected {
|
||||
color: #0877f1;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.todo-empty {
|
||||
padding: 24rpx 20rpx;
|
||||
color: #9ca3af;
|
||||
font-size: 24rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.readonly-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@ -239,6 +239,16 @@ async function completeTask() {
|
||||
userId: doctorInfo.value.userid,
|
||||
})
|
||||
if (res && res.success) {
|
||||
if (todo.value?.benefitDeductOnComplete && todo.value?.benefitRecordId) {
|
||||
const deductRes = await api('completeBenefitTodo', {
|
||||
corpId: account.value.corpId,
|
||||
todoId: todo.value._id,
|
||||
treatmentRecordId: todo.value.benefitRecordId,
|
||||
executorUserId: doctorInfo.value.userid,
|
||||
completedAt: Date.now(),
|
||||
});
|
||||
if (!deductRes?.success) return toast(deductRes?.message || '待办已完成,但权益自动核销失败');
|
||||
}
|
||||
await toast('操作成功');
|
||||
uni.navigateBack();
|
||||
} else {
|
||||
|
||||
@ -94,6 +94,8 @@ const urlsConfig = {
|
||||
// 健康档案相关接口
|
||||
addMedicalRecord: 'addMedicalRecord',
|
||||
addTreatmentRecord: "addTreatmentRecord",
|
||||
updateTreatmentRecord: "updateTreatmentRecord",
|
||||
completeBenefitTodo: "completeBenefitTodo",
|
||||
getProjectPackageList: "getProjectPackageList",
|
||||
getTreatmentRecord: "getTreatmentRecord",
|
||||
getDeductRecord: "getDeductRecord",
|
||||
@ -145,7 +147,8 @@ const urlsConfig = {
|
||||
customerTransferRecord: 'customerTransferRecord',
|
||||
// sendConsultRejectedMessage: "sendConsultRejectedMessage"
|
||||
getTeamTodos: 'getTeamTodos',
|
||||
updateTaskTodo: 'updateTaskTodo'
|
||||
updateTaskTodo: 'updateTaskTodo',
|
||||
createTodo: 'createTodo'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export const TODO_EVENT_TYPE_LABELS = {
|
||||
benefitExecution: '权益执行',
|
||||
followUpNoShow: '未到院回访',
|
||||
followUpNoDeal: '未成交回访',
|
||||
followUp: '诊后回访',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user