checkIn.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <view class="home">
  3. <view class="nav">
  4. <view :style="{ paddingTop }">
  5. <view class="title" :style="[{ height }, { lineHeight: height }]">
  6. <view class="back" @click="goBack()">
  7. <u-icon name="arrow-left" color="#ffffff" size="22"></u-icon>
  8. </view>
  9. <text>打卡</text>
  10. </view>
  11. </view>
  12. </view>
  13. <view class="main">
  14. <view class="main-header">
  15. <view class="user-info">
  16. <image class="user-img" src="@/static/images/user.jpg" mode="scaleToFill" />
  17. <view class="info flex1 flex-column flex_1">
  18. <u-text :lines="1" size="32rpx" :bold="true" :text="nickName"></u-text>
  19. <u-text :lines="1" size="24rpx" :text="postName"></u-text>
  20. </view>
  21. </view>
  22. <view class="more" @click="showCheckList">
  23. <u-icon name="order" size="60rpx"></u-icon>
  24. <u-text :lines="1" size="24rpx" text="打卡记录"></u-text>
  25. </view>
  26. </view>
  27. <view class="main-container">
  28. <template v-if="!showList">
  29. <view class="btn" @click="checkIn">打卡</view>
  30. <view class="location">
  31. <u--text @click="getLocation" :lines="1" :block="true" align="center" size="24rpx" :text="address">
  32. </u--text>
  33. <u-loading-icon mode="circle" size="24rpx" :show="show"></u-loading-icon>
  34. </view>
  35. </template>
  36. <u-list @scrolltolower="scrolltolower" v-else>
  37. <u-list-item v-for="(item, index) in checkList" :key="index">
  38. <u-cell :title="item.punchTime" :label="item.punchLocation">
  39. </u-cell>
  40. </u-list-item>
  41. </u-list>
  42. </view>
  43. </view>
  44. <u-toast ref="uToast"></u-toast>
  45. <!-- <uni-file-picker file-mediatype="all" v-model="imageValue" @select="select" @progress="progress" @success="success"
  46. @fail="fail" ref="upload" limit="1">
  47. <view class="upload-btn">
  48. <u-icon name="plus-circle-fill" color="blue" size="28"></u-icon>
  49. </view>
  50. </uni-file-picker> -->
  51. </view>
  52. </template>
  53. <script>
  54. import {
  55. mapGetters
  56. } from 'vuex'
  57. import to from 'await-to-js'
  58. import api from '@/api/system'
  59. export default {
  60. data() {
  61. return {
  62. height: '',
  63. paddingTop: '',
  64. address: '获取定位',
  65. form: {
  66. punchLat: 0,
  67. punchLng: 0,
  68. punchLocation: '',
  69. punchImg: ''
  70. },
  71. show: false,
  72. imageValue: [],
  73. showList: false,
  74. checkList: [],
  75. queryForm: {
  76. pageNum: 1,
  77. pageSize: 10
  78. }
  79. }
  80. },
  81. computed: {
  82. ...mapGetters(['nickName', 'postName']),
  83. },
  84. created() {
  85. this.getLocation()
  86. const navData = uni.getMenuButtonBoundingClientRect()
  87. this.height = navData.height + 'px'
  88. this.paddingTop = navData.top + 'px'
  89. },
  90. methods: {
  91. getLocation() {
  92. this.show = true
  93. const _this = this
  94. uni.getLocation({
  95. type: 'wgs84',
  96. success: function(res) {
  97. const latitude = res.latitude.toString();
  98. const longitude = res.longitude.toString();
  99. uni.request({
  100. header: {
  101. "Content-Type": "application/text"
  102. },
  103. url: 'http://apis.map.qq.com/ws/geocoder/v1/?location=' + latitude + ',' + longitude +
  104. '&key=6REBZ-BRN6J-BMAFY-FIRI3-SMK43-G3FXU',
  105. success(re) {
  106. if (re.statusCode === 200) {
  107. _this.address = re.data.result.address;
  108. _this.form = {
  109. punchLat: latitude,
  110. punchLng: longitude,
  111. punchLocation: re.data.result.address
  112. }
  113. _this.show = false
  114. } else {
  115. _this.address = '点击重试'
  116. this.$refs.uToast.show({
  117. type: 'error',
  118. message: '定位失败,请重试',
  119. })
  120. }
  121. },
  122. fail: err => _this.show = false
  123. });
  124. },
  125. fail: err => _this.show = false
  126. });
  127. },
  128. async checkIn() {
  129. if (!this.form.punchLat || !this.form.punchLng) {
  130. this.address = '点击重试'
  131. return this.$refs.uToast.show({
  132. type: 'error',
  133. message: '定位失败,请重试',
  134. })
  135. }
  136. console.log(this.$refs.upload);
  137. // this.$refs.upload.choose()
  138. const [err, res] = await uni.chooseImage({
  139. count: 1, //默认9
  140. sizeType: ['original'] //可以指定是原图还是压缩图,默认二者都有
  141. })
  142. console.log(res, 'rs');
  143. if (err) return
  144. this.select(res)
  145. res.tempFiles[0].name = (new Date()).getTime() + ''
  146. res.tempFiles[0].type = 'image'
  147. console.log(res.tempFiles[0], typeof res.tempFiles[0])
  148. },
  149. // // 选择上传触发函数
  150. select(e) {
  151. console.log(e)
  152. let url = process.uniEnv.VUE_APP_UPLOAD_WEED
  153. uni.request({
  154. url, //仅为示例,并非真实接口地址。
  155. success: (res) => {
  156. this.uploadFiles(e, res.data)
  157. },
  158. })
  159. },
  160. // 上传函数
  161. async uploadFiles(e, res) {
  162. let action = 'http://' + res.url + '/' + res.fid
  163. uni.uploadFile({
  164. url: action,
  165. filePath: e.tempFilePaths[0],
  166. name: 'file',
  167. formData: {
  168. file: e.tempFiles[0],
  169. },
  170. success: (res) => {
  171. this.form.punchImg = action
  172. api.checkIn(this.form).then(res => {
  173. this.$refs.uToast.show({
  174. type: 'success',
  175. message: '打卡成功',
  176. })
  177. })
  178. },
  179. fail: () => {
  180. console.log('err')
  181. },
  182. })
  183. },
  184. showCheckList() {
  185. if (!this.showList) this.loadCheckList()
  186. this.showList = !this.showList
  187. },
  188. async loadCheckList() {
  189. this.loadStatus = 'loading'
  190. const [err, res] = await to(api.getCheckList(this.queryForm))
  191. if (err) {
  192. this.loadStatus = 'nomore'
  193. return
  194. }
  195. if (res && res.code == 200) {
  196. this.checkList = [...this.checkList, ...(res.data.list || [])]
  197. this.total = res.data.total
  198. this.loadStatus = this.checkList.length == this.total ? 'nomore' : 'loadmore'
  199. } else {
  200. this.loadStatus = 'nomore'
  201. }
  202. },
  203. scrolltolower() {
  204. if (this.list.length < this.total && this.loadStatus != 'loading') {
  205. this.queryForm.pageNum++
  206. this.$u.throttle(this.loadCheckList(), 2000, false)
  207. }
  208. this.loadCheckList()
  209. },
  210. goBack() {
  211. uni.navigateBack({
  212. //关闭当前页面,返回上一页面或多级页面。
  213. delta: 1,
  214. })
  215. },
  216. }
  217. }
  218. </script>
  219. <style lang="scss" scoped>
  220. /deep/ .uni-file-picker {
  221. display: none;
  222. }
  223. .home {
  224. padding-top: 188rpx;
  225. height: 100%;
  226. .nav {
  227. position: absolute;
  228. left: 0;
  229. top: 0;
  230. width: 100%;
  231. height: 284rpx;
  232. background: #3e7ef8;
  233. .title {
  234. position: relative;
  235. text-align: center;
  236. font-size: 32rpx;
  237. font-weight: bold;
  238. color: #ffffff;
  239. .back {
  240. position: absolute;
  241. top: 0;
  242. bottom: 0;
  243. margin: auto;
  244. left: 70rpx;
  245. display: flex;
  246. }
  247. }
  248. }
  249. .main {
  250. display: flex;
  251. flex-direction: column;
  252. position: absolute;
  253. width: 100%;
  254. height: calc(100vh - 188rpx);
  255. background: #ffffff;
  256. box-shadow: 0 6rpx 19rpx 2rpx rgba(0, 45, 132, 0.15);
  257. border-radius: 31rpx 31rpx 0 0;
  258. padding: 0 32rpx;
  259. overflow: hidden;
  260. padding-bottom: 64rpx;
  261. .main-header {
  262. padding: 20rpx 40rpx;
  263. display: flex;
  264. justify-content: space-between;
  265. .user-info {
  266. display: flex;
  267. .user-img {
  268. width: 116rpx;
  269. height: 116rpx;
  270. border-radius: 50%;
  271. margin-right: 32rpx;
  272. }
  273. .info {
  274. height: 116rpx;
  275. margin-right: 32rpx;
  276. }
  277. }
  278. .more {
  279. display: flex;
  280. flex-direction: column;
  281. align-items: center;
  282. }
  283. }
  284. .main-container {
  285. flex: 1;
  286. display: flex;
  287. flex-direction: column;
  288. align-items: center;
  289. justify-content: center;
  290. .btn {
  291. width: 300rpx;
  292. height: 300rpx;
  293. border-radius: 50%;
  294. background: linear-gradient(70deg, #3e7ef8, #1d66dc);
  295. display: flex;
  296. justify-content: center;
  297. align-items: center;
  298. color: #fff;
  299. font-size: 48rpx;
  300. font-weight: bold;
  301. box-shadow: 0 6rpx 19rpx 2rpx rgba(29, 102, 220, 0.2);
  302. margin-bottom: 40rpx;
  303. }
  304. .location {
  305. display: flex;
  306. height: 32rpx;
  307. line-height: 32rpx;
  308. }
  309. }
  310. }
  311. }
  312. </style>