建材商城系统20241014
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.

347 lines
11 KiB

7 months ago
  1. <template>
  2. <view class="hand-top">
  3. <navbar
  4. title="快捷下单"
  5. leftClick
  6. @leftClick="$utils.navigateBack"
  7. />
  8. <view class="picture-top">
  9. <view class="left-icon"></view>
  10. <text>拍照下单</text>
  11. </view>
  12. <view class="picture-upload">
  13. <view class="upload-content" @click="chooseImage" v-if="!imageUrl">
  14. <uv-icon name="camera-fill" color="#D03F25" size="200"></uv-icon>
  15. </view>
  16. <view class="image-preview" v-else>
  17. <image :src="imageUrl" mode="aspectFit" class="preview-img"></image>
  18. <view class="preview-actions">
  19. <view class="action-btn delete" @click="deleteImage">
  20. <uv-icon name="trash" size="40rpx" color="#D03F25"></uv-icon>
  21. <text>删除</text>
  22. </view>
  23. <view class="action-btn retake" @click="chooseImage">
  24. <uv-icon name="camera" size="40rpx" color="#D03F25"></uv-icon>
  25. <text>重拍</text>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="text-upload">
  30. <text>(拍照上传你所需要识别的产品图片)</text>
  31. </view>
  32. </view>
  33. <view class="fast-order">
  34. <view class="picture-button" @click="submitPictureOrder" :style="imageUrl ? '' : 'opacity: 0.5;'">
  35. <text>快捷下单</text>
  36. </view>
  37. </view>
  38. <!-- 上传进度指示器 -->
  39. <view class="upload-progress" v-if="isUploading">
  40. <view class="progress-bg">
  41. <view class="progress-bar" :style="{width: uploadProgress + '%'}"></view>
  42. </view>
  43. <text class="progress-text">{{uploadProgress}}%</text>
  44. </view>
  45. </view>
  46. </template>
  47. <script>
  48. export default {
  49. data() {
  50. return {
  51. imageUrl: '', // 图片本地路径
  52. imageOssUrl: '', // 上传到OSS后的图片路径
  53. isUploading: false, // 是否正在上传
  54. uploadProgress: 0, // 上传进度
  55. recognitionResult: null, // 识别结果
  56. };
  57. },
  58. methods: {
  59. // 选择图片
  60. chooseImage() {
  61. uni.chooseImage({
  62. count: 1, // 只选择一张图片
  63. sizeType: ['compressed'], // 压缩图片
  64. sourceType: ['camera', 'album'], // 相机和相册都允许
  65. success: (res) => {
  66. // 获取选择的图片路径
  67. this.imageUrl = res.tempFilePaths[0];
  68. console.log('已选择图片', this.imageUrl);
  69. },
  70. fail: (err) => {
  71. console.error('选择图片失败', err);
  72. }
  73. });
  74. },
  75. // 删除图片
  76. deleteImage() {
  77. uni.showModal({
  78. title: '提示',
  79. content: '确定要删除这张图片吗?',
  80. success: (res) => {
  81. if (res.confirm) {
  82. this.imageUrl = '';
  83. this.imageOssUrl = '';
  84. this.recognitionResult = null;
  85. }
  86. }
  87. });
  88. },
  89. // 提交图片订单
  90. submitPictureOrder() {
  91. if (!this.imageUrl) {
  92. uni.showToast({
  93. title: '请先拍照上传图片',
  94. icon: 'none'
  95. });
  96. return;
  97. }
  98. if (this.isUploading) {
  99. uni.showToast({
  100. title: '正在上传中,请稍候',
  101. icon: 'none'
  102. });
  103. return;
  104. }
  105. // 显示加载提示
  106. // uni.showLoading({
  107. // title: '上传中...'
  108. // });
  109. this.isUploading = true;
  110. this.uploadProgress = 0;
  111. // 上传图片
  112. this.uploadImage();
  113. },
  114. // 上传图片
  115. uploadImage() {
  116. // 模拟上传进度
  117. const simulateProgress = () => {
  118. this.uploadProgress = 0;
  119. const interval = setInterval(() => {
  120. this.uploadProgress += 5;
  121. if (this.uploadProgress >= 90) {
  122. clearInterval(interval);
  123. }
  124. }, 100);
  125. return interval;
  126. };
  127. const progressInterval = simulateProgress();
  128. // 使用OSS上传服务上传图片
  129. this.$Oss.ossUpload(this.imageUrl).then(url => {
  130. // 上传成功
  131. clearInterval(progressInterval);
  132. this.uploadProgress = 100;
  133. this.imageOssUrl = url;
  134. console.log('图片上传成功', url);
  135. // 调用拍照下单接口
  136. this.createPictureOrder(url);
  137. }).catch(err => {
  138. // 上传失败
  139. clearInterval(progressInterval);
  140. console.error('图片上传失败', err);
  141. this.handleUploadFailed('图片上传失败,请重试');
  142. });
  143. },
  144. // 创建拍照订单
  145. createPictureOrder(imageUrl) {
  146. this.$api('addOrder', {
  147. imageUrl: imageUrl,
  148. type: '0', //0表示拍照下单
  149. }, res => {
  150. uni.hideLoading();
  151. this.isUploading = false;
  152. if (res.code == 200) {
  153. // 下单成功
  154. uni.showToast({
  155. title: '下单成功',
  156. icon: 'success',
  157. duration: 1000,
  158. success: () => {
  159. // uni.reLaunch({
  160. // url: '/pages/index/index'
  161. // })
  162. uni.navigateBack(-1)
  163. }
  164. });
  165. } else {
  166. uni.showModal({
  167. title: '提示',
  168. content: res.message || '下单失败',
  169. showCancel: false
  170. });
  171. }
  172. }, err => {
  173. // 错误处理
  174. uni.hideLoading();
  175. this.isUploading = false;
  176. console.error('下单请求失败', err);
  177. this.handleUploadFailed('网络请求失败,请检查网络连接');
  178. });
  179. },
  180. // 处理上传失败情况
  181. handleUploadFailed(message) {
  182. uni.hideLoading();
  183. this.isUploading = false;
  184. this.uploadProgress = 0;
  185. uni.showModal({
  186. title: '上传失败',
  187. content: message,
  188. showCancel: false
  189. });
  190. }
  191. }
  192. }
  193. </script>
  194. <style scoped lang="scss">
  195. .hand-top{
  196. background-color: #ffffff;
  197. position: relative;
  198. .picture-top{
  199. color: #333333;
  200. height: 100rpx;
  201. display: flex;
  202. align-items: center;
  203. background-color: #ffffff;
  204. .left-icon{
  205. background-color: #D03F25;
  206. display: inline-block;
  207. width: 10rpx;
  208. height: 30rpx;
  209. border-radius: 100rpx;
  210. margin-left: 50rpx;
  211. margin-right: 20rpx;
  212. padding-bottom: 5rpx;
  213. }
  214. }
  215. .picture-upload{
  216. background-color: #ffffff;
  217. height: 550rpx;
  218. .upload-content{
  219. width: 680rpx;
  220. height: 400rpx;
  221. background-color: #ffffff;
  222. background-color: #F4F4F4;
  223. margin: auto;
  224. margin-top: 50rpx;
  225. border-radius: 20rpx;
  226. display: flex;
  227. align-items: center;
  228. justify-content: center;
  229. margin-top: 60rpx;
  230. }
  231. .image-preview {
  232. width: 680rpx;
  233. height: 400rpx;
  234. background-color: #F4F4F4;
  235. margin: auto;
  236. margin-top: 60rpx;
  237. border-radius: 20rpx;
  238. position: relative;
  239. overflow: hidden;
  240. .preview-img {
  241. width: 100%;
  242. height: 100%;
  243. object-fit: contain;
  244. }
  245. .preview-actions {
  246. position: absolute;
  247. bottom: 0;
  248. left: 0;
  249. right: 0;
  250. height: 80rpx;
  251. background-color: rgba(0, 0, 0, 0.5);
  252. display: flex;
  253. justify-content: space-around;
  254. align-items: center;
  255. .action-btn {
  256. display: flex;
  257. flex-direction: column;
  258. align-items: center;
  259. justify-content: center;
  260. padding: 10rpx 30rpx;
  261. text {
  262. color: #fff;
  263. font-size: 24rpx;
  264. margin-top: 6rpx;
  265. }
  266. }
  267. }
  268. }
  269. .text-upload{
  270. height: 100rpx;
  271. text-align: center;
  272. line-height: 100rpx;
  273. color: #666666;
  274. }
  275. }
  276. .fast-order{
  277. .picture-button{
  278. color: #ffffff;
  279. background-color: #DC2828;
  280. width: 85%;
  281. height: 100rpx;
  282. margin: auto;
  283. display: flex;
  284. align-items: center;
  285. justify-content: center;
  286. border-radius: 100rpx;
  287. }
  288. }
  289. .upload-progress {
  290. position: fixed;
  291. top: 50%;
  292. left: 50%;
  293. transform: translate(-50%, -50%);
  294. width: 600rpx;
  295. background-color: rgba(0, 0, 0, 0.7);
  296. border-radius: 20rpx;
  297. padding: 30rpx;
  298. text-align: center;
  299. z-index: 999;
  300. .progress-bg {
  301. width: 100%;
  302. height: 20rpx;
  303. background-color: #eee;
  304. border-radius: 10rpx;
  305. overflow: hidden;
  306. margin-bottom: 20rpx;
  307. .progress-bar {
  308. height: 100%;
  309. background-color: #D03F25;
  310. border-radius: 10rpx;
  311. transition: width 0.2s;
  312. }
  313. }
  314. .progress-text {
  315. color: #fff;
  316. font-size: 28rpx;
  317. }
  318. }
  319. }
  320. </style>