companyImg.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. <template>
  2. <view class="switch-roles">
  3. <nav-bar title="公司信息" color="#000"></nav-bar>
  4. <view class="roles-content">
  5. <view class="content">
  6. <view class="progress-num"> <text>7</text>/8 </view>
  7. <view class="title">
  8. <view>展示公司照片</view>
  9. </view>
  10. <view class="desc">在公司主页上展示亮眼的照片,体现企业氛围与文化魅力;最多上传20张</view>
  11. <view class="content-index">
  12. <!-- 多图上传区域 -->
  13. <view class="upload-section">
  14. <view class="images-grid">
  15. <!-- 已上传的图片 -->
  16. <view class="image-item" v-for="(image, index) in imageList" :key="index" @click="previewImage(index)">
  17. <image :src="image.url" mode="aspectFill" class="preview-image"></image>
  18. <view class="image-mask">
  19. <u-icon name="eye" color="#fff" size="30"></u-icon>
  20. </view>
  21. <view class="delete-btn" @click.stop="deleteImage(index)">
  22. <u-icon name="close" color="#fff" size="20"></u-icon>
  23. </view>
  24. </view>
  25. <!-- 添加图片按钮 -->
  26. <view class="upload-box" v-if="imageList.length < maxCount" @click="chooseImage">
  27. <view class="upload-placeholder">
  28. <u-icon name="plus" color="#999" size="40"></u-icon>
  29. <text class="upload-text">添加照片</text>
  30. </view>
  31. </view>
  32. </view>
  33. <!-- 上传计数 -->
  34. <view class="upload-count" v-if="imageList.length > 0">
  35. 已上传 {{ imageList.length }}/{{ maxCount }} 张
  36. </view>
  37. <!-- 上传进度 -->
  38. <view v-if="uploading" class="upload-progress">
  39. <view class="progress-bar">
  40. <view class="progress-inner" :style="{ width: uploadProgress + '%' }"></view>
  41. </view>
  42. <text class="progress-text">{{ uploadProgress }}%</text>
  43. </view>
  44. </view>
  45. <!-- 注意事项 -->
  46. <view class="warning-box">
  47. <view class="warning-title">注意事项:</view>
  48. <view class="warning-list">
  49. <view class="warning-item">1. 请上传清晰且完整的图片</view>
  50. <view class="warning-item">2.
  51. 请上传品牌相关的图片,含有其他内容将无法通过审核(包括但不限于含有水印、招聘信息、联系方式、二维码等相关内容)</view>
  52. <view class="warning-item">3. 上传图片须符合中国相关法律法规,不得含有违法内容或不良信息</view>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. </view>
  58. <view class="submit-btn" :class="{ disabled: imageList.length === 0 }" @click="goJobPostingSecond">下一步</view>
  59. <!-- 权限说明弹窗 -->
  60. <u-popup mode="top" ref="permission">
  61. <view class="popup-content">
  62. <view class="popup-text-permission">选择/拍摄照片需要相机/相册权限,用于上传用户头像</view>
  63. </view>
  64. </u-popup>
  65. </view>
  66. </template>
  67. <script>
  68. import navBar from "@/components/nav-bar/index.vue";
  69. export default {
  70. data() {
  71. return {
  72. text: "",
  73. imageList: [], // 上传的图片列表
  74. maxCount: 20, // 最大上传数量
  75. uploading: false, // 是否正在上传
  76. uploadProgress: 0, // 上传进度
  77. companyData: {}
  78. };
  79. },
  80. components: {
  81. navBar,
  82. },
  83. onLoad(options) {
  84. if (options.companyData) {
  85. this.companyData = JSON.parse(options.companyData);
  86. }
  87. },
  88. methods: {
  89. // 选择图片
  90. async chooseImage() {
  91. const that = this;
  92. const remainingCount = this.maxCount - this.imageList.length;
  93. // 1. 检查权限状态
  94. const hasPermission = await this.$queue.checkPermission(
  95. 'camera',
  96. '选择/拍摄照片需要相机/相册权限,用于上传用户头像',
  97. this
  98. );
  99. // 2. 如果未授权或者用户拒绝,显示提示
  100. if (!hasPermission) {
  101. return;
  102. }
  103. uni.chooseImage({
  104. count: remainingCount, // 最多选择剩余数量
  105. sizeType: ["compressed"],
  106. sourceType: ["album", "camera"],
  107. success: (res) => {
  108. const tempFilePaths = res.tempFilePaths;
  109. // 批量上传图片
  110. that.uploadMultipleImages(tempFilePaths);
  111. },
  112. fail: (error) => {
  113. console.log("选择图片失败:", error);
  114. uni.showToast({
  115. title: "选择图片失败",
  116. icon: "none",
  117. });
  118. },
  119. });
  120. },
  121. // 批量上传图片
  122. uploadMultipleImages(filePaths) {
  123. const that = this;
  124. that.uploading = true;
  125. that.uploadProgress = 0;
  126. // 模拟上传进度
  127. // const progressTimer = setInterval(() => {
  128. // that.uploadProgress += 10;
  129. // if (that.uploadProgress >= 90) {
  130. // clearInterval(progressTimer);
  131. // }
  132. // }, 100);
  133. // 模拟批量上传成功
  134. // setTimeout(() => {
  135. // clearInterval(progressTimer);
  136. // that.uploadProgress = 100;
  137. // // 将新图片添加到列表
  138. // const newImages = filePaths.map(filePath => ({
  139. // url: filePath,
  140. // // 实际开发中这里应该是服务器返回的URL
  141. // }));
  142. // that.imageList = [...that.imageList, ...newImages];
  143. // setTimeout(() => {
  144. // that.uploading = false;
  145. // uni.showToast({
  146. // title: `成功上传${newImages.length}张图片`,
  147. // icon: "success",
  148. // });
  149. // }, 500);
  150. // }, 1500);
  151. // 实际开发中应该使用下面的代码:
  152. let uploadedCount = 0;
  153. const totalCount = filePaths.length;
  154. filePaths.forEach((filePath, index) => {
  155. this.$queue.uploadFile(filePath, (path) => {
  156. if (path) {
  157. uploadedCount++;
  158. that.imageList.push({
  159. url: path
  160. });
  161. // 更新进度
  162. that.uploadProgress = Math.floor((uploadedCount / totalCount) * 100);
  163. // 所有图片上传完成
  164. if (uploadedCount === totalCount) {
  165. that.uploading = false;
  166. uni.showToast({
  167. title: `成功上传${uploadedCount}张图片`,
  168. icon: 'success'
  169. });
  170. }
  171. }
  172. else {
  173. uploadedCount++;
  174. console.log(`第${index + 1}张图片上传失败:`, error);
  175. if (uploadedCount === totalCount) {
  176. that.uploading = false;
  177. uni.showToast({
  178. title: '部分图片上传失败',
  179. icon: 'none'
  180. });
  181. }
  182. }
  183. })
  184. // uni.uploadFile({
  185. // url: '你的上传接口地址',
  186. // filePath: filePath,
  187. // name: 'file',
  188. // formData: {
  189. // 'type': 'company_photo'
  190. // },
  191. // success: (uploadRes) => {
  192. // uploadedCount++;
  193. // const data = JSON.parse(uploadRes.data);
  194. // if (data.code === 200) {
  195. // that.imageList.push({
  196. // url: data.data.url
  197. // });
  198. // }
  199. // // 更新进度
  200. // that.uploadProgress = Math.floor((uploadedCount / totalCount) * 100);
  201. // // 所有图片上传完成
  202. // if (uploadedCount === totalCount) {
  203. // that.uploading = false;
  204. // uni.showToast({
  205. // title: `成功上传${uploadedCount}张图片`,
  206. // icon: 'success'
  207. // });
  208. // }
  209. // },
  210. // fail: (error) => {
  211. // uploadedCount++;
  212. // console.log(`第${index + 1}张图片上传失败:`, error);
  213. // if (uploadedCount === totalCount) {
  214. // that.uploading = false;
  215. // uni.showToast({
  216. // title: '部分图片上传失败',
  217. // icon: 'none'
  218. // });
  219. // }
  220. // }
  221. // });
  222. });
  223. },
  224. // 预览图片
  225. previewImage(index) {
  226. if (this.imageList.length > 0) {
  227. const urls = this.imageList.map(item => item.url);
  228. uni.previewImage({
  229. urls: urls,
  230. current: index,
  231. });
  232. }
  233. },
  234. // 删除图片
  235. deleteImage(index) {
  236. const that = this;
  237. uni.showModal({
  238. title: "提示",
  239. content: "确定要删除这张照片吗?",
  240. success: (res) => {
  241. if (res.confirm) {
  242. that.imageList.splice(index, 1);
  243. uni.showToast({
  244. title: "删除成功",
  245. icon: "success",
  246. });
  247. }
  248. },
  249. });
  250. },
  251. // 下一步
  252. goJobPostingSecond() {
  253. if (this.imageList.length === 0) {
  254. uni.showToast({
  255. title: "请上传公司照片",
  256. icon: "none",
  257. });
  258. return;
  259. }
  260. // 跳转到下一页,传递图片数据
  261. const imageUrls = this.imageList.map(item => item.url);
  262. const companyData = this.companyData
  263. companyData.photos = imageUrls.join(',')
  264. uni.navigateTo({
  265. url: "/my/renzheng/mainWorkIntro?companyData=" + encodeURIComponent(JSON.stringify(companyData)),
  266. });
  267. },
  268. },
  269. };
  270. </script>
  271. <style lang="scss" scoped>
  272. .switch-roles {
  273. background-color: #fff;
  274. position: absolute;
  275. left: 0;
  276. right: 0;
  277. top: 0;
  278. bottom: 0;
  279. display: flex;
  280. flex-direction: column;
  281. .roles-content {
  282. width: 100%;
  283. flex: 1;
  284. overflow: hidden;
  285. overflow-y: auto;
  286. .content {
  287. padding: 40rpx;
  288. box-sizing: border-box;
  289. display: flex;
  290. flex-direction: column;
  291. align-items: center;
  292. justify-content: center;
  293. .progress-num {
  294. color: #016bf6;
  295. font-family: DM Sans;
  296. font-size: 24rpx;
  297. font-weight: 500;
  298. width: 100%;
  299. padding-bottom: 20rpx;
  300. box-sizing: border-box;
  301. text {
  302. font-size: 48rpx;
  303. font-weight: 700;
  304. }
  305. }
  306. .title {
  307. color: #333;
  308. width: 100%;
  309. font-family: DM Sans;
  310. font-size: 48rpx;
  311. font-weight: 700;
  312. display: flex;
  313. justify-content: space-between;
  314. align-items: center;
  315. margin-bottom: 20rpx;
  316. }
  317. .desc {
  318. color: rgba(102, 102, 102, 1);
  319. width: 100%;
  320. font-family: DM Sans;
  321. font-size: 24rpx;
  322. font-weight: 400;
  323. line-height: 32rpx;
  324. letter-spacing: 0.5%;
  325. text-align: left;
  326. box-sizing: border-box;
  327. margin-bottom: 40rpx;
  328. }
  329. .content-index {
  330. width: 100%;
  331. .upload-section {
  332. margin-bottom: 20rpx;
  333. .images-grid {
  334. display: grid;
  335. grid-template-columns: repeat(4, 1fr);
  336. gap: 20rpx;
  337. margin-bottom: 20rpx;
  338. .image-item {
  339. width: 142rpx;
  340. height: 142rpx;
  341. border-radius: 8rpx;
  342. position: relative;
  343. overflow: hidden;
  344. .preview-image {
  345. width: 100%;
  346. height: 100%;
  347. }
  348. .image-mask {
  349. position: absolute;
  350. top: 0;
  351. left: 0;
  352. width: 100%;
  353. height: 100%;
  354. background: rgba(0, 0, 0, 0.3);
  355. display: flex;
  356. align-items: center;
  357. justify-content: center;
  358. opacity: 0;
  359. transition: opacity 0.3s;
  360. }
  361. .delete-btn {
  362. position: absolute;
  363. top: 8rpx;
  364. right: 8rpx;
  365. width: 30rpx;
  366. height: 30rpx;
  367. background: rgba(0, 0, 0, 0.5);
  368. border-radius: 50%;
  369. display: flex;
  370. align-items: center;
  371. justify-content: center;
  372. }
  373. &:active .image-mask {
  374. opacity: 1;
  375. }
  376. }
  377. .upload-box {
  378. width: 142rpx;
  379. height: 142rpx;
  380. border-radius: 8rpx;
  381. display: flex;
  382. align-items: center;
  383. justify-content: center;
  384. background: #eee;
  385. .upload-placeholder {
  386. display: flex;
  387. flex-direction: column;
  388. align-items: center;
  389. justify-content: center;
  390. .upload-text {
  391. color: #666;
  392. font-size: 20rpx;
  393. margin-top: 8rpx;
  394. font-family: DM Sans;
  395. }
  396. }
  397. }
  398. }
  399. .upload-count {
  400. color: #666;
  401. font-size: 24rpx;
  402. text-align: center;
  403. margin-bottom: 20rpx;
  404. }
  405. .upload-progress {
  406. display: flex;
  407. align-items: center;
  408. gap: 20rpx;
  409. .progress-bar {
  410. flex: 1;
  411. height: 8rpx;
  412. background: #f0f0f0;
  413. border-radius: 4rpx;
  414. overflow: hidden;
  415. .progress-inner {
  416. height: 100%;
  417. background: #016bf6;
  418. border-radius: 4rpx;
  419. transition: width 0.3s;
  420. }
  421. }
  422. .progress-text {
  423. color: #016bf6;
  424. font-size: 24rpx;
  425. min-width: 80rpx;
  426. }
  427. }
  428. }
  429. .warning-box {
  430. color: rgba(102, 102, 102, 1);
  431. font-family: DM Sans;
  432. font-size: 24rpx;
  433. font-weight: 400;
  434. line-height: 32rpx;
  435. .warning-item {
  436. margin-top: 8rpx;
  437. }
  438. }
  439. }
  440. }
  441. }
  442. .submit-btn {
  443. flex-shrink: 0;
  444. border-radius: 999px;
  445. background: #ff6600;
  446. color: rgba(255, 255, 255, 1);
  447. font-family: DM Sans;
  448. font-size: 32rpx;
  449. font-weight: 400;
  450. line-height: 48rpx;
  451. display: flex;
  452. justify-content: center;
  453. align-items: center;
  454. padding: 24rpx 32rpx;
  455. box-sizing: border-box;
  456. margin: 30rpx 40rpx;
  457. margin-top: 20rpx;
  458. &.disabled {
  459. background: #ccc;
  460. color: #999;
  461. }
  462. }
  463. }
  464. </style>