4 Revīzijas cce42d191f ... 901585cd64

Autors SHA1 Ziņojums Datums
  wangjian 901585cd64 提交问卷入参传值调整 6 dienas atpakaļ
  wangjian 014d8c5f73 患者取值调整 6 dienas atpakaļ
  wangjian df163ab27c 增加合并选项功能 1 nedēļu atpakaļ
  wangjian 64609d6ae8 提交问卷默认加上患者信息,处理必填选项展示 2 nedēļas atpakaļ

+ 1 - 1
manifest.json

@@ -1,6 +1,6 @@
 {
     "name" : "uni-app-demo",
-    "appid" : "__UNI__797F817",
+    "appid" : "__UNI__5EC4523",
     "description" : "demo",
     "versionName" : "1.0.0",
     "versionCode" : "100",

+ 191 - 12
pagesAdmin/satisfaction/business/satisfactionQuestions/satisfactionQuestions.vue

@@ -20,13 +20,36 @@
 					<view
 						class="ques_item_box"
 						:id="'p' + index"
+						v-if="!isQuestionHidden(item)"
 						:class="item.QuestType == 'SubTitle' ? 'sub_title' : ''"
 					>
 						<view class="ques_title_box">
-							<text class="mustQuest_tag" wx:if="{{item.MustQuest}}">*</text>
+							<text class="mustQuest_tag" v-if="item.MustQuest">*</text>
 							<text v-if="item.QuestType != 'SubTitle'">{{ item.Sort }}.{{ item.Question }}</text>
 							<text v-if="item.QuestType == 'SubTitle'">{{ item.Num }}、{{ item.Question }}</text>
 						</view>
+						<!-- 大标题满意度 -->
+						<view
+							class="ques_options displayFlexCol"
+							v-if="item.QuestType == 'SubTitle' && item.HasScaleInSubtitle"
+						>
+							<block
+								v-for="(childItem, childIndex) in subtitleSatisfactionOptions"
+								:key="`SubTitleSatisfaction-${index}-${childIndex}`"
+							>
+								<text
+									class="choice_item"
+									:class="
+										isSubtitleSatisfactionActive(item.SubTitleIndex, childIndex) ? 'active_option' : ''
+									"
+									:data-subtitleindex="item.SubTitleIndex"
+									:data-childindex="childIndex"
+									@click="choiceSubtitleSatisfaction"
+								>
+									{{ childItem }}
+								</text>
+							</block>
+						</view>
 						<!-- 填空题 -->
 						<view
 							class="ques_options align_items_left displayFlexCol"
@@ -278,7 +301,7 @@
 						</view>
 						<image class="modal_user_right_img" :src="icon.satisfaction.right"></image>
 					</view>
-					<view class="modal_user_item" wx:else @click="goSelMember">
+					<view class="modal_user_item" v-else @click="goSelMember">
 						<view>点击选择答卷人</view>
 						<image class="modal_user_right_img" :src="icon.satisfaction.right"></image>
 					</view>
@@ -303,6 +326,7 @@ import {
 	UploadZxFile,
 	CommitAnswer_V3,
 	QuerySample_V3,
+	QueryMemberByCard_V3,
 } from '../../service';
 import icon from '@/utils/icon';
 import { common, throttle } from '@/utils';
@@ -318,9 +342,16 @@ const quesList = ref({} as any);
 const imgList = ref([]);
 const point = ref('');
 const complete = ref(false);
+const subtitleSatisfactionOptions = ['非常满意', '比较满意', '一般', '不太满意', '很不满意'];
+const subtitleSatisfaction = reactive({} as Record<string, number | null>);
 const anonymousType = ref(0);
 const showModal_Anonymous = ref(false); // 是否实名填写弹窗显示
 const showModal_User = ref(false); // 实名用户选择弹窗显示
+const pageParams = reactive({
+	cardNo: '',
+	cardType: '',
+  sampleId: '',
+});
 let quesAnswers = reactive({
 	MemberId: '',
 	TaskId: '-1',
@@ -333,6 +364,7 @@ let quesAnswers = reactive({
 	UserName: '',
 	Sex: '',
 	Age: '',
+	IdCard: '',
 	ThirdPartyId: '',
 	AnswerUseTime: 0,
 	PushDept: '',
@@ -340,15 +372,58 @@ let quesAnswers = reactive({
 	BedNo: '',
 	HospitalNo: '',
 	CardNo: '',
+	CardType: '',
+  SampleId: '',
 	AnswerList: [],
 });
 
+let queryPatient = reactive({
+	cardNo: '',
+	cardType: ''
+});
+
+const getAgeByBirthDate = (birthDate = '') => {
+	const birth = `${birthDate}`.replace(/\D/g, '').slice(0, 8);
+	if (!/^\d{8}$/.test(birth)) return '';
+	const year = Number(birth.slice(0, 4));
+	const month = Number(birth.slice(4, 6));
+	const day = Number(birth.slice(6, 8));
+	const date = new Date(year, month - 1, day);
+	if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return '';
+	const today = new Date();
+	let age = today.getFullYear() - year;
+	if (today.getMonth() + 1 < month || (today.getMonth() + 1 === month && today.getDate() < day)) {
+		age--;
+	}
+	return age >= 0 ? `${age}` : '';
+};
+
+const getPatientInfoByIdCard = (idCard = '') => {
+	const card = `${idCard}`.trim();
+	if (!/^\d{17}[\dXx]$/.test(card)) return { sex: '', age: '' };
+	const factors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
+	const checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
+	const sum = factors.reduce((total, factor, index) => total + Number(card[index]) * factor, 0);
+	if (checkCodes[sum % 11] !== card[17].toUpperCase()) return { sex: '', age: '' };
+	const birth = card.slice(6, 14);
+	const sexCode = Number(card.slice(16, 17));
+	const age = getAgeByBirthDate(birth);
+	if (!age) return { sex: '', age: '' };
+	return {
+		sex: sexCode % 2 === 1 ? '1' : '2',
+		age,
+	};
+};
+
 const { getCurrentUser } = mapGetters({
 	getCurrentUser: 'getCurrentUser',
 });
 
 const main = async (options) => {
 	currentUser.value = getCurrentUser();
+	pageParams.cardNo = options.cardno || options.cardNo || '';
+	pageParams.cardType = options.cardtype || options.cardType || '';
+	pageParams.sampleId = options.sampleId || options.SampleId || '';
 	const params = {
 		SubjectId: options.subjectId,
 		TaskId: options.taskId,
@@ -379,8 +454,8 @@ const main = async (options) => {
 		getSec();
 		
 		if(options?.type == "sms_myddc") {
-			currentUser.value.cardNo = options.cardNo
-			currentUser.value.cardType = options.cardType
+			currentUser.value.cardNo = pageParams.cardNo
+			currentUser.value.cardType = pageParams.cardType
 			showModal_Anonymous.value = false
 			showModal_User.value = false
 		}
@@ -535,6 +610,8 @@ const getSec = () => {
 const bySort = (list: any[]) => {
 	let find = 0;
 	let sort = 0;
+	let currentSubTitleIndex = -1;
+	let currentSubTitleItem = null as any;
 	let item = {} as any;
 	for (var t = 0; t < list.length; t++) {
 		item = list[t];
@@ -544,12 +621,20 @@ const bySort = (list: any[]) => {
 			sort = 0;
 			//判断是出现的第几个子标题
 			//num是子标题的排序
+			item.SubTitleIndex = find;
+			item.HasScaleInSubtitle = false;
+			currentSubTitleIndex = find;
+			currentSubTitleItem = item;
 			item.Num = toChinesNum(find + 1);
 			find++;
 		} else {
 			//sort是子标题底下的排序
+			item.SubTitleIndex = currentSubTitleIndex;
 			item.Sort = sort + 1;
 			sort++;
+			if (item.QuestType == 'Scale' && currentSubTitleItem) {
+				currentSubTitleItem.HasScaleInSubtitle = true;
+			}
 		}
 		item.SortNum = t;
 		if (common.isNotEmpty(item.QuestionItemList)) {
@@ -588,6 +673,57 @@ const toChinesNum = (num) => {
 };
 
 /** 单选/多选/量表 */
+const isSubtitleScaleExpanded = (subtitleIndex) => {
+	return Number(subtitleSatisfaction[subtitleIndex]) > 0;
+};
+
+const isSubtitleSatisfactionActive = (subtitleIndex, childIndex) => {
+	return Number(subtitleSatisfaction[subtitleIndex]) === Number(childIndex);
+};
+
+const isQuestionHidden = (item) => {
+	return item?.QuestType == 'Scale' && item.SubTitleIndex > -1 && !isSubtitleScaleExpanded(item.SubTitleIndex);
+};
+
+const getAnswerIndex = (answerList, questId) => {
+	let answerIndex = -1;
+	answerList.forEach((item, index) => {
+		if (item.QuestId == questId) {
+			answerIndex = index;
+		}
+	});
+	return answerIndex;
+};
+
+const setSingleQuestionAnswer = (question, answerList, childIndex) => {
+	if (!question?.QuestionItemList?.[childIndex]) return;
+	const answerIndex = getAnswerIndex(answerList, question.QuestId);
+	const answer = question.QuestionItemList[childIndex].ItemId;
+	question.AnswerList = [answer];
+	if (answerIndex > -1) {
+		answerList[answerIndex].Answer = answer;
+	}
+};
+
+const choiceSubtitleSatisfaction = (e) => {
+	const subtitleIndex = Number(e.currentTarget.dataset.subtitleindex);
+	const childIndex = Number(e.currentTarget.dataset.childindex);
+	const questionList = quesList.value.QuestionList;
+	const answerList = quesAnswers.AnswerList;
+	subtitleSatisfaction[subtitleIndex] = childIndex;
+
+	if (childIndex == 0) {
+		questionList.forEach((item) => {
+			if (item.SubTitleIndex == subtitleIndex && item.QuestType == 'Scale') {
+				setSingleQuestionAnswer(item, answerList, 0);
+			}
+		});
+	}
+
+	quesList.value.QuestionList = questionList;
+	quesAnswers.AnswerList = answerList;
+};
+
 const choiceOption = (e) => {
 	let index = e.currentTarget.dataset.index;
 	let childIndex = e.currentTarget.dataset.childindex;
@@ -898,10 +1034,28 @@ const setVal = (e) => {
 };
 
 /** 提交 */
+const validateSubtitleSatisfaction = () => {
+	const questionList = quesList.value.QuestionList || [];
+	for (var i = 0; i < questionList.length; i++) {
+		const item = questionList[i];
+		if (
+			item.QuestType == 'SubTitle' &&
+			item.HasScaleInSubtitle &&
+			subtitleSatisfaction[item.SubTitleIndex] == null
+		) {
+			common.showToast('存在未填写的问卷');
+			point.value = 'p' + i;
+			return false;
+		}
+	}
+	return true;
+};
+
 const submit = () => {
 	throttle(async () => {
 		await common.sleep(1000);
 		if (complete.value) return;
+		if (!validateSubtitleSatisfaction()) return;
 		uni.showLoading();
 		const answers = { ...quesAnswers } as any;
 		for (var i = 0; i < answers.AnswerList.length; i++) {
@@ -918,15 +1072,38 @@ const submit = () => {
 			}
 		});
 		
+		const cardNo = pageParams.cardNo || currentUser.value?.cardNo || '';
+		const cardType = pageParams.cardType || currentUser.value?.cardType || '';
+		let mobile = currentUser.value?.mobile ?? '';
+		let memberName = currentUser.value?.memberName ?? '';
+		let sex = currentUser.value?.sex ?? '';
+		let age = currentUser.value?.age ?? '';
+		let idCard = currentUser.value?.idCard ?? currentUser.value?.certNum ?? '';
+		let memberId = currentUser.value?.MemberId ?? currentUser.value?.memberId ?? cardNo ?? '';
+
+		queryPatient.cardNo = cardNo;
+		queryPatient.cardType = cardType;
+		let patientInfoRes = await QueryMemberByCard_V3(queryPatient);
+		let patientInfo = patientInfoRes.resData;
+		if (!patientInfo) {
+		  uni.hideLoading();
+		  return;
+		}
+
+		if (patientInfo.RespCode === '10000' && patientInfo.Data && patientInfo.Data.length > 0) {
+		  const patient = patientInfo.Data[0];
+		  const patientIdCard = patient.idCard || patient.idcard || patient.certNum || '';
+		  const patientInfoByIdCard = getPatientInfoByIdCard(patientIdCard);
+		  mobile = patient.mobile || mobile;
+		  memberName = patient.memberName || memberName;
+		  sex = patient.sex || patientInfoByIdCard.sex || sex;
+		  age = currentUser.value?.age || getAgeByBirthDate(patient.birthDate) || patientInfoByIdCard.age || age;
+		  idCard = patientIdCard || idCard;
+		  memberId = patient.hisMemberId || patient.memberId || memberId;
+		}
+
 		answers.AnswerList = JSON.stringify(quesAnswers.AnswerList);
-		// 安全读取 currentUser 字段,缺失则置空
-		const mobile = currentUser.value?.mobile ?? ''
-		const memberName = currentUser.value?.memberName ?? ''
-		const memberId = currentUser.value?.MemberId ?? currentUser.value?.memberId ?? ''
-		const sex = currentUser.value?.sex ?? ''
-		const age = currentUser.value?.age ?? ''
-		const cardNo = currentUser.value?.cardNo ?? ''
-		const cardType = currentUser.value?.cardType ?? ''
+
 		// quesAnswers.IP = (await getIP()).cip;
 		// quesAnswers.Location = (await getIP()).cname;
 		quesAnswers.UserAgent = app.globalData.smallPro_systemInfo;
@@ -935,12 +1112,14 @@ const submit = () => {
 		quesAnswers.MemberId = memberId;
 		quesAnswers.Sex = sex;
 		quesAnswers.Age = age;
+		quesAnswers.IdCard = idCard;
 		quesAnswers.ThirdPartyId = memberId || uni.getStorageSync('openid');
 		quesAnswers.BedNo = '';
 		quesAnswers.HospitalNo = objType.value == '4' ? cardNo : '';
 		quesAnswers.CardNo = objType.value == '3' ? cardNo : '';
 		quesAnswers.TaskId = taskId.value;
 		quesAnswers.CardType = objType.value == '3' ? cardType : '';
+		quesAnswers.SampleId = pageParams.sampleId;
 		
 		let res = await CommitAnswer_V3(quesAnswers);
 		clearTimeout(time);

+ 10 - 0
pagesAdmin/satisfaction/service/satisfactionQuestions/index.ts

@@ -55,3 +55,13 @@ export const QueryMemberCardList_V3 = async (queryData: any) => {
 	);
 	return handle.catchPromiseNew(resp, () => resp);
 };
+
+export const QueryMemberByCard_V3 = async (queryData: any) => {
+	const resp = handle.promistHandleNew(
+		await request.doPost(
+			`${REQUEST_CONFIG.BASE_URL}wsgw/accountMember/api/QueryMemberByCard_V3/callApiJSON.do`,
+			queryData
+		)
+	);
+	return handle.catchPromiseNew(resp, () => resp);
+};