searchDept.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. <template>
  2. <view class="content">
  3. <view class="search-box">
  4. <seiminSearch class="mSearch-input-box" :mode="2" button="inside" placeholder="输入科室名称支持拼音检索"
  5. @search="doSearch(false)" @input="changeInp" @confirm="doSearch(false)" v-model="keyword"></seiminSearch>
  6. </view>
  7. <view class="search-keyword">
  8. <scroll-view class="keyword-list-box" v-show="isShowKeywordList" scroll-y>
  9. <block v-for="(row, index) in keywordList" :key="index">
  10. <view class="keyword-entry" hover-class="keyword-entry-tap">
  11. <view class="keyword-text" @tap.stop="doSearch(keywordList[index].keyword)">
  12. <rich-text :nodes="row.htmlStr"></rich-text>
  13. </view>
  14. <view class="keyword-img" @tap.stop="doSearch(keywordList[index].keyword)">
  15. <image src="/static/HM-search/back.png"></image>
  16. </view>
  17. </view>
  18. </block>
  19. </scroll-view>
  20. <scroll-view class="keyword-box" v-show="!isShowKeywordList" scroll-y>
  21. <view class="keyword-block" v-if="oldKeywordList.length > 0">
  22. <view class="keyword-list-header">
  23. <view>历史搜索</view>
  24. <view>
  25. <image @tap="oldDelete" src="/static/HM-search/delete.png"></image>
  26. </view>
  27. </view>
  28. <view class="keyword">
  29. <view v-for="(keyword, index) in oldKeywordList" @tap="changeInp(keyword)" :key="index">{{ keyword }}
  30. </view>
  31. </view>
  32. </view>
  33. </scroll-view>
  34. </view>
  35. <seiminModel ref="seiminModel"></seiminModel>
  36. </view>
  37. </template>
  38. <script>
  39. import {
  40. backPress
  41. } from '../../utils/index.js';
  42. import {
  43. reqFetchDataList,
  44. reqChangeHospital,
  45. reqUpdData,
  46. reqGetCurrentUser,
  47. } from "../../request/api.js";
  48. import {
  49. mapState,
  50. mapMutations
  51. } from "vuex";
  52. import {
  53. DEPARTMENT_STRATEGY
  54. } from "../../utils/enum.departmentStrategy.js";
  55. export default {
  56. onBackPress() {
  57. backPress();
  58. },
  59. data() {
  60. return {
  61. reFresh: '',
  62. DEPARTMENT_STRATEGY,
  63. keyword: "",
  64. oldKeywordList: [],
  65. keywordList: [],
  66. isShowKeywordList: false,
  67. deptList: [],
  68. timer: null, //定时器
  69. searchText: "", //搜索文本
  70. searchData: [], //搜索结果
  71. };
  72. },
  73. computed: {
  74. ...mapState("login", ["loginInfo"]),
  75. ...mapState('other', [
  76. "deptDisplay",
  77. "searchDeptParams",
  78. "searchDeptResult",
  79. "searchDeptResultList",
  80. ]),
  81. },
  82. onUnload() {
  83. if (this.timer) {
  84. clearTimeout(this.timer);
  85. this.timer = null;
  86. }
  87. },
  88. onLoad(options) {
  89. this.init();
  90. },
  91. methods: {
  92. ...mapMutations('other', [
  93. "changeSearchDeptResult",
  94. "changeSeiminModel",
  95. "changeSearchDeptResultList",
  96. ]),
  97. ...mapMutations("login", ["changeLoginInfo"]),
  98. init() {
  99. this.loadOldKeyword();
  100. },
  101. blur() {
  102. uni.hideKeyboard();
  103. },
  104. //加载历史搜索,自动读取本地Storage
  105. loadOldKeyword() {
  106. uni.getStorage({
  107. key: "OldKeys",
  108. success: (res) => {
  109. var OldKeys = JSON.parse(res.data);
  110. this.oldKeywordList = OldKeys;
  111. },
  112. });
  113. },
  114. //防抖搜索
  115. changeInp(event) {
  116. this.searchText = event;
  117. clearTimeout(this.timer);
  118. this.timer = setTimeout(() => {
  119. this.inputChange(event);
  120. }, 500);
  121. },
  122. //监听输入
  123. inputChange(event) {
  124. //兼容引入组件时传入参数情况
  125. var keyword = event.detail ? event.detail.value : event;
  126. if (!keyword) {
  127. this.keywordList = [];
  128. this.isShowKeywordList = false;
  129. return;
  130. }
  131. this.keyword = keyword;
  132. this.isShowKeywordList = true;
  133. let postData = {
  134. idx: 0,
  135. sum: 20,
  136. department: {},
  137. };
  138. // 院区参数----start
  139. if (this.searchDeptParams.type === "changeDept_index") {
  140. //首页切换科室
  141. postData.department.hospital = {
  142. id: this.searchDeptParams.hospital.value,
  143. };
  144. postData.department.keyWord = keyword;
  145. postData.department.nurseSign = 1;
  146. } else if (
  147. this.searchDeptParams.type === "selectDept_start_qucikCreateOrder" ||
  148. this.searchDeptParams.type === "selectDept_end_qucikCreateOrder"
  149. ) {
  150. //快捷建单选择起点科室或选择终点科室
  151. postData.department.hospital = {
  152. id: this.loginInfo.user.currentHospital.id,
  153. };
  154. postData.department.searchType = 1;
  155. postData.department.ids = this.searchDeptParams.ids;
  156. postData.department.keyWord = keyword;
  157. postData.department.nurseSign = 1;
  158. if (this.searchDeptParams.departmentStrategy == this.DEPARTMENT_STRATEGY['固定科室类型']) {
  159. // 固定科室类型
  160. postData.department.type = {
  161. id: this.searchDeptParams.deptType,
  162. };
  163. }
  164. } else {
  165. postData.department.hospital = {
  166. id: this.loginInfo.user.currentHospital.id,
  167. };
  168. // 科室名称或科室别称开关----start
  169. if (this.deptDisplay == 1) {
  170. //科室名称
  171. postData.department.dept = keyword;
  172. } else if (this.deptDisplay == 2) {
  173. //科室别称
  174. postData.department.deptalias = keyword;
  175. }
  176. // 科室名称或科室别称开关----end
  177. }
  178. // 院区参数----end
  179. uni.showLoading({
  180. title: "加载中",
  181. mask: true,
  182. });
  183. reqFetchDataList("data", "department", postData).then((res) => {
  184. uni.hideLoading();
  185. if (res.status == 200) {
  186. this.searchData.push({
  187. name: keyword,
  188. list: res.list || [],
  189. });
  190. let searchText = this.searchText.detail ?
  191. this.searchText.detail.value :
  192. this.searchText;
  193. let index = this.searchData.findIndex(
  194. (item) => item.name === searchText
  195. );
  196. this.deptList = index >= 0 ? this.searchData[index].list : [];
  197. this.keywordList = this.drawCorrelativeKeyword(
  198. this.deptList,
  199. keyword
  200. );
  201. } else {
  202. this.$refs.seiminModel.show({
  203. skin: "toast",
  204. icon: "error",
  205. content: res.msg || "获取数据失败",
  206. });
  207. throw new Error(res.msg || "获取数据失败");
  208. }
  209. });
  210. },
  211. //高亮关键字
  212. drawCorrelativeKeyword(keywords, keyword) {
  213. var len = keywords.length,
  214. keywordArr = [];
  215. for (var i = 0; i < len; i++) {
  216. var row = keywords[i];
  217. //定义高亮#9f9f9f
  218. var html = "";
  219. if (this.deptDisplay == 1) {
  220. // 科室名称
  221. html = row.dept.replace(
  222. keyword,
  223. "<span style='color: #9f9f9f;'>" + keyword + "</span>"
  224. );
  225. } else if (this.deptDisplay == 2) {
  226. // 科室别称
  227. html = row.deptalias.replace(
  228. keyword,
  229. "<span style='color: #9f9f9f;'>" + keyword + "</span>"
  230. );
  231. }
  232. html = "<div>" + html + "</div>";
  233. var tmpObj = {
  234. keyword: this.deptDisplay == 1 ? row.dept : row.deptalias,
  235. htmlStr: html,
  236. };
  237. keywordArr.push(tmpObj);
  238. }
  239. return keywordArr;
  240. },
  241. //清除历史搜索
  242. oldDelete() {
  243. uni.showModal({
  244. content: "确定清除历史搜索记录?",
  245. success: (res) => {
  246. if (res.confirm) {
  247. console.log("用户点击确定");
  248. this.oldKeywordList = [];
  249. uni.removeStorage({
  250. key: "OldKeys",
  251. });
  252. } else if (res.cancel) {
  253. console.log("用户点击取消");
  254. }
  255. },
  256. });
  257. },
  258. //执行搜索
  259. doSearch(keyword) {
  260. keyword = keyword === false ? this.keyword : keyword;
  261. this.keyword = keyword;
  262. this.saveKeyword(keyword); //保存为历史
  263. let arr = this.deptList.filter((item) => {
  264. return this.deptDisplay == 1 ?
  265. item.dept === keyword :
  266. item.deptalias === keyword;
  267. });
  268. if (arr.length) {
  269. this.changeSearchDeptResult(arr[0]);
  270. if (this.searchDeptParams.type === "changeDept_index") {
  271. //首页切换科室
  272. this.changeDept_index_handler();
  273. } else if (
  274. this.searchDeptParams.type === "selectDept_start_qucikCreateOrder"
  275. ) {
  276. //快捷建单选择起点科室
  277. this.searchDeptResultList.start = arr[0];
  278. this.changeSearchDeptResultList(this.searchDeptResultList);
  279. this.selectDept_startOrEnd_qucikCreateOrder();
  280. } else if (
  281. this.searchDeptParams.type === "selectDept_end_qucikCreateOrder"
  282. ) {
  283. //快捷建单选择终点科室
  284. this.searchDeptResultList.end = arr[0];
  285. this.changeSearchDeptResultList(this.searchDeptResultList);
  286. this.selectDept_startOrEnd_qucikCreateOrder();
  287. }
  288. }
  289. },
  290. //保存关键字到历史记录
  291. saveKeyword(keyword) {
  292. uni.getStorage({
  293. key: "OldKeys",
  294. success: (res) => {
  295. var OldKeys = JSON.parse(res.data);
  296. var findIndex = OldKeys.indexOf(keyword);
  297. if (findIndex == -1) {
  298. OldKeys.unshift(keyword);
  299. } else {
  300. OldKeys.splice(findIndex, 1);
  301. OldKeys.unshift(keyword);
  302. }
  303. //最多10个纪录
  304. OldKeys.length > 10 && OldKeys.pop();
  305. uni.setStorage({
  306. key: "OldKeys",
  307. data: JSON.stringify(OldKeys),
  308. });
  309. this.oldKeywordList = OldKeys; //更新历史搜索
  310. },
  311. fail: (e) => {
  312. var OldKeys = [keyword];
  313. uni.setStorage({
  314. key: "OldKeys",
  315. data: JSON.stringify(OldKeys),
  316. });
  317. this.oldKeywordList = OldKeys; //更新历史搜索
  318. },
  319. });
  320. },
  321. //首页切换科室
  322. changeDept_index_handler() {
  323. if (this.searchDeptParams.type === "changeDept_index") {
  324. // 首页切换科室
  325. uni.showLoading({
  326. title: "加载中",
  327. mask: true,
  328. });
  329. if (
  330. this.loginInfo.user.currentHospital.id ==
  331. this.searchDeptParams.hospital.value
  332. ) {
  333. //没有切换院区
  334. this.changeDept_index_handler_common();
  335. } else {
  336. //切换院区
  337. reqChangeHospital({
  338. currentHosId: this.searchDeptParams.hospital.value,
  339. loginType: "PC",
  340. }).then((res) => {
  341. if (res.status == 200) {
  342. this.changeDept_index_handler_common();
  343. } else {
  344. uni.hideLoading();
  345. this.$refs.seiminModel.show({
  346. skin: "toast",
  347. icon: "error",
  348. content: res.msg || "操作失败",
  349. });
  350. throw new Error(res.msg || "操作失败");
  351. }
  352. });
  353. }
  354. }
  355. },
  356. // 首页切换科室,公共方法
  357. changeDept_index_handler_common() {
  358. // 更新用户
  359. reqUpdData("data", "user", {
  360. user: {
  361. dept: {
  362. id: this.searchDeptResult.id,
  363. },
  364. id: this.loginInfo.user.id,
  365. },
  366. }).then((res) => {
  367. if (res.status == 200) {
  368. // 获取当前登录用户信息
  369. reqGetCurrentUser().then((res) => {
  370. uni.hideLoading();
  371. if (res.status == 200) {
  372. this.$refs.seiminModel.show({
  373. skin: "toast",
  374. icon: "success",
  375. content: "切换科室成功",
  376. btns: [{
  377. click: (e) => {
  378. this.changeLoginInfo(res.data);
  379. this.changeSeiminModel(true);
  380. uni.navigateTo({
  381. url: this.searchDeptParams.backUrl,
  382. });
  383. },
  384. }, ],
  385. });
  386. } else {
  387. this.$refs.seiminModel.show({
  388. skin: "toast",
  389. icon: "error",
  390. content: res.msg || "操作失败",
  391. });
  392. throw new Error(res.msg || "操作失败");
  393. }
  394. });
  395. } else {
  396. uni.hideLoading();
  397. this.$refs.seiminModel.show({
  398. skin: "toast",
  399. icon: "error",
  400. content: res.msg || "操作失败",
  401. });
  402. throw new Error(res.msg || "操作失败");
  403. }
  404. });
  405. },
  406. // 快捷建单选择起点科室或选择终点科室
  407. selectDept_startOrEnd_qucikCreateOrder() {
  408. uni.navigateTo({
  409. url: this.searchDeptParams.backUrl,
  410. });
  411. },
  412. },
  413. };
  414. </script>
  415. <style lang="scss" scoped>
  416. view {
  417. display: block;
  418. }
  419. .search-box {
  420. background-color: rgb(242, 242, 242);
  421. padding: 15upx 2.5%;
  422. display: flex;
  423. justify-content: space-between;
  424. position: sticky;
  425. top: 0;
  426. }
  427. .search-box .mSearch-input-box {
  428. width: 100%;
  429. }
  430. .search-box .input-box {
  431. width: 85%;
  432. flex-shrink: 1;
  433. display: flex;
  434. justify-content: center;
  435. align-items: center;
  436. }
  437. .search-box .search-btn {
  438. width: 15%;
  439. margin: 0 0 0 2%;
  440. display: flex;
  441. justify-content: center;
  442. align-items: center;
  443. flex-shrink: 0;
  444. font-size: 28upx;
  445. color: #fff;
  446. background: linear-gradient(to right, #ff9801, #ff570a);
  447. border-radius: 60upx;
  448. }
  449. .search-box .input-box>input {
  450. width: 100%;
  451. height: 60upx;
  452. font-size: 32upx;
  453. border: 0;
  454. border-radius: 60upx;
  455. -webkit-appearance: none;
  456. -moz-appearance: none;
  457. appearance: none;
  458. padding: 0 3%;
  459. margin: 0;
  460. background-color: #ffffff;
  461. }
  462. .placeholder-class {
  463. color: #9e9e9e;
  464. }
  465. .search-keyword {
  466. width: 100%;
  467. background-color: rgb(242, 242, 242);
  468. }
  469. .keyword-list-box {
  470. height: calc(100vh - 110upx);
  471. padding-top: 10upx;
  472. border-radius: 20upx 20upx 0 0;
  473. background-color: #fff;
  474. }
  475. .keyword-entry-tap {
  476. background-color: #eee;
  477. }
  478. .keyword-entry {
  479. width: 94%;
  480. height: 80upx;
  481. margin: 0 3%;
  482. font-size: 30upx;
  483. color: #333;
  484. display: flex;
  485. justify-content: space-between;
  486. align-items: center;
  487. border-bottom: solid 1upx #e7e7e7;
  488. }
  489. .keyword-entry image {
  490. width: 60upx;
  491. height: 60upx;
  492. }
  493. .keyword-entry .keyword-text,
  494. .keyword-entry .keyword-img {
  495. height: 80upx;
  496. display: flex;
  497. align-items: center;
  498. }
  499. .keyword-entry .keyword-text {
  500. width: 90%;
  501. }
  502. .keyword-entry .keyword-img {
  503. width: 10%;
  504. justify-content: center;
  505. }
  506. .keyword-box {
  507. height: calc(100vh - 110upx);
  508. border-radius: 20upx 20upx 0 0;
  509. background-color: #fff;
  510. }
  511. .keyword-box .keyword-block {
  512. padding: 10upx 0;
  513. }
  514. .keyword-box .keyword-block .keyword-list-header {
  515. width: 94%;
  516. padding: 10upx 3%;
  517. font-size: 27upx;
  518. color: #333;
  519. display: flex;
  520. justify-content: space-between;
  521. }
  522. .keyword-box .keyword-block .keyword-list-header image {
  523. width: 40upx;
  524. height: 40upx;
  525. }
  526. .keyword-box .keyword-block .keyword {
  527. width: 94%;
  528. padding: 3px 3%;
  529. display: flex;
  530. flex-flow: wrap;
  531. justify-content: flex-start;
  532. }
  533. .keyword-box .keyword-block .hide-hot-tis {
  534. display: flex;
  535. justify-content: center;
  536. font-size: 28upx;
  537. color: #6b6b6b;
  538. }
  539. .keyword-box .keyword-block .keyword>view {
  540. display: flex;
  541. justify-content: center;
  542. align-items: center;
  543. border-radius: 60upx;
  544. padding: 0 20upx;
  545. margin: 10upx 20upx 10upx 0;
  546. height: 60upx;
  547. font-size: 28upx;
  548. background-color: rgb(242, 242, 242);
  549. color: #6b6b6b;
  550. }
  551. </style>