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

345 lines
11 KiB

6 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 === 0) {
  153. // 下单成功
  154. uni.showToast({
  155. title: '下单成功',
  156. icon: 'success',
  157. duration: 1500,
  158. success: () => {
  159. uni.reLaunch({
  160. url: '/pages/index/index'
  161. })
  162. }
  163. });
  164. } else {
  165. uni.showModal({
  166. title: '提示',
  167. content: res.message || '下单失败',
  168. showCancel: false
  169. });
  170. }
  171. }, err => {
  172. // 错误处理
  173. uni.hideLoading();
  174. this.isUploading = false;
  175. console.error('下单请求失败', err);
  176. this.handleUploadFailed('网络请求失败,请检查网络连接');
  177. });
  178. },
  179. // 处理上传失败情况
  180. handleUploadFailed(message) {
  181. uni.hideLoading();
  182. this.isUploading = false;
  183. this.uploadProgress = 0;
  184. uni.showModal({
  185. title: '上传失败',
  186. content: message,
  187. showCancel: false
  188. });
  189. }
  190. }
  191. }
  192. </script>
  193. <style scoped lang="scss">
  194. .hand-top{
  195. background-color: #ffffff;
  196. position: relative;
  197. .picture-top{
  198. color: #333333;
  199. height: 100rpx;
  200. display: flex;
  201. align-items: center;
  202. background-color: #ffffff;
  203. .left-icon{
  204. background-color: #D03F25;
  205. display: inline-block;
  206. width: 10rpx;
  207. height: 30rpx;
  208. border-radius: 100rpx;
  209. margin-left: 50rpx;
  210. margin-right: 20rpx;
  211. padding-bottom: 5rpx;
  212. }
  213. }
  214. .picture-upload{
  215. background-color: #ffffff;
  216. height: 550rpx;
  217. .upload-content{
  218. width: 680rpx;
  219. height: 400rpx;
  220. background-color: #ffffff;
  221. background-color: #F4F4F4;
  222. margin: auto;
  223. margin-top: 50rpx;
  224. border-radius: 20rpx;
  225. display: flex;
  226. align-items: center;
  227. justify-content: center;
  228. margin-top: 60rpx;
  229. }
  230. .image-preview {
  231. width: 680rpx;
  232. height: 400rpx;
  233. background-color: #F4F4F4;
  234. margin: auto;
  235. margin-top: 60rpx;
  236. border-radius: 20rpx;
  237. position: relative;
  238. overflow: hidden;
  239. .preview-img {
  240. width: 100%;
  241. height: 100%;
  242. object-fit: contain;
  243. }
  244. .preview-actions {
  245. position: absolute;
  246. bottom: 0;
  247. left: 0;
  248. right: 0;
  249. height: 80rpx;
  250. background-color: rgba(0, 0, 0, 0.5);
  251. display: flex;
  252. justify-content: space-around;
  253. align-items: center;
  254. .action-btn {
  255. display: flex;
  256. flex-direction: column;
  257. align-items: center;
  258. justify-content: center;
  259. padding: 10rpx 30rpx;
  260. text {
  261. color: #fff;
  262. font-size: 24rpx;
  263. margin-top: 6rpx;
  264. }
  265. }
  266. }
  267. }
  268. .text-upload{
  269. height: 100rpx;
  270. text-align: center;
  271. line-height: 100rpx;
  272. color: #666666;
  273. }
  274. }
  275. .fast-order{
  276. .picture-button{
  277. color: #ffffff;
  278. background-color: #DC2828;
  279. width: 85%;
  280. height: 100rpx;
  281. margin: auto;
  282. display: flex;
  283. align-items: center;
  284. justify-content: center;
  285. border-radius: 100rpx;
  286. }
  287. }
  288. .upload-progress {
  289. position: fixed;
  290. top: 50%;
  291. left: 50%;
  292. transform: translate(-50%, -50%);
  293. width: 600rpx;
  294. background-color: rgba(0, 0, 0, 0.7);
  295. border-radius: 20rpx;
  296. padding: 30rpx;
  297. text-align: center;
  298. z-index: 999;
  299. .progress-bg {
  300. width: 100%;
  301. height: 20rpx;
  302. background-color: #eee;
  303. border-radius: 10rpx;
  304. overflow: hidden;
  305. margin-bottom: 20rpx;
  306. .progress-bar {
  307. height: 100%;
  308. background-color: #D03F25;
  309. border-radius: 10rpx;
  310. transition: width 0.2s;
  311. }
  312. }
  313. .progress-text {
  314. color: #fff;
  315. font-size: 28rpx;
  316. }
  317. }
  318. }
  319. </style>