clockDetail.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <template>
  2. <view class="clock-details">
  3. <view class="clock-details__header">
  4. <view class="clock-details__title">
  5. <uni-icons type="location-filled" color="#fff"></uni-icons>
  6. <view class="text">
  7. {{ address || '暂未获取到具体地址' }}
  8. </view>
  9. </view>
  10. <view
  11. class="clock-details__title fixed-width"
  12. @click="updateCurrentLocation"
  13. >
  14. <uni-icons
  15. :type="isPendingLocation ? 'spinner-cycle' : 'loop'"
  16. color="#fff"
  17. ></uni-icons>
  18. <view class="text"> 重新定位 </view>
  19. </view>
  20. </view>
  21. <view class="clock-details__body">
  22. <view class="clock-details__img-container">
  23. <view class="clock-details__imgs">
  24. <view
  25. class="clock-details__img"
  26. v-for="(item, index) in urllist"
  27. :key="index + item"
  28. >
  29. <view class="icon" @click="handleRemove(index)">
  30. <u-icon name="close" color="#fff"></u-icon>
  31. </view>
  32. <image :src="baseUrl + item" mode="aspectFit" class="img"></image>
  33. </view>
  34. <view
  35. class="clock-details__upload"
  36. @click="chooseImage"
  37. v-if="urllist.length < 3"
  38. >
  39. <u-icon size="20" name="plus" color="#409eff"></u-icon>
  40. </view>
  41. </view>
  42. </view>
  43. <view class="clock-details__area">
  44. <view
  45. class="clock-details__edit-icon"
  46. v-if="!isEdit"
  47. @click="isEdit = !isEdit"
  48. >
  49. <uni-icons type="compose" color="#1B76FF"></uni-icons>
  50. </view>
  51. <u--textarea
  52. :focus="true"
  53. v-else
  54. v-model="message"
  55. placeholder=""
  56. :maxlength="200"
  57. autoHeight
  58. border="none"
  59. >
  60. </u--textarea>
  61. </view>
  62. </view>
  63. <view class="clock-details__footer">
  64. <u-button
  65. type="primary"
  66. text="签到"
  67. @click="handleClockInSubmit"
  68. ></u-button>
  69. </view>
  70. <u-loading-page
  71. loading-text="加载中..."
  72. :loading="loading"
  73. font-size="16"
  74. ></u-loading-page>
  75. </view>
  76. </template>
  77. <script>
  78. import * as taskService from '@/service/task.js'
  79. import { Debounce } from '@/util/anitthro.js'
  80. import { pullAt } from 'lodash-es'
  81. export default {
  82. data() {
  83. return {
  84. isEdit: false,
  85. latitude: 0,
  86. longitude: 0,
  87. address: '',
  88. taskID: '',
  89. message: '',
  90. logs: [],
  91. kpsurlL: '',
  92. urllist: [],
  93. loading: false,
  94. isPendingLocation: false,
  95. }
  96. },
  97. onLoad(options) {
  98. console.warn('clock detail ', options)
  99. this.message = ''
  100. this.urllist = []
  101. this.taskID = options.taskID
  102. },
  103. mounted() {
  104. console.log('mounted clock detail')
  105. this.updateCurrentLocation()
  106. },
  107. methods: {
  108. updateCurrentLocation() {
  109. console.log('updateCurrentLocation ')
  110. if (this.isPendingLocation) {
  111. return
  112. }
  113. this.isPendingLocation = true
  114. uni.getLocation({
  115. type: 'gcj02',
  116. // altitude: true, // 高度
  117. geocode: true,
  118. success: (res) => {
  119. console.warn(res, 'get location')
  120. console.log('当前位置的经度1:' + res.longitude)
  121. console.log('当前位置的纬度1:' + res.latitude)
  122. this.logs.push(
  123. `center-position:当前位置的经度${res.longitude};当前位置的纬度${res.latitude}`
  124. )
  125. this.latitude = res.latitude
  126. this.longitude = res.longitude
  127. if (res.address) {
  128. const {
  129. country,
  130. province,
  131. city,
  132. district,
  133. street,
  134. streetNum,
  135. poiName,
  136. } = res.address || {}
  137. this.address =
  138. province + city + district + street + streetNum + poiName
  139. }
  140. },
  141. fail(err) {
  142. console.warn(err, 'get location error')
  143. },
  144. complete: () => {
  145. console.log('complete get location')
  146. this.isPendingLocation = false
  147. },
  148. })
  149. },
  150. validate() {
  151. if (!this.address) {
  152. throw new Error('请重新获取下定位信息')
  153. }
  154. if (!this.taskID) {
  155. throw new Error('请返回重新进行打卡操作')
  156. }
  157. if (!this.latitude && !this.longitude) {
  158. throw new Error('请重新获取下定位信息')
  159. }
  160. if (!this.urllist.length) {
  161. throw new Error('请先拍摄图片再进行打卡')
  162. }
  163. if (!this.message) {
  164. throw new Error('请输入内容')
  165. }
  166. },
  167. // 签到提交
  168. handleClockInSubmit() {
  169. try {
  170. this.validate()
  171. } catch (error) {
  172. return uni.$u.toast(error.message)
  173. }
  174. this.loading = true
  175. console.log(this.urllist, '------------- clock in submit')
  176. const payload = {
  177. task_id: this.taskID,
  178. message: this.message,
  179. img_list: JSON.stringify(this.urllist),
  180. address: this.address,
  181. lng: this.longitude,
  182. lat: this.latitude,
  183. }
  184. console.warn(payload, 'clock in data')
  185. taskService
  186. .addTaskClockInData(payload)
  187. .then((res) => {
  188. uni.$u.toast('打卡成功')
  189. // TODO 返回上一页
  190. setTimeout(() => {
  191. uni.switchTab({
  192. url: '/pages/index/index',
  193. })
  194. })
  195. })
  196. .finally(() => {
  197. this.loading = false
  198. })
  199. },
  200. chooseImage() {
  201. uni.chooseImage({
  202. count: 1, //默认9
  203. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  204. sourceType: ['camera', 'album'], //从相册选择
  205. success: (res) => {
  206. console.log(res)
  207. // this.urllist.push(res.tempFilePaths[0])
  208. // this.kpsurlL = res.tempFilePaths[0]
  209. this.onok({ path: res.tempFilePaths[0] })
  210. },
  211. })
  212. },
  213. handleRemove(index) {
  214. console.log(index, 'handle remove', this.urllist)
  215. if (index !== undefined) {
  216. // pullAt(this.urllist, index)
  217. this.urllist.splice(index, 1)
  218. console.log(this.urllist, 'remove finished ')
  219. }
  220. },
  221. oncancle() {
  222. this.kpsurlL = ''
  223. },
  224. onok(ev) {
  225. this.loading = true
  226. Debounce(() => {
  227. uni.uploadFile({
  228. url:
  229. this.baseUrl +
  230. '/api/api_gateway?method=monitor_manage.cbd_manage.add_img', //仅为示例,非真实的接口地址
  231. filePath: ev.path,
  232. name: 'img_file',
  233. success: (uploadFileRes) => {
  234. console.log(JSON.parse(uploadFileRes.data).data.src)
  235. this.urllist.push(JSON.parse(uploadFileRes.data).data.src)
  236. console.log(this.urllist, ' upload file')
  237. this.kpsurlL = ''
  238. this.loading = false
  239. },
  240. complete() {
  241. console.log('上传完成 1355566')
  242. this.loading = false
  243. },
  244. })
  245. }, 1000)()
  246. },
  247. },
  248. }
  249. </script>
  250. <style lang="scss" scoped>
  251. .clock-details {
  252. &__header {
  253. height: 320rpx;
  254. display: flex;
  255. justify-content: space-between;
  256. align-items: flex-start;
  257. background-image: url(~@/static/image/task/clock.png);
  258. background-size: 100%;
  259. background-repeat: no-repeat;
  260. }
  261. &__title {
  262. // width: 0;
  263. flex: 1 1 auto;
  264. padding: 48rpx 24rpx;
  265. display: flex;
  266. align-items: flex-start;
  267. font-size: 12px;
  268. line-height: 18px;
  269. color: #ffffff;
  270. .text {
  271. margin-left: 10rpx;
  272. }
  273. &.fixed-width {
  274. width: 140rpx;
  275. flex: 0 0 auto;
  276. }
  277. }
  278. &__upload {
  279. width: 144rpx;
  280. height: 144rpx;
  281. border: 1px dashed #409eff;
  282. display: flex;
  283. justify-content: space-around;
  284. margin-left: 32rpx;
  285. margin-bottom: 30rpx;
  286. }
  287. &__img-container {
  288. border-bottom: 1px solid rgba(151, 151, 151, 0.09);
  289. // @include hairline-bottom(rgba(151, 151, 151, 0.09));
  290. }
  291. &__imgs {
  292. position: relative;
  293. display: flex;
  294. flex-wrap: wrap;
  295. align-items: center;
  296. padding: 40rpx 0;
  297. margin-left: -32rpx;
  298. }
  299. &__img {
  300. flex: 0 0 auto;
  301. width: 198rpx;
  302. height: 198rpx;
  303. margin-left: 32rpx;
  304. margin-bottom: 30rpx;
  305. position: relative;
  306. .img {
  307. width: 100%;
  308. height: 100%;
  309. }
  310. .icon {
  311. position: absolute;
  312. top: -20rpx;
  313. right: -20rpx;
  314. z-index: 9;
  315. width: 40rpx;
  316. height: 40rpx;
  317. border-radius: 50%;
  318. display: flex;
  319. justify-content: space-around;
  320. background-color: red;
  321. }
  322. }
  323. &__body {
  324. min-height: 600rpx;
  325. padding: 0 24rpx;
  326. margin: -156rpx 24rpx 0;
  327. border-radius: 16rpx;
  328. background-color: #fff;
  329. }
  330. &__area {
  331. font-size: 12px;
  332. line-height: 18px;
  333. color: #656565;
  334. font-weight: 400;
  335. }
  336. &__edit-icon {
  337. padding: 24rpx 0;
  338. }
  339. &__footer {
  340. position: fixed;
  341. left: 76rpx;
  342. right: 76rpx;
  343. bottom: 110rpx;
  344. }
  345. }
  346. </style>
  347. <style>
  348. page {
  349. background: #f7f8fb;
  350. }
  351. </style>