searchDept.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. <template>
  2. <div class="content">
  3. <div class="search-box">
  4. <seiminSearch
  5. class="mSearch-input-box"
  6. :mode="2"
  7. button="inside"
  8. placeholder="输入关键字"
  9. @search="doSearch(false)"
  10. @input="changeInp"
  11. @confirm="doSearch(false)"
  12. v-model="keyword"
  13. ></seiminSearch>
  14. </div>
  15. <div class="search-keyword">
  16. <cube-scroll class="keyword-list-box" v-show="isShowKeywordList">
  17. <div class="keyword-entry" v-for="(row, index) in keywordList" :key="index">
  18. <div
  19. class="keyword-text"
  20. @click.stop="doSearch(keywordList[index].keyword)"
  21. >
  22. <span v-html="row.htmlStr"></span>
  23. </div>
  24. <div
  25. class="keyword-img"
  26. @click.stop="doSearch(keywordList[index].keyword)"
  27. >
  28. <img src="../assets/HM-search/back.png" />
  29. </div>
  30. </div>
  31. </cube-scroll>
  32. <cube-scroll class="keyword-box" v-show="!isShowKeywordList">
  33. <div class="keyword-block" v-if="oldKeywordList.length > 0">
  34. <div class="keyword-list-header">
  35. <div>历史搜索</div>
  36. <div>
  37. <img @click="oldDelete" src="../assets/HM-search/delete.png" />
  38. </div>
  39. </div>
  40. <div class="keyword">
  41. <div
  42. v-for="(keyword, index) in oldKeywordList"
  43. @click="changeInp(keyword)"
  44. :key="index"
  45. >
  46. {{ keyword }}
  47. </div>
  48. </div>
  49. </div>
  50. </cube-scroll>
  51. </div>
  52. <!-- <seiminModel ref="seiminModel"></seiminModel> -->
  53. </div>
  54. </template>
  55. <script>
  56. import seiminSearch from "../custom/seiminSearch.vue";
  57. export default {
  58. components: {
  59. seiminSearch
  60. },
  61. data() {
  62. return {
  63. other: {},
  64. model: {},
  65. reFresh: "",
  66. keyword: "",
  67. oldKeywordList: [],
  68. keywordList: [],
  69. isShowKeywordList: false,
  70. deptList: [],
  71. timer: null, //定时器
  72. searchText: "", //搜索文本
  73. searchData: [] //搜索结果
  74. };
  75. },
  76. beforeDestroy() {
  77. if (this.timer) {
  78. clearTimeout(this.timer);
  79. this.timer = null;
  80. }
  81. },
  82. mounted() {
  83. if(this.$route.query.model){
  84. let other = JSON.parse(this.$route.query.other);
  85. this.model = JSON.parse(this.$route.query.model);
  86. this.other = other;
  87. }
  88. this.init();
  89. },
  90. methods: {
  91. // ...mapMutations('other', [
  92. // "changeSearchDeptResult",
  93. // "changeSeiminModel",
  94. // "changeSearchDeptResultList",
  95. // ]),
  96. // ...mapMutations("login", ["changeLoginInfo"]),
  97. init() {
  98. this.loadOldKeyword();
  99. },
  100. //加载历史搜索,自动读取本地Storage
  101. loadOldKeyword() {
  102. this.oldKeywordList = JSON.parse(localStorage.getItem("OldKeys")) || [];
  103. },
  104. //防抖搜索
  105. changeInp(event) {
  106. this.searchText = event;
  107. clearTimeout(this.timer);
  108. this.timer = setTimeout(() => {
  109. this.inputChange(event);
  110. }, 500);
  111. },
  112. //监听输入
  113. inputChange(event = "") {
  114. //兼容引入组件时传入参数情况
  115. var keyword = event.target ? event.target.value : event;
  116. if (!keyword) {
  117. this.keywordList = [];
  118. this.isShowKeywordList = false;
  119. return;
  120. }
  121. this.keyword = keyword;
  122. this.isShowKeywordList = true;
  123. let postData = {
  124. idx: 0,
  125. sum: 9999,
  126. incidentcategory: {
  127. category: keyword,
  128. selectType: "pinyin_qs",
  129. hierarchyQuery: "three"
  130. }
  131. };
  132. this.toast = this.$createToast({
  133. time: 0,
  134. mask: true,
  135. txt: "正在加载中"
  136. });
  137. this.toast.show();
  138. this.$http
  139. .post("service/user/data/fetchDataList/incidentcategory", postData)
  140. .then(res => {
  141. res = res.data;
  142. this.toast.hide();
  143. if (res.status == 200) {
  144. this.searchData.push({
  145. name: keyword,
  146. list: res.list || []
  147. });
  148. let searchText = this.searchText.detail
  149. ? this.searchText.detail.value
  150. : this.searchText;
  151. let index = this.searchData.findIndex(
  152. item => item.name === searchText
  153. );
  154. this.deptList = index >= 0 ? this.searchData[index].list : [];
  155. this.keywordList = this.drawCorrelativeKeyword(
  156. this.deptList,
  157. keyword
  158. );
  159. } else {
  160. this.$refs.seiminModel.show({
  161. skin: "toast",
  162. icon: "error",
  163. content: res.msg || "获取数据失败"
  164. });
  165. throw new Error(res.msg || "获取数据失败");
  166. }
  167. });
  168. },
  169. //高亮关键字
  170. drawCorrelativeKeyword(keywords, keyword) {
  171. var len = keywords.length,
  172. keywordArr = [];
  173. for (var i = 0; i < len; i++) {
  174. var row = keywords[i];
  175. //定义高亮#9f9f9f
  176. var html = "";
  177. // 科室名称
  178. html = row.mutiCategory.replace(
  179. keyword,
  180. "<span style='color: #9f9f9f;'>" + keyword + "</span>"
  181. );
  182. html = "<div>" + html + "</div>";
  183. var tmpObj = {
  184. keyword: row.mutiCategory,
  185. htmlStr: html
  186. };
  187. keywordArr.push(tmpObj);
  188. }
  189. return keywordArr;
  190. },
  191. //清除历史搜索
  192. oldDelete() {
  193. this.$createDialog({
  194. type: "confirm",
  195. icon: "cubeic-alert",
  196. title: "提示",
  197. content: "确定清除历史搜索记录?",
  198. confirmBtn: {
  199. text: "确定",
  200. active: true,
  201. disabled: false,
  202. href: "javascript:;"
  203. },
  204. cancelBtn: {
  205. text: "取消",
  206. active: false,
  207. disabled: false,
  208. href: "javascript:;"
  209. },
  210. onConfirm: () => {
  211. this.oldKeywordList = [];
  212. localStorage.removeItem("OldKeys");
  213. },
  214. onCancel: () => {}
  215. }).show();
  216. },
  217. //执行搜索
  218. doSearch(keyword) {
  219. keyword = keyword === false ? this.keyword : keyword;
  220. this.keyword = keyword;
  221. this.saveKeyword(keyword); //保存为历史
  222. let arr = this.deptList.filter(item => {
  223. return item.mutiCategory === keyword;
  224. });
  225. if (arr.length) {
  226. // model
  227. this.model.category = arr[0];
  228. // this.$router.push(`/newIncident?id=${arr[0].id}&model=${JSON.stringify(this.model)}&other=${JSON.stringify(this.other)}`);
  229. this.$router.push({
  230. name: 'NewIncident',
  231. params: {
  232. id: arr[0].id,
  233. model: this.model,
  234. other: this.other,
  235. },
  236. })
  237. }
  238. },
  239. //保存关键字到历史记录
  240. saveKeyword(keyword) {
  241. var OldKeys = JSON.parse(localStorage.getItem("OldKeys"));
  242. if (OldKeys) {
  243. var findIndex = OldKeys.indexOf(keyword);
  244. if (findIndex == -1) {
  245. OldKeys.unshift(keyword);
  246. } else {
  247. OldKeys.splice(findIndex, 1);
  248. OldKeys.unshift(keyword);
  249. }
  250. //最多10个纪录
  251. OldKeys.length > 10 && OldKeys.pop();
  252. localStorage.setItem("OldKeys", JSON.stringify(OldKeys));
  253. this.oldKeywordList = OldKeys; //更新历史搜索
  254. } else {
  255. OldKeys = [keyword];
  256. localStorage.setItem("OldKeys", JSON.stringify(OldKeys));
  257. this.oldKeywordList = OldKeys; //更新历史搜索
  258. }
  259. }
  260. }
  261. };
  262. </script>
  263. <style lang="less" scoped>
  264. view {
  265. display: block;
  266. }
  267. .search-box {
  268. background-color: rgb(242, 242, 242);
  269. padding: 0.15rem 2.5%;
  270. display: flex;
  271. justify-content: space-between;
  272. position: sticky;
  273. top: 0;
  274. }
  275. .search-box .mSearch-input-box {
  276. width: 100%;
  277. }
  278. .search-box .input-box {
  279. width: 85%;
  280. flex-shrink: 1;
  281. display: flex;
  282. justify-content: center;
  283. align-items: center;
  284. }
  285. .search-box .search-btn {
  286. width: 15%;
  287. margin: 0 0 0 2%;
  288. display: flex;
  289. justify-content: center;
  290. align-items: center;
  291. flex-shrink: 0;
  292. font-size: 0.28rem;
  293. color: #fff;
  294. background: linear-gradient(to right, #ff9801, #ff570a);
  295. border-radius: 0.6rem;
  296. }
  297. .search-box .input-box > input {
  298. width: 100%;
  299. height: 0.6rem;
  300. font-size: 0.32rem;
  301. border: 0;
  302. border-radius: 0.6rem;
  303. -webkit-appearance: none;
  304. -moz-appearance: none;
  305. appearance: none;
  306. padding: 0 3%;
  307. margin: 0;
  308. background-color: #ffffff;
  309. }
  310. .placeholder-class {
  311. color: #9e9e9e;
  312. }
  313. .search-keyword {
  314. width: 100%;
  315. background-color: rgb(242, 242, 242);
  316. }
  317. .keyword-list-box {
  318. height: calc(100vh - 1.1rem);
  319. padding-top: 0.1rem;
  320. border-radius: 0.2rem 0.2rem 0 0;
  321. background-color: #fff;
  322. }
  323. .keyword-entry-tap {
  324. background-color: #eee;
  325. }
  326. .keyword-entry {
  327. width: 94%;
  328. height: 0.8rem;
  329. margin: 0 3%;
  330. font-size: 0.3rem;
  331. color: #333;
  332. display: flex;
  333. justify-content: space-between;
  334. align-items: center;
  335. border-bottom: solid 1px #e7e7e7;
  336. }
  337. .keyword-entry img {
  338. width: 0.6rem;
  339. height: 0.6rem;
  340. }
  341. .keyword-entry .keyword-text,
  342. .keyword-entry .keyword-img {
  343. height: 0.8rem;
  344. display: flex;
  345. align-items: center;
  346. }
  347. .keyword-entry .keyword-text {
  348. width: 90%;
  349. }
  350. .keyword-entry .keyword-img {
  351. width: 10%;
  352. justify-content: center;
  353. }
  354. .keyword-box {
  355. height: calc(100vh - 1.1rem);
  356. border-radius: 0.2rem 0.2rem 0 0;
  357. background-color: #fff;
  358. }
  359. .keyword-box .keyword-block {
  360. padding: 0.1rem 0;
  361. }
  362. .keyword-box .keyword-block .keyword-list-header {
  363. width: 94%;
  364. padding: 0.1rem 3%;
  365. font-size: 0.27rem;
  366. color: #333;
  367. display: flex;
  368. justify-content: space-between;
  369. }
  370. .keyword-box .keyword-block .keyword-list-header img {
  371. width: 0.4rem;
  372. height: 0.4rem;
  373. }
  374. .keyword-box .keyword-block .keyword {
  375. width: 94%;
  376. padding: 3px 3%;
  377. display: flex;
  378. flex-flow: wrap;
  379. justify-content: flex-start;
  380. }
  381. .keyword-box .keyword-block .hide-hot-tis {
  382. display: flex;
  383. justify-content: center;
  384. font-size: 0.28rem;
  385. color: #6b6b6b;
  386. }
  387. .keyword-box .keyword-block .keyword > view {
  388. display: flex;
  389. justify-content: center;
  390. align-items: center;
  391. border-radius: 0.6rem;
  392. padding: 0 0.2rem;
  393. margin: 0.1rem 0.2rem 0.1rem 0;
  394. height: 0.6rem;
  395. font-size: 0.28rem;
  396. background-color: rgb(242, 242, 242);
  397. color: #6b6b6b;
  398. }
  399. </style>