companyImg.vue 11 KB

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