猫妈狗爸伴宠师小程序前端代码
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.

299 lines
6.6 KiB

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