history.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <template>
  2. <view class="content">
  3. <view class="self-inf">
  4. <view class="img-title-box">
  5. <view class="title">病史信息</view>
  6. <view class="content">耳鸣情况及其他系统合并疾病情况</view>
  7. <view class="footer">约2分钟完成</view>
  8. </view>
  9. </view>
  10. <view class="example">
  11. <!-- 基础表单校验 -->
  12. <uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
  13. <uni-forms-item label="姓名" required name="name" box-width="190rpx">
  14. <uni-easyinput :value="baseFormData.name" @input="baseFormData.name = $event" placeholder="请输入" />
  15. </uni-forms-item>
  16. <uni-forms-item label="电话" required name="phone" box-width="190rpx">
  17. <uni-easyinput type="number" :value="baseFormData.phone" @input="baseFormData.phone = $event" placeholder="请输入" />
  18. </uni-forms-item>
  19. <uni-forms-item label="性别" required name="sex" box-width="190rpx">
  20. <uni-data-checkbox v-model="baseFormData.sex" :localdata="selectData.sex" @change="change('sex',$event)" :wrap="true"/>
  21. </uni-forms-item>
  22. <uni-forms-item label="年龄" name="age" box-width="190rpx">
  23. <uni-easyinput type="number" :value="baseFormData.age" @input="baseFormData.age = $event" placeholder="请输入" />
  24. </uni-forms-item>
  25. <uni-forms-item label="常住地" required name="address" box-width="190rpx">
  26. <uni-easyinput :value="baseFormData.address" @input="baseFormData.address = $event" placeholder="请输入" />
  27. </uni-forms-item>
  28. <uni-forms-item label="民族" required name="nation" box-width="190rpx">
  29. <picker @change="change('nation',$event)" :value="pickerIndexObj.nation" :range="selectData.nation" range-key="text">
  30. <view class="picker-class-box">{{pickerText(selectData.nation, pickerIndexObj.nation)}}</view>
  31. </picker>
  32. </uni-forms-item>
  33. <uni-forms-item label="职业" required name="profession" box-width="190rpx">
  34. <picker @change="change('profession',$event)" :value="pickerIndexObj.profession" :range="selectData.profession" range-key="text">
  35. <view class="picker-class-box">{{pickerText(selectData.profession, pickerIndexObj.profession)}}</view>
  36. </picker>
  37. </uni-forms-item>
  38. <uni-forms-item label="工作地点" required name="work_address" box-width="190rpx">
  39. <uni-easyinput :value="baseFormData.work_address" @input="baseFormData.work_address = $event" placeholder="请输入" />
  40. </uni-forms-item>
  41. <uni-forms-item label="学历" required name="education" box-width="190rpx">
  42. <picker @change="change('education',$event)" :value="pickerIndexObj.education" :range="selectData.education" range-key="text">
  43. <view class="picker-class-box">{{pickerText(selectData.education, pickerIndexObj.education)}}</view>
  44. </picker>
  45. </uni-forms-item>
  46. <uni-forms-item label="婚姻" required name="marriage" box-width="190rpx">
  47. <picker @change="change('marriage',$event)" :value="pickerIndexObj.marriage" :range="selectData.marriage" range-key="text">
  48. <view class="picker-class-box">{{pickerText(selectData.marriage, pickerIndexObj.marriage)}}</view>
  49. </picker>
  50. </uni-forms-item>
  51. <uni-forms-item label="居住情况" required name="house" box-width="190rpx">
  52. <picker @change="change('house',$event)" :value="pickerIndexObj.house" :range="selectData.house" range-key="text">
  53. <view class="picker-class-box">{{pickerText(selectData.house, pickerIndexObj.house)}}</view>
  54. </picker>
  55. </uni-forms-item>
  56. <uni-forms-item label="耳鸣病程" required name="days" box-width="190rpx">
  57. <view class="display-between">
  58. <uni-easyinput :value="baseFormData.days" @input="baseFormData.days = $event" placeholder="请输入" type="number" widthStyle="160rpx" />
  59. <uni-data-checkbox v-model="unitValue" :localdata="unitList" @change="unitChange($event)" :wrap="true"/>
  60. </view>
  61. </uni-forms-item>
  62. <uni-forms-item label="惯用手" required name="common_hand" box-width="190rpx">
  63. <uni-data-checkbox v-model="baseFormData.common_hand" :localdata="selectData.hand" @change="change('hand',$event)" :wrap="true"/>
  64. </uni-forms-item>
  65. <uni-forms-item label="就诊类型" required name="type" box-width="190rpx">
  66. <picker @change="change('type',$event)" :value="pickerIndexObj.type" :range="selectData.type" range-key="text">
  67. <view class="picker-class-box">{{pickerText(selectData.type, pickerIndexObj.type)}}</view>
  68. </picker>
  69. </uni-forms-item>
  70. <uni-forms-item label="就诊医院" required name="hospital_id" box-width="190rpx">
  71. <picker @change="change('hospital',$event)" :value="pickerIndexObj.hospital" :range="selectData.hospital" range-key="text">
  72. <view class="picker-class-box">{{pickerText(selectData.hospital, pickerIndexObj.hospital)}}</view>
  73. </picker>
  74. </uni-forms-item>
  75. <uni-forms-item label="就诊医生" required name="doctor_id" box-width="190rpx">
  76. <picker @change="change('doctor',$event)" :value="pickerIndexObj.doctor" :range="doctorRange" range-key="text">
  77. <view class="picker-class-box">{{pickerText(doctorRange, pickerIndexObj.doctor)}}</view>
  78. </picker>
  79. </uni-forms-item>
  80. <uni-forms-item label="ID号" name="code" box-width="190rpx">
  81. <uni-easyinput :value="baseFormData.code" @input="baseFormData.code = $event" placeholder="请输入"/>
  82. </uni-forms-item>
  83. </uni-forms>
  84. <button class="footer-btn" @click="submit('valiForm')">提交</button>
  85. </view>
  86. </view>
  87. </template>
  88. <script>
  89. import { request, currentOpenId } from '@/utils/request.js'
  90. export default {
  91. data() {
  92. const currentDate = this.getDate({
  93. format: true
  94. })
  95. return {
  96. // 校验规则
  97. rules: {
  98. name: {
  99. rules: [{
  100. required: true,
  101. errorMessage: '请输入姓名'
  102. }]
  103. },
  104. sex: {
  105. rules: [{
  106. required: true,
  107. errorMessage: '请选择性别'
  108. }]
  109. },
  110. address: {
  111. rules: [{
  112. required: true,
  113. errorMessage: '请输入常住地'
  114. }]
  115. },
  116. phone: {
  117. rules: [{
  118. required: true,
  119. errorMessage: '请输入电话号码'
  120. },
  121. {
  122. minLength: 11,
  123. maxLength: 11,
  124. errorMessage: '电话号码长度为11个数字',
  125. }
  126. ]
  127. },
  128. days: {
  129. rules: [{
  130. required: true,
  131. errorMessage: '请输入耳鸣病程'
  132. }]
  133. },
  134. common_hand: {
  135. rules: [{
  136. required: true,
  137. errorMessage: '请选择惯用手'
  138. }]
  139. },
  140. work_address: {
  141. rules: [{
  142. required: true,
  143. errorMessage: '请输入工作地点'
  144. }]
  145. },
  146. },
  147. // 基础表单数据
  148. baseFormData: {
  149. address: "",
  150. age: "",
  151. birth_year: "0",
  152. birthday: "0",
  153. profession: 1,
  154. work_address: "",
  155. code: "",
  156. common_hand: 2,
  157. create_time: "0",
  158. days: "",
  159. doctor_id: 1,
  160. doctor_name: "",
  161. education: 1,
  162. hospital_id: 1,
  163. hospital_name: "",
  164. house: 1,
  165. id: "2",
  166. marriage: 1,
  167. name: "",
  168. nation: 1,
  169. phone: "",
  170. sex: 1,
  171. title: "0",
  172. type: 1,
  173. update_time: "1728436174",
  174. weixin_user_id: "1",
  175. },
  176. pickerIndexObj:{
  177. profession: -1,
  178. nation: -1,
  179. education: -1,
  180. marriage: -1,
  181. house: -1,
  182. type: -1,
  183. hospital: -1,
  184. doctor: -1,
  185. },
  186. selectData:{
  187. sex: [],
  188. hand: [],
  189. profession: [],
  190. nation: [],
  191. education: [],
  192. marriage: [],
  193. house: [],
  194. type: [],
  195. hospital: [],
  196. },
  197. doctorRange: [],
  198. isAuth: true,
  199. pageId:1,
  200. date: currentDate,
  201. isFinish:false,
  202. unitList:[{ value: "天" , text: "天" },{ value:"月", text: "月" },{ value: "年" , text: "年" }],
  203. unitValue:'天',
  204. unitSubmit:'天'
  205. };
  206. },
  207. computed: {
  208. startDate() {
  209. return this.getDate('start');
  210. },
  211. endDate() {
  212. return this.getDate('end');
  213. }
  214. },
  215. onLoad(query) {
  216. this.isFinish = query.finish || false
  217. },
  218. async onShow() {
  219. const scene = getApp().globalData.sceneParam
  220. if(scene){
  221. await this.$onLaunched;
  222. let codeParam = this.getQueryParams(scene)
  223. this.getUserHis(codeParam.doctor_id,codeParam.hospital_id);
  224. getApp().globalData.sceneParam = '';
  225. }else {
  226. this.getUserHis('');
  227. }
  228. },
  229. methods: {
  230. getDate(type) {
  231. const date = new Date();
  232. let year = date.getFullYear();
  233. let month = date.getMonth() + 1;
  234. let day = date.getDate();
  235. if (type === 'start') {
  236. year = year - 124;
  237. } else if (type === 'end') {
  238. year = year + 0;
  239. }
  240. month = month > 9 ? month : '0' + month;
  241. day = day > 9 ? day : '0' + day;
  242. return `${year}-${month}-${day}`;
  243. },
  244. getQueryParams(str) {
  245. const paramsArr = str.split('&');
  246. const paramObj = {};
  247. paramsArr.forEach(param => {
  248. const [key, value] = param.split('=');
  249. paramObj[key] = value;
  250. });
  251. return paramObj;
  252. },
  253. validatePikcer(){
  254. let pickerObj = this.pickerIndexObj , pickerArr = [];
  255. let language = {
  256. 'nation':'民族',
  257. 'profession':'职业',
  258. 'education':'学历',
  259. 'marriage':'婚姻',
  260. 'house':'居住情况',
  261. 'type':'就诊类型',
  262. 'hospital':'就诊医院',
  263. 'doctor':'就诊医生'
  264. }
  265. for(let k in pickerObj) {
  266. if(pickerObj[k] === -1){
  267. uni.showToast({
  268. title:'请选择' + language[k],
  269. mask:true,
  270. icon:"error",
  271. duration:2000
  272. })
  273. break;
  274. }
  275. }
  276. for(let k in pickerObj) {
  277. let obj = {
  278. key: k,
  279. value:pickerObj[k]
  280. }
  281. pickerArr.push(obj)
  282. }
  283. return pickerArr.every((item)=>{return item.value !== -1})
  284. },
  285. submit(ref) {
  286. let that = this;
  287. that.$refs[ref].validate().then(res => {
  288. let isPicker = that.validatePikcer();
  289. if(isPicker){that.submitForm();}
  290. }).catch(err => {
  291. console.log('err', err);
  292. })
  293. },
  294. getPostId(type,selectIdx){
  295. let resultId;
  296. this.pickerIndexObj[type] = selectIdx;
  297. if(type === 'doctor'){
  298. this.doctorRange.filter((item,idx)=>{
  299. if(idx === selectIdx){
  300. resultId = item.value;
  301. }
  302. });
  303. }else {
  304. this.selectData[type].filter((item,idx)=>{
  305. if(idx === selectIdx){
  306. resultId = item.value;
  307. }
  308. });
  309. }
  310. return resultId;
  311. },
  312. unitChange(e){
  313. this.unitValue = e.detail.value;
  314. this.unitSubmit = e.detail.value;
  315. },
  316. change(types,e) {
  317. let that = this;
  318. let value = e;
  319. let tpyeVal = types;
  320. switch (tpyeVal) {
  321. case 'sex' :
  322. value = e.detail.value;
  323. that.baseFormData.sex = value;
  324. break;
  325. case 'nation' :
  326. value = Number(e.detail.value);
  327. that.baseFormData.nation = that.getPostId(tpyeVal,value);
  328. break;
  329. case 'education' :
  330. value = Number(e.detail.value);
  331. that.baseFormData.education = that.getPostId(tpyeVal,value);
  332. break;
  333. case 'profession' :
  334. value = Number(e.detail.value);
  335. that.baseFormData.profession = that.getPostId(tpyeVal,value);
  336. break;
  337. case 'hand' :
  338. value = e.detail.value;
  339. that.baseFormData.common_hand = value;
  340. break;
  341. case 'hospital' :
  342. value = Number(e.detail.value);
  343. that.baseFormData.hospital_id = that.getPostId(tpyeVal,value)
  344. that.baseFormData.hospital_name = that.selectData.hospital[that.pickerIndexObj.hospital].text
  345. that.getDoctor(that.baseFormData.hospital_id)
  346. break;
  347. case 'doctor' :
  348. value = Number(e.detail.value);
  349. that.baseFormData.doctor_id = that.getPostId(tpyeVal,value)
  350. that.baseFormData.doctor_name = that.doctorRange[that.pickerIndexObj.doctor].text
  351. break;
  352. case 'house' :
  353. value = Number(e.detail.value);
  354. that.baseFormData.house = that.getPostId(tpyeVal,value);
  355. break;
  356. case 'marriage' :
  357. value = Number(e.detail.value);
  358. that.baseFormData.marriage = that.getPostId(tpyeVal,value);
  359. break;
  360. case 'type' :
  361. value = Number(e.detail.value);
  362. that.baseFormData.type = that.getPostId(tpyeVal,value);
  363. break;
  364. }
  365. },
  366. pickerText(arr, idx) {
  367. return (arr && arr[idx]) ? arr[idx].text : ''
  368. },
  369. pickerEchoShow(dataArr,dataId,typeName){
  370. // sex/hand 是复选组件自己处理回显;career_type(工作性质)后台会返回但表单目前没有对应字段,跳过避免污染 pickerIndexObj
  371. if(typeName === 'sex' || typeName === 'hand' || typeName === 'career_type'){
  372. return
  373. }else {
  374. let rangeArr = dataArr, selectedId = dataId;
  375. this.pickerIndexObj[typeName] = rangeArr.findIndex(item => item.value === selectedId);
  376. }
  377. },
  378. makeFromData(docId,hosId){
  379. if(this.baseFormData.age == '0')this.baseFormData.age = '';
  380. this.baseFormData.sex = Number(this.baseFormData.sex);
  381. if(this.baseFormData.sex == '0')this.baseFormData.sex = '';
  382. this.baseFormData.common_hand = Number(this.baseFormData.common_hand);
  383. if(this.baseFormData.common_hand == '0')this.baseFormData.common_hand = '';
  384. if(docId) {
  385. this.baseFormData.hospital_id = Number(hosId);
  386. this.baseFormData.hospital = this.baseFormData.hospital_id
  387. this.baseFormData.doctor_id = Number(docId);
  388. this.baseFormData.doctor = this.baseFormData.doctor_id
  389. }else {
  390. this.baseFormData.hospital_id = Number(this.baseFormData.hospital_id);
  391. this.baseFormData.hospital = this.baseFormData.hospital_id
  392. this.baseFormData.doctor_id = Number(this.baseFormData.doctor_id);
  393. this.baseFormData.doctor = this.baseFormData.doctor_id
  394. }
  395. this.baseFormData.profession = Number(this.baseFormData.profession);
  396. this.baseFormData.education = Number(this.baseFormData.education);
  397. this.baseFormData.marriage = Number(this.baseFormData.marriage);
  398. this.baseFormData.nation = Number(this.baseFormData.nation);
  399. this.baseFormData.type = Number(this.baseFormData.type);
  400. this.baseFormData.house = Number(this.baseFormData.house);
  401. this.getUserSelect();
  402. },
  403. async getUserHis(docId,hosId) {
  404. const res = await request('user', 'get_case_info', { openId: currentOpenId(), doctor_id: docId || 0 })
  405. if (res.code === 200) {
  406. this.baseFormData = res.data;
  407. // 后台没填过的选择类字段存的是字符串 "0"(或者字段压根不存在),跟 age/sex 是同一套"0 代表未填"的约定,
  408. // "0"/undefined 在 JS 里判真值容易漏判,选项列表都是从 value:1 开始编号,统一兜底成 1,否则选择器会显示空白
  409. ['profession','nation','education','marriage','house','common_hand','type','hospital_id','doctor_id'].forEach((key)=>{
  410. if (!this.baseFormData[key] || this.baseFormData[key] == '0') this.baseFormData[key] = 1
  411. })
  412. // 老病历记录没有工作地点字段时后台返回 null,uni-easyinput 绑定 null 初始值会导致输入内容同步不到 baseFormData,提前归一化成空字符串
  413. if (this.baseFormData.work_address == null || this.baseFormData.work_address == undefined) this.baseFormData.work_address = ''
  414. this.unitValue = this.baseFormData.days.substr(-1);
  415. this.baseFormData.days = this.baseFormData.days.substr(0,(this.baseFormData.days.length-1))
  416. }
  417. // 不管是否已有历史病历,选项列表(民族/职业/学历...)都要加载,否则新用户第一次填表时全部选择项空白
  418. this.makeFromData(docId,hosId)
  419. },
  420. async getUserSelect() {
  421. const res = await request('user', 'get_case_select', { openId: currentOpenId() })
  422. if (res.code === 200) {
  423. let pickerArr = res.data;
  424. for(let key in pickerArr){
  425. this.pickerEchoShow(pickerArr[key],this.baseFormData[key],key)
  426. }
  427. this.selectData = Object.assign({}, this.selectData, pickerArr);
  428. this.getDoctor(this.baseFormData.hospital_id)
  429. }
  430. },
  431. async getDoctor(hosId) {
  432. const res = await request('user', 'get_doctor_select', { hospital_id: hosId })
  433. if (res.code === 200) {
  434. this.doctorRange = this.objToArr(res.data);
  435. this.pickerEchoShow(this.doctorRange,this.baseFormData.doctor_id,'doctor')
  436. }
  437. },
  438. async submitForm() {
  439. this.baseFormData.days = this.baseFormData.days + this.unitSubmit;
  440. const res = await request('user', 'update_case_info', this.baseFormData)
  441. if (res.code === 200) {
  442. uni.navigateTo({
  443. url:"/pages/sickForm/blurb?finish=" + this.isFinish
  444. });
  445. } else {
  446. console.error('update_case_info failed', res)
  447. }
  448. },
  449. objToArr(obj){
  450. let arr = [];
  451. for(let key in obj) {
  452. arr.push({ text: obj[key], value: Number(key) })
  453. }
  454. return arr;
  455. },
  456. }
  457. }
  458. </script>
  459. <style lang="scss" scoped>
  460. .content {
  461. .self-inf {
  462. height: 400rpx;
  463. width: 100%;
  464. background-image: url('/static/common-header-bg.jpg');
  465. background-size: contain;
  466. background-repeat: no-repeat;
  467. .img-title-box {
  468. display: flex;
  469. flex-direction: column;
  470. padding: 40rpx;
  471. .title {
  472. font-size: 40rpx;
  473. color: #000;
  474. margin-top: 100rpx;
  475. }
  476. .content{
  477. font-size: 28rpx;
  478. color: #999999;
  479. margin: 20rpx 0 20rpx 0;
  480. }
  481. .footer{
  482. font-size: 24rpx;
  483. border: 1px solid #f97631;
  484. color: #f97631;
  485. padding: 5rpx;
  486. width: 136rpx;
  487. }
  488. }
  489. }
  490. }
  491. .example {
  492. padding: 0 20rpx 140rpx;
  493. }
  494. .picker-class-box {
  495. color: #333;
  496. }
  497. .footer-btn {
  498. width: 94%;
  499. height: 100rpx;
  500. margin-left: 3%;
  501. color: #fff;
  502. background-color: #37a7ed;
  503. border-radius: 10rpx;
  504. display: flex;
  505. justify-content: center;
  506. align-items: center;
  507. font-size: 36rpx;
  508. }
  509. </style>