customerEdit.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. <template>
  2. <div class="formwrap">
  3. <el-tabs v-model="activeName" @tab-click="handleClick">
  4. <el-tab-pane label="用户管理" name="customerEdit">
  5. <el-form ref="editForm" :model="formmodel" :rules="rules" label-width="140px">
  6. <el-row>
  7. <el-col :span="8">
  8. <el-form-item label="用户姓名" prop="named">
  9. <el-input v-model="formmodel.named" clearable placeholder="请输入姓名" :maxlength="20" />
  10. </el-form-item>
  11. </el-col>
  12. <el-col :span="8">
  13. <el-form-item label="用户编号">
  14. <el-input v-model="formmodel.card_no" clearable placeholder="请输入用户编号" :maxlength="20" />
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="8">
  18. <el-form-item label="年龄" prop="age">
  19. <el-input v-model="formmodel.age" clearable :maxlength="4" placeholder="请输入年龄">
  20. <el-select slot="append" v-model="formmodel.age_unit" placeholder="请选择年龄单位">
  21. <el-option label="岁" value="岁" />
  22. <el-option label="月" value="月" />
  23. <el-option label="天" value="天" />
  24. </el-select>
  25. </el-input>
  26. </el-form-item>
  27. </el-col>
  28. </el-row>
  29. <el-row>
  30. <el-col :span="8">
  31. <el-form-item label="性别" class="form-item-sex">
  32. <el-radio v-model="formmodel.sex" :label="1">男</el-radio>
  33. <el-radio v-model="formmodel.sex" :label="0">女</el-radio>
  34. <el-radio v-model="formmodel.sex" :label="3">未知</el-radio>
  35. </el-form-item>
  36. </el-col>
  37. <el-col :span="8">
  38. <el-form-item label="在院状态">
  39. <el-radio v-model="formmodel.status" :label="0">在院</el-radio>
  40. <el-radio v-model="formmodel.status" :label="1">已出院</el-radio>
  41. </el-form-item>
  42. </el-col>
  43. <el-col :span="8">
  44. <el-form-item label="证件类型">
  45. <el-radio v-model="formmodel.id_type" label="身份证">身份证</el-radio>
  46. <el-radio v-model="formmodel.id_type" label="护照">护照</el-radio>
  47. <el-radio v-model="formmodel.id_type" label="军人证">军人证</el-radio>
  48. </el-form-item>
  49. </el-col>
  50. </el-row>
  51. <el-row>
  52. <el-col :span="8">
  53. <el-form-item label="证件号">
  54. <el-input v-model="formmodel.id_no" clearable placeholder="请输入证件号" :maxlength="20" />
  55. </el-form-item>
  56. </el-col>
  57. <el-col :span="8">
  58. <el-form-item label="入院日期" prop="in_date">
  59. <el-date-picker
  60. v-model="formmodel.in_date"
  61. type="date"
  62. :editable="false"
  63. value-format="timestamp"
  64. placeholder="选择入院日期"
  65. :picker-options="{disabledDate(time) { return time.getTime() > Date.now() }}"
  66. />
  67. </el-form-item>
  68. </el-col>
  69. <el-col :span="8">
  70. <el-form-item label="出院日期" prop="out_date">
  71. <el-date-picker
  72. v-model="formmodel.out_date"
  73. type="date"
  74. :editable="false"
  75. value-format="timestamp"
  76. placeholder="选择出院日期"
  77. :picker-options="{disabledDate(time) { return time.getTime() < Date.now() }}"
  78. />
  79. </el-form-item>
  80. </el-col>
  81. </el-row>
  82. <el-row>
  83. <el-col :span="8">
  84. <el-form-item label="责任医生">
  85. <el-select v-model="formmodel.doctor_id" placeholder="请选择医生" @change="doctorChange(1)">
  86. <el-option v-for="(item,index) in doctors" :key="index" :label="item.clerk_name" :value="item.clerk_id" />
  87. </el-select>
  88. </el-form-item>
  89. </el-col>
  90. <el-col :span="8">
  91. <el-form-item label="责任护士">
  92. <el-select v-model="formmodel.nurse_id" placeholder="请选择护士" @change="doctorChange(2)">
  93. <el-option v-for="(item,index) in nurses" :key="index" :label="item.clerk_name" :value="item.clerk_id" />
  94. </el-select>
  95. </el-form-item>
  96. </el-col>
  97. <el-col :span="8">
  98. <el-form-item label="责任护工">
  99. <el-select v-model="formmodel.worker_id" placeholder="请选择护工" @change="doctorChange(3)">
  100. <el-option v-for="(item,index) in workrs" :key="index" :label="item.clerk_name" :value="item.clerk_id" />
  101. </el-select>
  102. </el-form-item>
  103. </el-col>
  104. </el-row>
  105. <el-row v-if="nurseData.length > 0">
  106. <el-col v-for="(item, index) in nurseList" :key="index" :span="24 / nurseList.length">
  107. <el-form-item :label="item[0]">
  108. <el-select v-model="nurseData[index].nurse_level" :placeholder="'请选择'+item[0]" @change="changeNurseData(index)">
  109. <el-option v-for="(t,i) in item[1]" :key="i" :label="t.option_name" :value="t.id">
  110. <span style="float: left">{{ t.option_name }}</span>
  111. <span :style="'float: right; background-color: #'+t.color_rgb+';color: #'+t.color_rgb">颜色</span>
  112. </el-option>
  113. </el-select>
  114. </el-form-item>
  115. </el-col>
  116. </el-row>
  117. <el-row>
  118. <el-col :span="16">
  119. <el-form-item label="病况描述">
  120. <el-input
  121. v-model="formmodel.illness_desc"
  122. type="textarea"
  123. :autosize="{ minRows: 2, maxRows: 4}"
  124. :minlength="2"
  125. :maxlength="50"
  126. :placeholder="'请输入文本内容,长度2~50'"
  127. />
  128. </el-form-item>
  129. </el-col>
  130. </el-row>
  131. <el-form-item style="margin-top:15px;">
  132. <el-button type="primary" :disabled="isDisabled" class="save" @click="handlerSubmit('editForm')">保存修改</el-button>
  133. </el-form-item>
  134. </el-form>
  135. <el-card v-if="this.customerId != 0" style="maring:15px">
  136. <div>
  137. <div style="float: left"><h4>用户备注</h4></div>
  138. <div style="float: right">
  139. <el-button type="success" @click="dialogAddVisible = true">添加备注</el-button>
  140. </div>
  141. </div>
  142. <div style="clear:both">
  143. <div>
  144. <el-card v-for="(item, index) in tableData" :key="index">
  145. <div>
  146. <span style="margin-left: 20px;font-weight:bold">备注内容:</span><span style="line-height:1.5">{{ item.content }}</span>
  147. </div>
  148. <div style="margin: 10px">
  149. <div style="float: left">
  150. <span v-if="item.file_name">
  151. <el-link :href="item.file_path" icon="el-icon-folder" type="success" target="_blank" :download="item.file_name">{{ item.file_name }}</el-link>
  152. </span>
  153. </div>
  154. <div style="float: right">
  155. <p>
  156. <span style="font-weight:bold">创建时间:</span>{{ forDate(item.create_time) }}
  157. <span style="font-weight:bold;margin-left: 10px;">创建人:</span>{{ item.create_name }}
  158. </p>
  159. </div>
  160. </div>
  161. </el-card>
  162. <!--翻页-->
  163. <el-pagination
  164. v-if="pageData"
  165. slot="pagination"
  166. :current-page="pageData.page_no"
  167. :page-sizes="[10, 30, 50, 100]"
  168. :page-size="pageData.page_size"
  169. layout="total, sizes, prev, pager, next, jumper"
  170. :total="pageData.data_total"
  171. @size-change="handlePageSizeChange"
  172. @current-change="handlePageCurrentChange"
  173. />
  174. </div>
  175. </div>
  176. </el-card>
  177. <el-dialog title="添加用户备注" :visible.sync="dialogAddVisible" :append-to-body="true" width="80%">
  178. <el-form ref="editForm" :model="formmodel" :rules="rules" label-width="140px">
  179. <el-form-item label="内容" prop="content">
  180. <el-input
  181. v-model="content"
  182. type="textarea"
  183. :autosize="{ minRows: 2, maxRows: 6}"
  184. :minlength="2"
  185. :maxlength="300"
  186. show-word-limit
  187. :placeholder="'请输入文本内容,长度300'"
  188. />
  189. </el-form-item>
  190. <el-form-item label="附件">
  191. <el-upload
  192. v-if="!filePath"
  193. class="avatar-uploader"
  194. :action="`${uploadServer}?scene=avatar`"
  195. :show-file-list="false"
  196. :on-success="uploaded"
  197. :before-upload="handleShopLogoBefore"
  198. >
  199. <i class="el-icon-plus avatar-uploader-icon" />
  200. </el-upload>
  201. <span v-if="filePath">{{ fileName }}</span>
  202. </el-form-item>
  203. <el-form-item>
  204. <el-button type="primary" @click="addRemark">立即添加</el-button>
  205. <el-button @click="quxiao">取消</el-button>
  206. </el-form-item>
  207. </el-form>
  208. </el-dialog>
  209. </el-tab-pane>
  210. <el-tab-pane v-if="customerId != 0" label="用户亲属" name="customer-relative">
  211. <customer-relative :member-id="memberId" />
  212. </el-tab-pane>
  213. </el-tabs>
  214. </div>
  215. </template>
  216. <script>
  217. import * as customer_API from '@/api/ncs_customer'
  218. import * as clerk_API from '@/api/ncs_clerk'
  219. import * as NurseConfig_API from '@/api/ncs_nurse_config'
  220. import * as remark_API from '@/api/ncs_remark'
  221. import * as RegExp from '@/utils/RegExp'
  222. import { unixToDate } from '@/utils/Foundation'
  223. // import { serverUrl } from '@/utils/domain'
  224. import customerRelative from '@/views/customer/customer_relative'
  225. const serverUrl = domain.serverUrl
  226. export default {
  227. name: 'PatientInfoEdit',
  228. components: { customerRelative },
  229. props: {
  230. customerId: {
  231. type: Number,
  232. default: 0
  233. },
  234. frameId: {
  235. type: Number,
  236. default: 0
  237. }
  238. },
  239. data: function() {
  240. return {
  241. formmodel: {
  242. sex: 1,
  243. status: 0,
  244. age_unit: '岁',
  245. id_type: '身份证',
  246. part_id: this.$store.getters.partId
  247. },
  248. nurseList: [],
  249. nurseData: [],
  250. nurseConfigDtos: [],
  251. rules: {
  252. named: [
  253. this.MixinRequired('请输入真实姓名!'),
  254. { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' },
  255. {
  256. validator: (rule, value, callback) => {
  257. if (!RegExp.userName.test(value)) {
  258. callback(new Error('只支持汉字、字母、数字、“-”、“_”的组合!'))
  259. } else {
  260. callback()
  261. }
  262. }
  263. }
  264. ],
  265. age: [{ required: true, message: '请输入年龄', trigger: 'blur' }],
  266. content: [{ required: true, message: '请输入备注内容', trigger: 'blur' }],
  267. in_date: [{ required: true, message: '请选择入院日期', trigger: 'blur' }]
  268. },
  269. isDisabled: false,
  270. doctors: [],
  271. nurses: [],
  272. workrs: [],
  273. doctor_mapping_id: false,
  274. nurse_Mapping_id: false,
  275. worker_mapping_id: false,
  276. params: {
  277. page_size: 10,
  278. page_no: 1,
  279. sort: 'create_time',
  280. dir: 'desc'
  281. },
  282. tableData: [],
  283. pageData: [],
  284. dialogAddVisible: false,
  285. fileName: null,
  286. filePath: null,
  287. uploadServer: serverUrl + '/ncs/upload/uploadFile',
  288. userInfo: this.$store.getters.userInfo,
  289. content: null,
  290. activeName: 'customerEdit',
  291. memberId: null
  292. }
  293. },
  294. watch: {
  295. frameId: function(newval) {
  296. this.getNurseConfigs()
  297. this.hasCustomerId()
  298. }
  299. },
  300. mounted() {
  301. this.getEmployees()
  302. if (this.nurseList.length === 0) {
  303. this.getNurseConfigs()
  304. this.hasCustomerId()
  305. }
  306. },
  307. methods: {
  308. getEmployees() {
  309. const _this = this
  310. clerk_API.listByPartRoleId({ partId: this.$store.getters.partId }).then(res => {
  311. const groupBy = (arr, func) =>
  312. arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
  313. acc[val] = (acc[val] || []).concat(arr[i])
  314. return acc
  315. }, {})
  316. const groupData = groupBy(res, item => item.role_name)
  317. if (Object.entries(groupData).length > 0) {
  318. Object.entries(groupData).forEach(item => {
  319. if (item[0] === '医生') {
  320. _this.doctors = item[1]
  321. } else if (item[0] === '护士') {
  322. _this.nurses = item[1]
  323. } else if (item[0] === '护工') {
  324. _this.workrs = item[1]
  325. }
  326. })
  327. }
  328. })
  329. },
  330. getNurseConfigs() {
  331. this.nurseData = []
  332. const _this = this
  333. NurseConfig_API.listByPartId({ partId: this.$store.getters.partId }).then(res => {
  334. const groupBy = (arr, func) =>
  335. arr.map(typeof func === 'function' ? func : val => val[func]).reduce((acc, val, i) => {
  336. acc[val] = (acc[val] || []).concat(arr[i])
  337. return acc
  338. }, {})
  339. // 以参数名称来分组
  340. const groupData = groupBy(res, item => item.config_name)
  341. _this.nurseList = Object.entries(groupData)
  342. if (_this.nurseList.length > 0) {
  343. _this.nurseList.forEach((item, index) => {
  344. _this.nurseData.push({ nurse_level: null, id: null, nurse_config: item[1][0].ncfg_id })
  345. })
  346. }
  347. })
  348. },
  349. hasCustomerId() {
  350. this.clearForm()
  351. if (this.customerId !== 0) {
  352. const _this = this
  353. customer_API.getCustomerInfo(this.customerId).then(res => {
  354. _this.formmodel = res
  355. _this.doctor_mapping_id = res.doctor_mapping_id
  356. _this.nurse_Mapping_id = res.nurse_Mapping_id
  357. _this.worker_mapping_id = res.worker_mapping_id
  358. _this.formmodel.doctor_mapping_id = null
  359. _this.formmodel.nurse_Mapping_id = null
  360. _this.formmodel.worker_mapping_id = null
  361. if (_this.formmodel.in_date) {
  362. _this.formmodel.in_date = _this.formmodel.in_date * 1000
  363. }
  364. if (_this.formmodel.out_date) {
  365. _this.formmodel.out_date = _this.formmodel.out_date * 1000
  366. }
  367. console.log(_this.formmodel.in_date, _this.formmodel.out_date)
  368. _this.getRemarks()
  369. if (res.list !== null) {
  370. _this.nurseData.forEach((item, index) => {
  371. res.list.forEach((t, i) => { // 为护理项赋值
  372. if (item.nurse_config === t.nurse_config) {
  373. item.nurse_level = t.nurse_level
  374. item.id = t.id
  375. }
  376. })
  377. })
  378. }
  379. })
  380. }
  381. },
  382. doctorChange(type) {
  383. if (this.customerId !== 0) {
  384. if (type === 1) {
  385. if (this.doctor_mapping_id === null) {
  386. this.formmodel.doctor_mapping_id = 0 // 为0则新增,// 其他值为修改
  387. } else {
  388. this.formmodel.doctor_mapping_id = this.doctor_mapping_id
  389. }
  390. } else if (type === 2) {
  391. if (this.nurse_Mapping_id === null) {
  392. this.formmodel.nurse_Mapping_id = 0 // 为0则新增,// 其他值为修改
  393. } else {
  394. this.formmodel.nurse_Mapping_id = this.nurse_Mapping_id
  395. }
  396. } else {
  397. if (this.worker_mapping_id === null) {
  398. this.formmodel.worker_mapping_id = 0 // 为0则新增,// 其他值为修改
  399. } else {
  400. this.formmodel.worker_mapping_id = this.worker_mapping_id
  401. }
  402. }
  403. }
  404. },
  405. /** 保存按钮处理事件 */
  406. handlerSubmit(formName) {
  407. this.$refs[formName].validate(valid => {
  408. if (valid) {
  409. this.isDisabled = true
  410. if (this.formmodel.in_date) {
  411. this.formmodel.in_date = this.formmodel.in_date / 1000
  412. }
  413. if (this.formmodel.out_date) {
  414. this.formmodel.out_date = this.formmodel.out_date / 1000
  415. }
  416. if (this.customerId === 0) {
  417. this.formmodel.frame_id = this.frameId
  418. this.formmodel.list = this.nurseConfigDtos
  419. customer_API.addAll(this.formmodel).then(res => {
  420. this.$message.success(this.$t('action.addSuccess2'))
  421. this.clearForm()
  422. this.$emit('saved')
  423. }).catch(e => {
  424. this.isDisabled = false
  425. })
  426. } else {
  427. this.formmodel.list = this.nurseConfigDtos
  428. customer_API.updateAll(this.formmodel).then(res => {
  429. this.$message.success(this.$t('action.editSuccess'))
  430. this.isDisabled = false
  431. this.$emit('saved')
  432. })
  433. }
  434. } else {
  435. this.$message.error(this.$t('action.fromError'))
  436. return false
  437. }
  438. })
  439. },
  440. clearForm() {
  441. this.activeName = 'customerEdit'
  442. this.formmodel = {
  443. sex: 1,
  444. status: 0,
  445. age_unit: '岁',
  446. id_type: '身份证',
  447. part_id: this.$store.getters.partId,
  448. named: null,
  449. card_no: null,
  450. id_no: null,
  451. in_date: new Date(new Date().toLocaleDateString()).getTime(),
  452. out_date: null,
  453. doctor_id: null,
  454. nurse_id: null,
  455. worker_id: null,
  456. illness_desc: null
  457. }
  458. this.isDisabled = false
  459. this.nurseConfigDtos = []
  460. },
  461. // 选择了护理项
  462. changeNurseData(index) {
  463. const i = this.nurseConfigDtos.findIndex(item => {
  464. return item.nurse_level === this.nurseData[index].nurse_level
  465. })
  466. if (i !== -1) {
  467. this.nurseConfigDtos.splice(i, 1)
  468. }
  469. this.nurseConfigDtos.push(this.nurseData[index])
  470. },
  471. getRemarks() {
  472. const _this = this
  473. this.params.fixedCondition = ' part_id=' + this.$store.getters.partId + ' and type=1 and member_id = ' + this.formmodel.member_id
  474. remark_API.getRemarks(this.params).then(res => {
  475. _this.tableData = res.data
  476. _this.pageData = {
  477. page_no: res.page_no,
  478. page_size: res.page_size,
  479. data_total: res.data_total
  480. }
  481. })
  482. },
  483. /** 分页大小发生改变 */
  484. handlePageSizeChange(size) {
  485. this.params.page_size = size
  486. this.getRemarks()
  487. },
  488. /** 分页页数发生改变 */
  489. handlePageCurrentChange(page) {
  490. this.params.page_no = page
  491. this.getRemarks()
  492. },
  493. forDate(date) {
  494. return unixToDate(date)
  495. },
  496. /** 上传成功后的钩子 更换图片 置空存储数组*/
  497. uploaded(res) {
  498. this.filePath = serverUrl + '/' + res
  499. },
  500. /** 图片上传之前的校验 */
  501. handleShopLogoBefore(file) {
  502. const _this = this
  503. return new Promise((resolve, reject) => {
  504. let hz = file.name
  505. _this.fileName = hz
  506. const index = hz.lastIndexOf('.')
  507. hz = hz.substring(index + 1, hz.length)
  508. const isImg = hz === 'jpeg' || hz === 'png' || hz === 'jpg' || hz === 'txt' || hz === 'doc' || hz === 'docx' || hz === 'xls' || hz === 'xlsx'
  509. const isLt5M = file.size / 1024 / 1024 < 5
  510. if (!isImg) {
  511. _this.$message.error('上传附件只能是txt,doc,docx,xls,xlsx,jpg,png,jpeg格式!')
  512. reject()
  513. }
  514. if (!isLt5M) {
  515. _this.$message.error('上传附件大小不能超过 5MB!')
  516. reject()
  517. }
  518. resolve()
  519. })
  520. },
  521. addRemark() {
  522. if (!this.content) {
  523. this.$message.info('请输入内容!')
  524. return
  525. }
  526. if (!this.filePath) {
  527. this.fileName = null
  528. }
  529. const data = {
  530. partId: this.$store.getters.partId,
  531. type: 1,
  532. memberId: this.formmodel.member_id,
  533. createName: this.userInfo.username,
  534. content: this.content,
  535. filePath: this.filePath,
  536. fileName: this.fileName
  537. }
  538. const _this = this
  539. remark_API.save(data).then(res => {
  540. _this.$message.success(this.$t('action.addSuccess2'))
  541. _this.getRemarks()
  542. _this.quxiao()
  543. })
  544. },
  545. quxiao() {
  546. this.dialogAddVisible = false
  547. this.content = null
  548. this.fileName = null
  549. this.filePath = null
  550. },
  551. handleClick(tab) {
  552. this.memberId = this.formmodel.member_id
  553. }
  554. }
  555. }
  556. </script>
  557. <style type="text/scss" scoped>
  558. .el-input .el-select {
  559. width: 68px;
  560. }
  561. .el-select {
  562. width: 100%;
  563. }
  564. .formwrap {
  565. border: 1px solid #ebebeb;
  566. border-radius: 3px;
  567. background: #fff;
  568. padding: 24px;
  569. min-height: 500px;
  570. }
  571. /deep/ .avatar-uploader .el-upload {
  572. border: 1px dashed #d9d9d9;
  573. border-radius: 6px;
  574. cursor: pointer;
  575. position: relative;
  576. overflow: hidden;
  577. }
  578. /deep/ .avatar-uploader .el-upload:hover {
  579. border-color: #409EFF;
  580. }
  581. /deep/ .avatar-uploader-icon {
  582. font-size: 28px;
  583. color: #8c939d;
  584. width: 100px;
  585. height: 100px;
  586. line-height: 100px;
  587. text-align: center;
  588. }
  589. /deep/ .avatar {
  590. width: 100px;
  591. height: 100px;
  592. display: block;
  593. }
  594. </style>