index.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. <template>
  2. <!-- 禁止滚动穿透 -->
  3. <page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
  4. <view class="main">
  5. <view class="one">
  6. <view class="one_1">
  7. <input type="text" v-model="searchInfo.name" @input="toInput" placeholder="搜索群组名称">
  8. </view>
  9. <view class="one_2">
  10. <button size="mini" class="button" type="primary" @click="toAdd">添加</button>
  11. </view>
  12. </view>
  13. <view class="two">
  14. <scroll-view scroll-y="true" class="scroll-view" @scrolltolower="toPage" @scroll="toScroll">
  15. <view class="list-scroll-view">
  16. <view class="list" v-for="(item, index) in list" :key="index" @tap="toView(item)">
  17. <view class="title">{{item.name||'暂无群组名称'}}</view>
  18. <view class="button">
  19. <button class="warning" size="mini" type="warn" @tap.stop="toEdit(item)">修改</button>
  20. <button class="warning" size="mini" type="warn" @tap.stop="toCode(item)">群二维码</button>
  21. <button class="danger" size="mini" type="warn" @tap.stop="toDel(item)">删除</button>
  22. </view>
  23. </view>
  24. </view>
  25. <view class="is_bottom" v-if="is_bottom">
  26. <text>{{config.bottom_title||'到底了!'}}</text>
  27. </view>
  28. </scroll-view>
  29. </view>
  30. <uni-popup ref="popup" background-color="#fff" type="center" :is-mask-click="false" @change="change">
  31. <view class="popup">
  32. <view class="close">
  33. <text>信息管理</text>
  34. <uni-icons @tap="toClose" type="close" size="20"></uni-icons>
  35. </view>
  36. <view class="info_1">
  37. <uni-forms ref="valiForm" :rules="rules" :modelValue="form">
  38. <uni-forms-item label="群名" required name="name">
  39. <uni-easyinput v-model="form.name" placeholder="请输入群名" />
  40. </uni-forms-item>
  41. <uni-forms-item label="简介" required name="content">
  42. <uni-easyinput type="textarea" autoHeight v-model="form.content" placeholder="请输入简介" />
  43. </uni-forms-item>
  44. </uni-forms>
  45. <button class="button" size="mini" type="primary" @click="submit('valiForm')">保存</button>
  46. </view>
  47. </view>
  48. </uni-popup>
  49. </view>
  50. </template>
  51. <script>
  52. export default {
  53. data() {
  54. return {
  55. user: {},
  56. config: {},
  57. searchInfo: {},
  58. list: [],
  59. total: 0,
  60. skip: 0,
  61. limit: 10,
  62. page: 0,
  63. form: {},
  64. // 校验规则
  65. rules: {
  66. name: {
  67. rules: [{
  68. required: true,
  69. errorMessage: '群名不能为空'
  70. }]
  71. },
  72. content: {
  73. rules: [{
  74. required: true,
  75. errorMessage: '简介不能为空'
  76. }]
  77. }
  78. },
  79. // 数据是否触底
  80. is_bottom: false,
  81. scrollTop: 0,
  82. // 禁止滚动穿透
  83. show: false
  84. }
  85. },
  86. onShow: async function() {
  87. const that = this;
  88. that.clearPage();
  89. await that.searchToken();
  90. await that.searchConfig();
  91. await that.search();
  92. },
  93. onPullDownRefresh: async function() {
  94. const that = this;
  95. that.clearPage();
  96. await that.search();
  97. uni.stopPullDownRefresh();
  98. },
  99. methods: {
  100. // 禁止滚动穿透
  101. change(e) {
  102. const that = this;
  103. that.show = e.show
  104. },
  105. searchToken() {
  106. const that = this;
  107. try {
  108. const res = uni.getStorageSync('token');
  109. if (res) {
  110. const user = that.$jwt(res);
  111. that.$set(that, `user`, user);
  112. }
  113. } catch (e) {}
  114. },
  115. searchConfig() {
  116. const that = this;
  117. try {
  118. const res = uni.getStorageSync('config');
  119. if (res) that.$set(that, `config`, res);
  120. } catch (e) {}
  121. },
  122. async search() {
  123. const that = this;
  124. let user = that.user;
  125. let info = {
  126. skip: that.skip,
  127. limit: that.limit,
  128. }
  129. if (that.user.role == 'Doctor') info.doctor = that.user._id
  130. else info.doctor = that.user.doctor
  131. const res = await that.$api(`/group`, 'GET', {
  132. ...info,
  133. ...that.searchInfo
  134. })
  135. if (res.errcode == '0') {
  136. let list = [...that.list, ...res.data];
  137. that.$set(that, `list`, list)
  138. that.$set(that, `total`, res.total)
  139. } else {
  140. uni.showToast({
  141. title: res.errmsg,
  142. });
  143. }
  144. },
  145. // 输入框
  146. toInput(e) {
  147. const that = this;
  148. if (that.searchInfo.title) that.$set(that.searchInfo, `title`, e.detail.value)
  149. else that.$set(that, `searchInfo`, {})
  150. that.clearPage();
  151. that.search();
  152. },
  153. // 添加
  154. toAdd() {
  155. const that = this;
  156. that.$refs.popup.open()
  157. },
  158. // 二维码
  159. toCode() {
  160. const that = this;
  161. console.log('二维码');
  162. },
  163. // 修改
  164. async toEdit(item) {
  165. const that = this;
  166. const res = await that.$api(`/group/${item._id}`, 'GET', {})
  167. if (res.errcode == '0') {
  168. that.$set(that, `form`, res.data)
  169. that.$refs.popup.open()
  170. } else {
  171. uni.showToast({
  172. title: res.errmsg,
  173. icon: 'none'
  174. });
  175. }
  176. },
  177. // 保存
  178. submit(ref) {
  179. const that = this;
  180. that.$refs[ref].validate().then(async form => {
  181. let res;
  182. if (form._id) res = await that.$api(`/group/${form._id}`, 'POST', form)
  183. else res = await that.$api(`/group`, 'POST', form)
  184. if (res.errcode == '0') {
  185. that.toClose();
  186. that.clearPage();
  187. that.search();
  188. } else {
  189. uni.showToast({
  190. title: res.errmsg,
  191. icon: 'none'
  192. });
  193. }
  194. })
  195. },
  196. // 删除
  197. async toDel(item) {
  198. const that = this;
  199. uni.showModal({
  200. title: '提示',
  201. content: '您确定删除该数据吗?',
  202. success: async function(res) {
  203. if (res.confirm) {
  204. const res = await that.$api(`/group/${item._id||item.id}`, 'DELETE', {},
  205. 'freeLabel')
  206. if (res.errcode == 0) {
  207. that.clearPage();
  208. that.search();
  209. } else {
  210. uni.showToast({
  211. title: res.errmsg,
  212. icon: 'none'
  213. })
  214. }
  215. }
  216. }
  217. });
  218. },
  219. // 关闭弹框
  220. toClose() {
  221. const that = this;
  222. that.$set(that, `form`, {})
  223. that.$refs.popup.close();
  224. },
  225. // 分页
  226. toPage(e) {
  227. const that = this;
  228. let list = that.list;
  229. let limit = that.limit;
  230. if (that.total > list.length) {
  231. uni.showLoading({
  232. title: '加载中',
  233. mask: true
  234. })
  235. let page = that.page + 1;
  236. that.$set(that, `page`, page)
  237. let skip = page * limit;
  238. that.$set(that, `skip`, skip)
  239. that.search();
  240. uni.hideLoading();
  241. } else that.$set(that, `is_bottom`, true)
  242. },
  243. toScroll(e) {
  244. const that = this;
  245. let up = that.scrollTop;
  246. that.$set(that, `scrollTop`, e.detail.scrollTop);
  247. let num = Math.sign(up - e.detail.scrollTop);
  248. if (num == 1) that.$set(that, `is_bottom`, false);
  249. },
  250. // 清空列表
  251. clearPage() {
  252. const that = this;
  253. that.$set(that, `list`, [])
  254. that.$set(that, `skip`, 0)
  255. that.$set(that, `limit`, 10)
  256. that.$set(that, `page`, 0)
  257. }
  258. }
  259. }
  260. </script>
  261. <style lang="scss" scoped>
  262. .main {
  263. display: flex;
  264. flex-direction: column;
  265. width: 100vw;
  266. height: 100vh;
  267. .one {
  268. display: flex;
  269. justify-content: center;
  270. align-items: center;
  271. padding: 2vw;
  272. .one_1 {
  273. padding: 0 2vw;
  274. width: 75vw;
  275. input {
  276. padding: 2vw;
  277. background-color: var(--f1Color);
  278. font-size: var(--font14Size);
  279. border-radius: 5px;
  280. }
  281. }
  282. .one_2 {
  283. padding: 2vw 0;
  284. .button {
  285. background-color: var(--f3CColor);
  286. color: var(--mainColor);
  287. }
  288. }
  289. }
  290. .two {
  291. position: relative;
  292. flex-grow: 1;
  293. background-color: var(--f9Color);
  294. .list:first-child {
  295. margin: 2vw;
  296. }
  297. .list {
  298. background-color: var(--mainColor);
  299. border: 1px solid var(--f5Color);
  300. padding: 2vw;
  301. margin: 0 2vw 2vw 2vw;
  302. border-radius: 5px;
  303. .title {
  304. font-size: var(--font14Size);
  305. font-weight: bold;
  306. padding: 2vw 0;
  307. }
  308. .button {
  309. margin: 2vw 0 0 0;
  310. text-align: center;
  311. .warning {
  312. background: var(--f3CColor);
  313. }
  314. .danger {
  315. background: var(--fF0Color);
  316. }
  317. button {
  318. margin: 0 1vw 0 0;
  319. }
  320. }
  321. }
  322. }
  323. .uni-popup {
  324. z-index: 9999 !important;
  325. }
  326. .popup {
  327. display: flex;
  328. flex-direction: column;
  329. width: 90vw;
  330. height: 35vh;
  331. background-color: var(--f9Color);
  332. .close {
  333. display: flex;
  334. justify-content: space-between;
  335. padding: 2vw;
  336. text:first-child {
  337. font-size: var(--font16Size);
  338. font-weight: bold;
  339. }
  340. }
  341. .info_1 {
  342. position: relative;
  343. display: flex;
  344. flex-direction: column;
  345. max-height: 30vh;
  346. padding: 2vw;
  347. .button {
  348. background-color: var(--f3CColor);
  349. color: var(--mainColor);
  350. font-size: var(--font14Size);
  351. }
  352. }
  353. }
  354. }
  355. .scroll-view {
  356. position: absolute;
  357. top: 0;
  358. left: 0;
  359. right: 0;
  360. bottom: 0;
  361. .list-scroll-view {
  362. display: flex;
  363. flex-direction: column;
  364. }
  365. }
  366. .is_bottom {
  367. width: 100%;
  368. text-align: center;
  369. text {
  370. padding: 2vw 0;
  371. display: inline-block;
  372. color: var(--f85Color);
  373. font-size: var(--font14Size);
  374. }
  375. }
  376. </style>