feat:服务记录接口接入
This commit is contained in:
parent
70d0f5e496
commit
8e72ec6d24
@ -45,7 +45,7 @@
|
||||
</view>
|
||||
<view class="body">
|
||||
<view class="content" :class="{ clamp: !expandMap[i._id] }">
|
||||
{{ i.taskContent || '暂无内容' }}<text v-if="i.result">(处理结果: {{ i.result }})</text>
|
||||
{{ i.taskContentDisplay || '暂无内容' }}
|
||||
</view>
|
||||
<image class="pen" src="/static/icons/icon-pen.svg" @click.stop="edit(i)" />
|
||||
</view>
|
||||
@ -85,7 +85,11 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { ensureSeed, queryServiceRecords } from './mock';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
import { toast } from '@/utils/widget';
|
||||
import { getServiceTypeLabel, getServiceTypeOptions } from '@/utils/service-type-const';
|
||||
|
||||
const props = defineProps({
|
||||
data: { type: Object, default: () => ({}) },
|
||||
@ -94,21 +98,11 @@ const props = defineProps({
|
||||
floatingBottom: { type: Number, default: 16 },
|
||||
});
|
||||
|
||||
const typeList = [
|
||||
{ label: '全部', value: 'ALL' },
|
||||
{ label: '电话回访', value: 'phone' },
|
||||
{ label: '短信提醒', value: 'sms' },
|
||||
{ label: '问卷', value: 'questionnaire' },
|
||||
{ label: '文章', value: 'article' },
|
||||
];
|
||||
const teamList = [
|
||||
{ label: '全部', value: 'ALL' },
|
||||
{ label: '口腔一科(示例)', value: 'team_1' },
|
||||
{ label: '正畸团队(示例)', value: 'team_2' },
|
||||
];
|
||||
const typeList = [{ label: '全部', value: 'ALL' }, ...getServiceTypeOptions({ excludeCustomerUpdate: true })];
|
||||
const teamList = ref([{ label: '全部', value: 'ALL' }]);
|
||||
|
||||
const currentType = ref(typeList[0]);
|
||||
const currentTeam = ref(teamList[0]);
|
||||
const currentTeam = ref(teamList.value[0]);
|
||||
const dateRange = ref([]);
|
||||
|
||||
const page = ref(1);
|
||||
@ -117,6 +111,70 @@ const pages = ref(1);
|
||||
const loading = ref(false);
|
||||
const list = ref([]);
|
||||
const expandMap = ref({});
|
||||
const userNameMap = ref({});
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||
const { getDoctorInfo } = accountStore;
|
||||
|
||||
async function ensureDoctor() {
|
||||
if (doctorInfo.value) return;
|
||||
if (!account.value?.openid) return;
|
||||
try {
|
||||
await getDoctorInfo();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
function getUserId() {
|
||||
const d = doctorInfo.value || {};
|
||||
const a = account.value || {};
|
||||
return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
|
||||
}
|
||||
|
||||
function getCorpId() {
|
||||
const t = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
const a = account.value || {};
|
||||
const d = doctorInfo.value || {};
|
||||
return String(t.corpId || a.corpId || d.corpId || '') || '';
|
||||
}
|
||||
|
||||
function getCurrentTeamId() {
|
||||
const t = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
return String(t.teamId || '') || '';
|
||||
}
|
||||
|
||||
function resolveUserName(userId) {
|
||||
const id = String(userId || '');
|
||||
if (!id) return '';
|
||||
const map = userNameMap.value || {};
|
||||
return String(map[id] || '') || id;
|
||||
}
|
||||
|
||||
function formatTaskContent(text) {
|
||||
if (typeof text !== 'string') return '';
|
||||
return text.replace(/&&&([^&]+)&&&/g, (_, id) => resolveUserName(id)).trim();
|
||||
}
|
||||
|
||||
async function loadTeamMembers(teamId) {
|
||||
const tid = String(teamId || '') || '';
|
||||
if (!tid) return;
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
if (!corpId) return;
|
||||
const res = await api('getTeamData', { corpId, teamId: tid });
|
||||
if (!res?.success) return;
|
||||
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||
const members = Array.isArray(t.memberList) ? t.memberList : [];
|
||||
const map = members.reduce((acc, m) => {
|
||||
const uid = String(m?.userid || '');
|
||||
if (!uid) return acc;
|
||||
acc[uid] = String(m?.anotherName || m?.name || m?.userid || '') || uid;
|
||||
return acc;
|
||||
}, {});
|
||||
userNameMap.value = { ...(userNameMap.value || {}), ...map };
|
||||
}
|
||||
|
||||
const moreStatus = computed(() => {
|
||||
if (loading.value) return 'loading';
|
||||
@ -133,10 +191,12 @@ function mapRow(i) {
|
||||
const fileType = i.pannedEventSendFile?.type === 'article' ? 'article' : i.pannedEventSendFile?.type === 'questionnaire' ? 'questionnaire' : '';
|
||||
return {
|
||||
...i,
|
||||
_id: String(i?._id || i?.id || ''),
|
||||
hasFile,
|
||||
fileType,
|
||||
timeStr: i.executionTime ? dayjs(i.executionTime).format('YYYY-MM-DD HH:mm') : '--',
|
||||
typeStr: typeList.find((t) => t.value === i.eventType)?.label || '',
|
||||
typeStr: getServiceTypeLabel(i.eventType),
|
||||
taskContentDisplay: formatTaskContent(String(i?.taskContent || '')),
|
||||
};
|
||||
}
|
||||
|
||||
@ -147,23 +207,62 @@ function reset() {
|
||||
getMore();
|
||||
}
|
||||
|
||||
function getMore() {
|
||||
function getEventTypeList() {
|
||||
const v = currentType.value?.value || 'ALL';
|
||||
if (v === 'ALL') return typeList.filter((i) => i.value !== 'ALL').map((i) => i.value);
|
||||
return [v];
|
||||
}
|
||||
|
||||
async function getMore() {
|
||||
if (!props.archiveId) return;
|
||||
if (loading.value) return;
|
||||
if (page.value > pages.value) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const { list: arr, pages: p } = queryServiceRecords({
|
||||
archiveId: props.archiveId,
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
if (!corpId) {
|
||||
toast('缺少 corpId,请先完成登录/团队选择');
|
||||
return;
|
||||
}
|
||||
|
||||
const params = {
|
||||
corpId,
|
||||
customerId: String(props.archiveId),
|
||||
eventTypeList: getEventTypeList(),
|
||||
};
|
||||
if (dateRange.value.length) params.executionTime = dateRange.value;
|
||||
|
||||
const teamId = currentTeam.value?.value && currentTeam.value.value !== 'ALL' ? currentTeam.value.value : '';
|
||||
const res = await api('getServiceRecord', {
|
||||
page: page.value,
|
||||
pageSize,
|
||||
eventType: currentType.value.value,
|
||||
teamId: currentTeam.value.value,
|
||||
dateRange: dateRange.value,
|
||||
params,
|
||||
queryType: '',
|
||||
teamId,
|
||||
});
|
||||
|
||||
if (!res?.success) {
|
||||
toast(res?.message || '获取服务记录失败');
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = res?.data;
|
||||
const arr = Array.isArray(payload?.data) ? payload.data : Array.isArray(payload) ? payload : [];
|
||||
const p =
|
||||
typeof payload?.pages === 'number'
|
||||
? payload.pages
|
||||
: typeof payload?.total === 'number'
|
||||
? Math.ceil(payload.total / pageSize) || 0
|
||||
: typeof res?.total === 'number'
|
||||
? Math.ceil(res.total / pageSize) || 0
|
||||
: arr.length < pageSize
|
||||
? page.value
|
||||
: page.value + 1;
|
||||
|
||||
pages.value = p;
|
||||
const mapped = arr.map(mapRow);
|
||||
const mapped = arr.map(mapRow).filter((i) => i && i._id);
|
||||
list.value = page.value === 1 ? mapped : [...list.value, ...mapped];
|
||||
page.value += 1;
|
||||
} finally {
|
||||
@ -180,7 +279,9 @@ function pickType(e) {
|
||||
reset();
|
||||
}
|
||||
function pickTeam(e) {
|
||||
currentTeam.value = teamList[e.detail.value] || teamList[0];
|
||||
currentTeam.value = teamList.value[e.detail.value] || teamList.value[0];
|
||||
const tid = currentTeam.value?.value && currentTeam.value.value !== 'ALL' ? currentTeam.value.value : getCurrentTeamId();
|
||||
loadTeamMembers(tid);
|
||||
reset();
|
||||
}
|
||||
|
||||
@ -194,10 +295,32 @@ function clearDates() {
|
||||
}
|
||||
|
||||
function add() {
|
||||
const archive = props.data || {};
|
||||
const customerUserId = String(archive.externalUserId || archive.customerUserId || '') || '';
|
||||
uni.setStorageSync('service-record-detail', {
|
||||
customerId: String(props.archiveId),
|
||||
customerName: String(archive.name || ''),
|
||||
customerUserId,
|
||||
eventType: '',
|
||||
});
|
||||
uni.navigateTo({ url: `/pages/case/service-record-detail?archiveId=${encodeURIComponent(props.archiveId)}&mode=add` });
|
||||
}
|
||||
|
||||
function edit(record) {
|
||||
const archive = props.data || {};
|
||||
const customerUserId = String(archive.externalUserId || archive.customerUserId || '') || '';
|
||||
uni.setStorageSync('service-record-detail', {
|
||||
customerId: String(props.archiveId),
|
||||
customerName: String(archive.name || ''),
|
||||
customerUserId,
|
||||
id: String(record?._id || ''),
|
||||
executionTime: record?.executionTime || 0,
|
||||
executeTeamId: String(record?.executeTeamId || ''),
|
||||
executeTeamName: String(record?.executeTeamName || ''),
|
||||
eventType: String(record?.eventType || ''),
|
||||
taskContent: String(record?.taskContent || ''),
|
||||
pannedEventSendFile: record?.pannedEventSendFile || null,
|
||||
});
|
||||
uni.navigateTo({ url: `/pages/case/service-record-detail?archiveId=${encodeURIComponent(props.archiveId)}&mode=edit&id=${encodeURIComponent(record._id)}` });
|
||||
}
|
||||
|
||||
@ -234,8 +357,30 @@ function copyFile() {
|
||||
closeFilePopup();
|
||||
}
|
||||
|
||||
async function loadTeams() {
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
const userId = getUserId();
|
||||
if (!corpId || !userId) return;
|
||||
const res = await api('getTeamBymember', { corpId, corpUserId: userId });
|
||||
if (!res?.success) return;
|
||||
const list = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
|
||||
const normalized = list
|
||||
.map((raw) => {
|
||||
if (!raw || typeof raw !== 'object') return null;
|
||||
const teamId = raw.teamId || raw.id || raw._id || '';
|
||||
const name = raw.name || raw.teamName || raw.team || '';
|
||||
if (!teamId || !name) return null;
|
||||
return { label: String(name), value: String(teamId) };
|
||||
})
|
||||
.filter(Boolean);
|
||||
teamList.value = [{ label: '全部', value: 'ALL' }, ...normalized];
|
||||
currentTeam.value = teamList.value.find((i) => i.value === currentTeam.value?.value) || teamList.value[0];
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
ensureSeed(props.archiveId, props.data);
|
||||
loadTeams();
|
||||
loadTeamMembers(getCurrentTeamId());
|
||||
reset();
|
||||
uni.$on('archive-detail:service-record-changed', reset);
|
||||
});
|
||||
@ -252,40 +397,55 @@ watch(
|
||||
|
||||
<style scoped>
|
||||
.wrap {
|
||||
padding: 12px 0 96px;
|
||||
padding: 8px 0 96px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
padding: 10px 14px;
|
||||
padding: 6px 14px;
|
||||
background: #f5f6f8;
|
||||
border-bottom: 1px solid #f2f2f2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.filters :deep(picker) {
|
||||
display: block;
|
||||
flex: 0 0 auto;
|
||||
width: 100px;
|
||||
}
|
||||
.filters :deep(uni-datetime-picker) {
|
||||
display: block;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin: 0 12px;
|
||||
}
|
||||
.filter-pill {
|
||||
background: #fff;
|
||||
border: 1px solid #e6e6e6;
|
||||
border-radius: 6px;
|
||||
padding: 10px 10px;
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
min-width: 110px;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.filter-pill.wide {
|
||||
min-width: 160px;
|
||||
min-width: 0;
|
||||
}
|
||||
.pill-text {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
max-width: 190px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
margin-right: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.filter-pill :deep(uni-icons) {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.pill-text.muted {
|
||||
color: #999;
|
||||
}
|
||||
@ -295,8 +455,8 @@ watch(
|
||||
|
||||
.timeline {
|
||||
background: #fff;
|
||||
margin-top: 10px;
|
||||
padding: 12px 0 70px;
|
||||
margin-top: 6px;
|
||||
padding: 10px 0 70px;
|
||||
}
|
||||
.cell {
|
||||
padding: 0 14px;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<scroll-view scroll-y class="scroll">
|
||||
<view class="card">
|
||||
<view class="section-title">执行日期</view>
|
||||
<picker mode="date" @change="pickDate">
|
||||
<picker mode="date" @change="pickDate" :disabled="true">
|
||||
<view class="picker-box">
|
||||
<uni-icons type="calendar" size="18" color="#666" class="mr" />
|
||||
<view class="picker-text" :class="{ muted: !date }">{{ date || '请选择服务日期' }}</view>
|
||||
@ -13,7 +13,7 @@
|
||||
</picker>
|
||||
|
||||
<view class="section-title">执行时间</view>
|
||||
<picker mode="time" @change="pickTime">
|
||||
<picker mode="time" @change="pickTime" :disabled="Boolean(recordId)">
|
||||
<view class="picker-box">
|
||||
<uni-icons type="calendar" size="18" color="#666" class="mr" />
|
||||
<view class="picker-text" :class="{ muted: !time }">{{ time || '请选择执行时间' }}</view>
|
||||
@ -23,8 +23,8 @@
|
||||
<view class="section-title">服务类型</view>
|
||||
<picker mode="selector" :range="typeOptions" range-key="label" @change="pickType" :disabled="Boolean(recordId)">
|
||||
<view class="picker-box between">
|
||||
<view class="picker-text" :class="{ muted: !currentType.value }">
|
||||
{{ currentType.value ? currentType.label : '请选择服务类型' }}
|
||||
<view class="picker-text" :class="{ muted: !currentType?.value }">
|
||||
{{ currentType?.value ? currentType.label : '请选择服务类型' }}
|
||||
</view>
|
||||
<uni-icons type="arrowright" size="16" color="#999" />
|
||||
</view>
|
||||
@ -33,8 +33,8 @@
|
||||
<view class="section-title">所属团队</view>
|
||||
<picker mode="selector" :range="teamOptions" range-key="label" @change="pickTeam" :disabled="Boolean(recordId)">
|
||||
<view class="picker-box between">
|
||||
<view class="picker-text" :class="{ muted: !currentTeam.value }">
|
||||
{{ currentTeam.value ? currentTeam.label : '请选择所属团队' }}
|
||||
<view class="picker-text" :class="{ muted: !currentTeam?.value }">
|
||||
{{ currentTeam?.value ? currentTeam.label : '请选择所属团队' }}
|
||||
</view>
|
||||
<uni-icons type="arrowright" size="16" color="#999" />
|
||||
</view>
|
||||
@ -45,12 +45,6 @@
|
||||
<textarea v-model="form.taskContent" class="textarea tall" maxlength="1000" placeholder="请输入服务小结内容" />
|
||||
<view class="counter">{{ (form.taskContent || '').length }}/1000</view>
|
||||
</view>
|
||||
|
||||
<view class="section-title">处理结果</view>
|
||||
<view class="textarea-box">
|
||||
<textarea v-model="form.result" class="textarea" maxlength="500" placeholder="请输入处理结果(可选)" />
|
||||
<view class="counter">{{ (form.result || '').length }}/500</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 120px;"></view>
|
||||
</scroll-view>
|
||||
@ -71,65 +65,122 @@
|
||||
import { reactive, ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import dayjs from 'dayjs';
|
||||
import { ensureSeed, getServiceRecord, removeServiceRecord, upsertServiceRecord } from '@/components/archive-detail/mock';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import api from '@/utils/api';
|
||||
import useAccountStore from '@/store/account';
|
||||
import { toast } from '@/utils/widget';
|
||||
import { getServiceTypeOptions } from '@/utils/service-type-const';
|
||||
|
||||
const archiveId = ref('');
|
||||
const mode = ref('add');
|
||||
const recordId = ref('');
|
||||
|
||||
const typeOptions = [
|
||||
{ label: '电话回访', value: 'phone' },
|
||||
{ label: '短信提醒', value: 'sms' },
|
||||
{ label: '问卷', value: 'questionnaire' },
|
||||
{ label: '文章', value: 'article' },
|
||||
];
|
||||
const currentType = ref(typeOptions[0]);
|
||||
const typeOptions = getServiceTypeOptions({ excludeCustomerUpdate: true });
|
||||
const currentType = ref(null);
|
||||
|
||||
const teamOptions = [
|
||||
{ label: '口腔一科(示例)', value: 'team_1' },
|
||||
{ label: '正畸团队(示例)', value: 'team_2' },
|
||||
];
|
||||
const currentTeam = ref(teamOptions[0]);
|
||||
const teamOptions = ref([]);
|
||||
const currentTeam = ref(null);
|
||||
|
||||
const date = ref('');
|
||||
const time = ref('');
|
||||
const form = reactive({
|
||||
executorName: '',
|
||||
taskContent: '',
|
||||
result: '',
|
||||
articleUrl: '',
|
||||
surveryId: '',
|
||||
});
|
||||
const customerId = ref('');
|
||||
const customerName = ref('');
|
||||
const customerUserId = ref('');
|
||||
|
||||
const accountStore = useAccountStore();
|
||||
const { account, doctorInfo } = storeToRefs(accountStore);
|
||||
const { getDoctorInfo } = accountStore;
|
||||
|
||||
async function ensureDoctor() {
|
||||
if (doctorInfo.value) return;
|
||||
if (!account.value?.openid) return;
|
||||
try {
|
||||
await getDoctorInfo();
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
function getUserId() {
|
||||
const d = doctorInfo.value || {};
|
||||
const a = account.value || {};
|
||||
return String(d.userid || d.userId || d.corpUserId || a.userid || a.userId || '') || '';
|
||||
}
|
||||
|
||||
function getCorpId() {
|
||||
const t = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
const a = account.value || {};
|
||||
const d = doctorInfo.value || {};
|
||||
return String(t.corpId || a.corpId || d.corpId || '') || '';
|
||||
}
|
||||
|
||||
function getCurrentTeam() {
|
||||
const t = uni.getStorageSync('ykt_case_current_team') || {};
|
||||
const teamId = String(t.teamId || '') || '';
|
||||
const name = String(t.name || t.teamName || '') || '';
|
||||
return teamId ? { value: teamId, label: name || teamId } : null;
|
||||
}
|
||||
|
||||
async function loadTeams() {
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
const userId = getUserId();
|
||||
if (!corpId || !userId) return;
|
||||
const res = await api('getTeamBymember', { corpId, corpUserId: userId });
|
||||
if (!res?.success) return;
|
||||
const list = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
|
||||
teamOptions.value = list
|
||||
.map((raw) => {
|
||||
if (!raw || typeof raw !== 'object') return null;
|
||||
const teamId = raw.teamId || raw.id || raw._id || '';
|
||||
const name = raw.name || raw.teamName || raw.team || '';
|
||||
if (!teamId) return null;
|
||||
return { label: String(name || teamId), value: String(teamId) };
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
archiveId.value = options?.archiveId ? String(options.archiveId) : '';
|
||||
recordId.value = options?.id ? String(options.id) : '';
|
||||
|
||||
ensureSeed(archiveId.value, {});
|
||||
mode.value = options?.mode ? String(options.mode) : 'add';
|
||||
const seed = uni.getStorageSync('service-record-detail') || null;
|
||||
|
||||
if (recordId.value) {
|
||||
const record = getServiceRecord({ archiveId: archiveId.value, id: recordId.value });
|
||||
if (record) {
|
||||
currentType.value = typeOptions.find((i) => i.value === record.eventType) || typeOptions[0];
|
||||
currentTeam.value = teamOptions.find((i) => i.value === record.executeTeamId) || teamOptions[0];
|
||||
date.value = record.executionTime ? dayjs(record.executionTime).format('YYYY-MM-DD') : '';
|
||||
time.value = record.executionTime ? dayjs(record.executionTime).format('HH:mm') : '';
|
||||
form.executorName = record.executorName || '';
|
||||
form.taskContent = record.taskContent || '';
|
||||
form.result = record.result || '';
|
||||
form.articleUrl = record.pannedEventSendFile?.type === 'article' ? record.pannedEventSendFile.url || '' : '';
|
||||
form.surveryId = record.pannedEventSendFile?.type === 'questionnaire' ? record.pannedEventSendFile.surveryId || '' : '';
|
||||
return;
|
||||
customerId.value = String(seed?.customerId || archiveId.value || '') || '';
|
||||
customerName.value = String(seed?.customerName || '') || '';
|
||||
customerUserId.value = String(seed?.customerUserId || '') || '';
|
||||
|
||||
const executionTime = seed?.executionTime && dayjs(seed.executionTime).isValid() ? dayjs(seed.executionTime) : null;
|
||||
date.value = executionTime ? executionTime.format('YYYY-MM-DD') : dayjs().format('YYYY-MM-DD');
|
||||
time.value = executionTime ? executionTime.format('HH:mm') : '';
|
||||
form.taskContent = String(seed?.taskContent || '') || '';
|
||||
|
||||
const seedType = String(seed?.eventType || '') || '';
|
||||
currentType.value = typeOptions.find((i) => i.value === seedType) || null;
|
||||
|
||||
const seedTeamId = String(seed?.executeTeamId || '') || '';
|
||||
const seedTeamName = String(seed?.executeTeamName || '') || '';
|
||||
if (seedTeamId) currentTeam.value = { value: seedTeamId, label: seedTeamName || seedTeamId };
|
||||
else currentTeam.value = getCurrentTeam();
|
||||
|
||||
loadTeams().then(() => {
|
||||
if (seedTeamId) currentTeam.value = teamOptions.value.find((t) => t.value === seedTeamId) || currentTeam.value;
|
||||
else {
|
||||
const cur = getCurrentTeam();
|
||||
if (cur) currentTeam.value = teamOptions.value.find((t) => t.value === cur.value) || cur;
|
||||
}
|
||||
}
|
||||
date.value = dayjs().format('YYYY-MM-DD');
|
||||
});
|
||||
});
|
||||
|
||||
function pickType(e) {
|
||||
currentType.value = typeOptions[e.detail.value] || typeOptions[0];
|
||||
currentType.value = typeOptions[e.detail.value] || null;
|
||||
}
|
||||
function pickTeam(e) {
|
||||
currentTeam.value = teamOptions[e.detail.value] || teamOptions[0];
|
||||
currentTeam.value = teamOptions.value[e.detail.value] || null;
|
||||
}
|
||||
function pickDate(e) {
|
||||
date.value = e.detail.value || '';
|
||||
@ -143,10 +194,7 @@ function cancel() {
|
||||
}
|
||||
|
||||
function save() {
|
||||
if (!archiveId.value) {
|
||||
uni.showToast({ title: '缺少 archiveId', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (!customerId.value) return toast('缺少 customerId');
|
||||
if (!date.value) return uni.showToast({ title: '请选择服务日期', icon: 'none' });
|
||||
if (!time.value) return uni.showToast({ title: '请选择执行时间', icon: 'none' });
|
||||
if (!currentType.value?.value) return uni.showToast({ title: '请选择服务类型', icon: 'none' });
|
||||
@ -154,27 +202,52 @@ function save() {
|
||||
if (!String(form.taskContent || '').trim()) return uni.showToast({ title: '请输入服务内容', icon: 'none' });
|
||||
|
||||
const executionTime = dayjs(`${date.value} ${time.value}`).isValid() ? dayjs(`${date.value} ${time.value}`).valueOf() : Date.now();
|
||||
const pannedEventSendFile =
|
||||
currentType.value.value === 'article'
|
||||
? (form.articleUrl ? { type: 'article', url: form.articleUrl } : null)
|
||||
: currentType.value.value === 'questionnaire'
|
||||
? (form.surveryId ? { type: 'questionnaire', surveryId: form.surveryId } : null)
|
||||
: null;
|
||||
submit(executionTime);
|
||||
}
|
||||
|
||||
upsertServiceRecord({
|
||||
archiveId: archiveId.value,
|
||||
record: {
|
||||
_id: recordId.value || '',
|
||||
eventType: currentType.value.value,
|
||||
executionTime,
|
||||
executeTeamId: currentTeam.value.value,
|
||||
executeTeamName: currentTeam.value.label,
|
||||
executorName: form.executorName,
|
||||
taskContent: form.taskContent,
|
||||
result: form.result,
|
||||
pannedEventSendFile,
|
||||
},
|
||||
});
|
||||
async function submit(executionTime) {
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
const userId = getUserId();
|
||||
if (!corpId || !userId) {
|
||||
toast('缺少用户/团队信息');
|
||||
return;
|
||||
}
|
||||
|
||||
const params = {
|
||||
taskContent: form.taskContent,
|
||||
executionTime,
|
||||
eventType: currentType.value.value,
|
||||
executeTeamId: currentTeam.value.value,
|
||||
executeTeamName: currentTeam.value.label,
|
||||
};
|
||||
|
||||
let res;
|
||||
if (recordId.value) {
|
||||
res = await api('updateServiceRecord', {
|
||||
corpId,
|
||||
id: recordId.value,
|
||||
params: {
|
||||
...params,
|
||||
updateUserId: userId,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
res = await api('addServiceRecord', {
|
||||
...params,
|
||||
corpId,
|
||||
creatorUserId: userId,
|
||||
executorUserId: userId,
|
||||
customerId: customerId.value,
|
||||
customerName: customerName.value,
|
||||
customerUserId: customerUserId.value,
|
||||
});
|
||||
}
|
||||
|
||||
if (!res?.success) {
|
||||
toast(res?.message || (recordId.value ? '修改失败' : '新增失败'));
|
||||
return;
|
||||
}
|
||||
uni.$emit('archive-detail:service-record-changed');
|
||||
uni.showToast({ title: '保存成功', icon: 'success' });
|
||||
setTimeout(() => uni.navigateBack(), 300);
|
||||
@ -184,9 +257,16 @@ function remove() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定删除当前记录?',
|
||||
success: (res) => {
|
||||
success: async (res) => {
|
||||
if (!res.confirm) return;
|
||||
removeServiceRecord({ archiveId: archiveId.value, id: recordId.value });
|
||||
await ensureDoctor();
|
||||
const corpId = getCorpId();
|
||||
if (!corpId || !recordId.value) return;
|
||||
const resp = await api('removeServiceRecord', { corpId, id: recordId.value });
|
||||
if (!resp?.success) {
|
||||
toast(resp?.message || '删除失败');
|
||||
return;
|
||||
}
|
||||
uni.$emit('archive-detail:service-record-changed');
|
||||
uni.showToast({ title: '已删除', icon: 'success' });
|
||||
setTimeout(() => uni.navigateBack(), 300);
|
||||
|
||||
@ -57,6 +57,11 @@ const urlsConfig = {
|
||||
getManagementPlan: 'getManagementPlan',
|
||||
getManagementPlanById: 'getManagementPlanById',
|
||||
getNextFollowUpTime: 'getNextFollowUpTime',
|
||||
// 服务记录(对齐 ykt-management-mobile/src/api/todo.js)
|
||||
getServiceRecord: 'getServiceRecord',
|
||||
addServiceRecord: 'addServiceRecord',
|
||||
updateServiceRecord: 'updateServiceRecord',
|
||||
removeServiceRecord: 'removeServiceRecord',
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
42
utils/service-type-const.js
Normal file
42
utils/service-type-const.js
Normal file
@ -0,0 +1,42 @@
|
||||
export const SERVICE_TYPE_LABELS = {
|
||||
remindFiling: '新建档案',
|
||||
addVisitRecord: '预约登记',
|
||||
ContentReminder: '宣教发送',
|
||||
questionnaire: '问卷调查',
|
||||
customerUpdate: '更新客户档案',
|
||||
serviceSummary: '咨询服务',
|
||||
visitRegistration: '就诊登记',
|
||||
followUpNoShow: '未到院回访',
|
||||
followUpNoDeal: '未成交回访',
|
||||
followUp: '诊后回访',
|
||||
followUpPostSurgery: '术后回访',
|
||||
followUpPostTreatment: '治疗后回访',
|
||||
appointmentReminder: '就诊提醒',
|
||||
followUpReminder: '复诊提醒',
|
||||
medicationReminder: '用药提醒',
|
||||
eventNotification: '活动通知',
|
||||
transferToSameTeam: '客户转移(团队内转)',
|
||||
transferToOtherTeam: '客户转移(转别的团队)',
|
||||
transferToCustomerPool: '客户转移(转公共客户池)',
|
||||
adminAllocateTeams: '管理员分配团队',
|
||||
adminRemoveTeams: '管理员解除团队',
|
||||
share: '客户共享',
|
||||
followUpComplaint: '投诉回访',
|
||||
followUpActivity: '活动回访',
|
||||
other: '其他',
|
||||
Feedback: '意见反馈',
|
||||
treatmentAppointment: '治疗预约',
|
||||
followupAppointment: '复诊预约',
|
||||
confirmArrival: '确认到院',
|
||||
};
|
||||
|
||||
export function getServiceTypeLabel(value) {
|
||||
const v = String(value || '');
|
||||
return SERVICE_TYPE_LABELS[v] || v || '其他';
|
||||
}
|
||||
|
||||
export function getServiceTypeOptions({ excludeCustomerUpdate = true } = {}) {
|
||||
return Object.keys(SERVICE_TYPE_LABELS)
|
||||
.filter((key) => (excludeCustomerUpdate ? key !== 'customerUpdate' : true))
|
||||
.map((key) => ({ value: key, label: SERVICE_TYPE_LABELS[key] }));
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user