猫妈狗爸伴宠师小程序前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

293 lines
6.4 KiB

1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
1 month ago
  1. <template>
  2. <view class="page">
  3. <view class="tips color-ffb size-22">
  4. 注意:这段内容将会在您的喂养员个人主页做为"服务案例展示并开放给其他铲屎官查看请认真编辑哟
  5. </view>
  6. <view class="li bg-fff">
  7. <view class="title">
  8. 服务类型
  9. <text class="size-22 color-999 ml10">可多选</text>
  10. </view>
  11. <up-checkbox-group v-model="form.serviceType">
  12. <view class="flex-between mt40" style="width: 100%;">
  13. <up-checkbox shape="circle" class="mr10" :customStyle="{marginBottom: '8px'}"
  14. v-for="item in petTypeOptions" :key="`serviceType-${item.id}`" :label="item.title" :name="item.id" activeColor="#FFBF60">
  15. </up-checkbox>
  16. </view>
  17. </up-checkbox-group>
  18. </view>
  19. <view class="li bg-fff">
  20. <view class="title">
  21. 服务时间
  22. </view>
  23. <view class="flex-between mt16">
  24. <text class="size-28 color-999">选择服务时间</text>
  25. <view class="flex-rowr" @click="openTimePicker">
  26. <view class="t-r size-28 mr10" :class="[form.serviceTime ? 'highlight' : '']">{{ serveTimeDesc }}</view>
  27. <up-icon name="arrow-right" color="#999999" size="27rpx"></up-icon>
  28. </view>
  29. </view>
  30. <up-datetime-picker
  31. v-model="form.serviceTime"
  32. :show="showTimePicker"
  33. mode="date"
  34. :closeOnClickOverlay="true"
  35. @close="closeTimePicker"
  36. @cancel="closeTimePicker"
  37. @confirm="closeTimePicker"
  38. ></up-datetime-picker>
  39. </view>
  40. <view class="li bg-fff">
  41. <view class="title">
  42. 服务地点
  43. </view>
  44. <view class="flex-between mt16">
  45. <text class="size-28 color-999">选择服务地点</text>
  46. <view class="flex-rowr" @click="selectAddr">
  47. <view class="t-r size-28 mr10" :class="[form.serviceSpot ? 'highlight' : '']">{{ form.serviceSpot || '请选择' }}</view>
  48. <up-icon name="arrow-right" color="#999999" size="27rpx"></up-icon>
  49. </view>
  50. </view>
  51. </view>
  52. <view class="li bg-fff">
  53. <view class="title">
  54. 文字记录
  55. </view>
  56. <textarea class="text"
  57. v-model="form.text"
  58. placeholder="请输入文字记录,可简单描述服务过程中发生的趣事,或夸奖一下服务宠物吧,10-100字"
  59. ></textarea>
  60. </view>
  61. <view class="li bg-fff">
  62. <view class="title">
  63. 图片记录
  64. </view>
  65. <view class="size-28 color-999 mt16">
  66. 请选择具有代表性的2-3张服务宠物图片服务过程图片或视频截图让铲屎官感受到您对毛孩子的爱吧
  67. </view>
  68. <view style="margin-top: 34rpx;">
  69. <up-upload
  70. :fileList="form.fileList"
  71. @afterRead="afterRead"
  72. @delete="deletePic"
  73. multiple
  74. >
  75. <image src="../static/list/icon-upload.png" style="width: 144rpx;height: 144rpx;"></image>
  76. </up-upload>
  77. </view>
  78. </view>
  79. <view class="footer-btn">
  80. <view class="btn" @click="onSave">
  81. 立即上传
  82. </view>
  83. </view>
  84. </view>
  85. </template>
  86. <script setup>
  87. import { ref, reactive, computed } from 'vue';
  88. import { onLoad } from '@dcloudio/uni-app'
  89. import { useStore } from 'vuex'
  90. import dayjs from 'dayjs'
  91. import { ossUpload } from '@/utils/oss-upload/oss/index.js'
  92. import { insertServiceLog, udpateServiceLog } from '@/api/serviceLog'
  93. const store = useStore()
  94. const id = ref()
  95. const form = reactive({
  96. serviceType: [],
  97. serviceTime: null,
  98. serviceSpot: null,
  99. latitude: null,
  100. longitude: null,
  101. text: null,
  102. fileList: [],
  103. })
  104. const fetchServiceLogDetail = async () => {
  105. try {
  106. const data = (await serviceLogList({ id: id.value }))?.[0]
  107. // const data = uni.getStorageSync('serviceLogData')
  108. const {
  109. serviceType,
  110. serviceTime,
  111. serviceSpot,
  112. text,
  113. image,
  114. } = data
  115. form.serviceType = serviceType?.split?.(',').map(item => parseInt(item)) || []
  116. form.serviceTime = serviceTime
  117. form.serviceSpot = serviceSpot
  118. form.text = text
  119. form.fileList = image?.split?.(',').map(url => ({ url })) || []
  120. } catch (err) {
  121. }
  122. }
  123. const petTypeOptions = computed(() => {
  124. return store.getters.petTypeOptions
  125. })
  126. const showTimePicker = ref(false)
  127. const openTimePicker = () => {
  128. showTimePicker.value = true
  129. }
  130. const closeTimePicker = () => {
  131. showTimePicker.value = false
  132. }
  133. const serveTimeDesc = computed(() => {
  134. if (!form.serviceTime) {
  135. return '请选择'
  136. }
  137. return dayjs(form.serviceTime).format('YYYY/MM/DD')
  138. })
  139. const setAddress = (res) => {
  140. //经纬度信息
  141. form.latitude = res.latitude
  142. form.longitude = res.longitude
  143. if (!res.address && res.name) { //用户直接选择城市的逻辑
  144. return form.serviceSpot = res.name
  145. }
  146. if (res.address || res.name) {
  147. return form.serviceSpot = res.address + res.name
  148. }
  149. form.serviceSpot = '' //用户啥都没选就点击勾选
  150. }
  151. const selectAddr = () => {
  152. uni.chooseLocation({
  153. success: function(res) {
  154. setAddress(res)
  155. }
  156. })
  157. }
  158. const afterRead = (event) => {
  159. event.file.forEach(n => {
  160. ossUpload(n.url)
  161. .then(url => {
  162. form.fileList.push({
  163. url
  164. })
  165. })
  166. })
  167. };
  168. const deletePic = (event) => {
  169. form.fileList.splice(event.index, 1);
  170. };
  171. const onSave = async () => {
  172. try {
  173. const {
  174. serviceType,
  175. serviceTime,
  176. serviceSpot,
  177. text,
  178. fileList,
  179. } = form
  180. const data = {
  181. userId: store.getters.userInfo.userId,
  182. serviceType: serviceType.join(','),
  183. serviceTime: dayjs(serviceTime).format('YYYY-MM-DD HH:mm:ss'),
  184. serviceSpot,
  185. text,
  186. image: fileList.map(item => item.url).join(',')
  187. }
  188. if (id.value) {
  189. data.id = id.value
  190. await udpateServiceLog(data)
  191. } else {
  192. await insertServiceLog(data)
  193. }
  194. uni.showToast({
  195. title: '上传成功!',
  196. icon: "none"
  197. })
  198. setTimeout(() => {
  199. uni.navigateBack()
  200. }, 1000)
  201. } catch (err) {
  202. }
  203. }
  204. onLoad((option) => {
  205. store.dispatch('fetchPetTypeOptions')
  206. id.value = option.id
  207. if (id.value) {
  208. fetchServiceLogDetail()
  209. }
  210. })
  211. </script>
  212. <style lang="scss" scoped>
  213. .page {
  214. min-height: 100vh;
  215. padding-bottom: 144rpx;
  216. }
  217. .text {
  218. padding: 16rpx;
  219. background-color: #F3F3F3;
  220. font-size: 28rpx;
  221. margin-top: 16rpx;
  222. border-radius: 20rpx;
  223. }
  224. .tips {
  225. padding: 8rpx 16rpx;
  226. background-color: rgb(255, 250, 242);
  227. }
  228. .li {
  229. margin: 20rpx;
  230. border-radius: 20rpx;
  231. padding: 24rpx 36rpx;
  232. }
  233. .title {
  234. font-size: 30rpx;
  235. font-weight: 700;
  236. display: flex;
  237. align-items: center;
  238. &:before {
  239. display: block;
  240. content: "";
  241. width: 10rpx;
  242. border-radius: 10rpx;
  243. height: 34rpx;
  244. background-color: #FFBF60;
  245. margin-right: 15rpx;
  246. }
  247. }
  248. .highlight {
  249. color: #FFBF60;
  250. }
  251. .footer-btn {
  252. z-index: 4;
  253. }
  254. </style>