邃芒智像(Uniapp : WX、TT、H5)
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.
 
 
 
 

482 line
12 KiB

  1. <template>
  2. <view class="page">
  3. <view class="showImgBox imgContenBox"
  4. ><image :src="styleData.coverImg"
  5. /></view>
  6. <text class="name">{{ styleData.title }}</text>
  7. <view class="imgBox">
  8. <!-- 图一 -->
  9. <view class="imgBoxItem">
  10. <image class="avatar" :src="avatarList[0].url" mode="aspectFill" />
  11. <view v-if="!avatarList[0].url" class="noUrlBox" @click="chooseImg(0)"
  12. >+</view
  13. >
  14. <!-- 遮罩层 -->
  15. <view v-if="avatarList[0].url" class="maskTips">{{
  16. avatarList[0].isMyAvatar ? "授权用户头像" : "已上传第1个头像"
  17. }}</view>
  18. <view
  19. v-if="avatarList[0].url && !avatarList[0].isMyAvatar"
  20. class="reUploadBtn"
  21. @click="chooseImg(0)"
  22. >更换头像</view
  23. >
  24. <view
  25. v-if="!avatarList[0].url && !avatarList[0].isMyAvatar"
  26. class="uploadBtn"
  27. @click="chooseImg(0)"
  28. >上传头像</view
  29. >
  30. </view>
  31. <image
  32. @click="swapItems"
  33. class="exchange"
  34. src="../../assets/icon/exchange.png"
  35. mode="scaleToFill"
  36. />
  37. <!-- 图二 -->
  38. <view class="imgBoxItem">
  39. <image class="avatar" :src="avatarList[1].url" mode="aspectFill" />
  40. <view v-if="!avatarList[1].url" class="noUrlBox" @click="chooseImg(1)"
  41. >+</view
  42. >
  43. <!-- 遮罩层 -->
  44. <view v-if="avatarList[1].url" class="maskTips">{{
  45. avatarList[1].isMyAvatar ? "授权用户头像" : "已上传第2个头像"
  46. }}</view>
  47. <view
  48. v-if="avatarList[1].url && !avatarList[1].isMyAvatar"
  49. class="reUploadBtn"
  50. @click="chooseImg(1)"
  51. >更换头像</view
  52. >
  53. <view
  54. v-if="!avatarList[1].url && !avatarList[1].isMyAvatar"
  55. class="uploadBtn"
  56. @click="chooseImg(1)"
  57. >上传头像</view
  58. >
  59. </view>
  60. <image
  61. v-if="styleData.mouldType == 3"
  62. @click="swapItems2"
  63. class="exchange"
  64. src="../../assets/icon/exchange.png"
  65. mode="scaleToFill"
  66. />
  67. <!-- 图三 -->
  68. <view v-if="styleData.mouldType == 3" class="imgBoxItem">
  69. <image class="avatar" :src="avatarList[2].url" mode="aspectFill" />
  70. <view v-if="!avatarList[2].url" class="noUrlBox" @click="chooseImg(2)"
  71. >+</view
  72. >
  73. <!-- 遮罩层 -->
  74. <view v-if="avatarList[2].url" class="maskTips">{{
  75. avatarList[2].isMyAvatar ? "授权用户头像" : "已上传第3个头像"
  76. }}</view>
  77. <view
  78. v-if="avatarList[2].url && !avatarList[2].isMyAvatar"
  79. class="reUploadBtn"
  80. @click="chooseImg(2)"
  81. >更换头像</view
  82. >
  83. <view
  84. v-if="!avatarList[2].url && !avatarList[2].isMyAvatar"
  85. class="uploadBtn"
  86. @click="chooseImg(2)"
  87. >上传头像</view
  88. >
  89. </view>
  90. </view>
  91. <text class="tips">人物头像对应模板人物位置,点击按钮可以调整顺序</text>
  92. <view class="orangeBtn" @click="createing(styleData.id)"
  93. >开始制作写真
  94. <view class="free">
  95. <text>耗金币{{ styleData.salePrice }}枚</text>
  96. </view>
  97. </view>
  98. <view class="balance"
  99. >金币余额:&nbsp;&nbsp;{{ userInfoModulesPinia.myGlod }}
  100. <image src="../../assets/icon/coin.png" mode="aspectFit" />
  101. </view>
  102. </view>
  103. </template>
  104. <script setup>
  105. //#region 导入
  106. import { ref, reactive } from "vue";
  107. import { onLoad } from "@dcloudio/uni-app";
  108. import { BASE_URL } from "@/utils/request";
  109. import {
  110. findByIdApi,
  111. findImageApi,
  112. createPhotoApi,
  113. } from "../../api/closeStyle";
  114. import { findGlodApi } from "../../api/home";
  115. import { userInfoModules } from "@/store/modules/userInfo";
  116. //#endregion
  117. const userInfoModulesPinia = userInfoModules();
  118. //#region 初始化
  119. const styleId = ref(null);
  120. const styleData = ref({});
  121. onLoad((options) => {
  122. styleId.value = options.id;
  123. // styleId.value = "857147862095679488";
  124. // styleId.value = "2003";
  125. // styleId.value = "246";
  126. getInfo();
  127. // getMyCoin();
  128. });
  129. async function getInfo() {
  130. try {
  131. const res = await findByIdApi(styleId.value);
  132. console.log(res);
  133. styleData.value = res.data;
  134. } catch (error) {
  135. uni.showToast({
  136. title: "获取数据失败,请重试",
  137. icon: "none",
  138. });
  139. }
  140. }
  141. // 查询我的金币
  142. async function getMyCoin() {
  143. const res4 = await findGlodApi();
  144. if (!res4.data) {
  145. userInfoModulesPinia.myGlod = 0;
  146. } else {
  147. userInfoModulesPinia.myGlod = res4.data.digitalAvatarResidueGlod
  148. ? res4.data.digitalAvatarResidueGlod
  149. : 0;
  150. }
  151. }
  152. //#endregion ---------------------
  153. //#region 上传图片
  154. const avatarList = ref([
  155. {
  156. url: userInfoModulesPinia.myAvatar,
  157. isMyAvatar: true,
  158. },
  159. {
  160. url: "",
  161. isMyAvatar: false,
  162. },
  163. {
  164. url: "",
  165. isMyAvatar: false,
  166. },
  167. ]);
  168. // 切换位置
  169. function swapItems() {
  170. const temp = avatarList.value[0];
  171. avatarList.value[0] = avatarList.value[1];
  172. avatarList.value[1] = temp;
  173. }
  174. function swapItems2() {
  175. const temp = avatarList.value[1];
  176. avatarList.value[1] = avatarList.value[2];
  177. avatarList.value[2] = temp;
  178. }
  179. // 打开图片选择,包含了百度检测人脸检测和上传图片
  180. function chooseImg(index) {
  181. uni.chooseImage({
  182. count: 1,
  183. success: async (res) => {
  184. console.log(res, "887");
  185. uni.showLoading({
  186. title: "上传中...",
  187. mask: true,
  188. });
  189. // 百度敏感信息检测
  190. uni.uploadFile({
  191. url: BASE_URL + "api/baidu/checkPhoto", //上传图片api
  192. filePath: res.tempFilePaths[0],
  193. name: "file",
  194. formData: {
  195. user: "test",
  196. },
  197. header: {
  198. // Authorization: userInfoModulesPinia.token,
  199. token: userInfoModulesPinia.token,
  200. },
  201. success: async (res2) => {
  202. if (JSON.parse(res2.data).code != 200) {
  203. uni.hideLoading();
  204. uni.showToast({
  205. title: "图片不符合规范, 请重试",
  206. icon: "none",
  207. });
  208. return;
  209. } else {
  210. // 人脸识别接口
  211. uni.uploadFile({
  212. url: BASE_URL + "api/userDigital/checkPhoto", //上传图片api
  213. filePath: res.tempFilePaths[0],
  214. name: "file",
  215. formData: {
  216. user: "test",
  217. },
  218. header: {
  219. // Authorization: userInfoModulesPinia.token,
  220. token: userInfoModulesPinia.token,
  221. },
  222. success: (res3) => {
  223. if (JSON.parse(res3.data).code != 200) {
  224. uni.hideLoading();
  225. uni.showToast({
  226. title: "图片不符合规范, 请重试",
  227. icon: "none",
  228. });
  229. return;
  230. } else {
  231. // 上传接口
  232. uni.uploadFile({
  233. url: BASE_URL + "api/upload/awsImgUpload", //上传图片api
  234. filePath: res.tempFilePaths[0],
  235. name: "file",
  236. formData: {
  237. user: "test",
  238. },
  239. header: {
  240. "Content-Type": "multipart/form-data",
  241. token: userInfoModulesPinia.token,
  242. },
  243. success: async (res4) => {
  244. if (JSON.parse(res4.data).code != 200) {
  245. uni.hideLoading();
  246. uni.showToast({
  247. title: "网络被数字人偷走了, 请稍后重试",
  248. icon: "none",
  249. });
  250. return;
  251. }
  252. // 赋值
  253. avatarList.value[index].url = JSON.parse(
  254. res4.data
  255. ).data.url;
  256. uni.hideLoading();
  257. },
  258. fail: () => {
  259. uni.hideLoading();
  260. uni.showToast({
  261. title: "网络被数字人偷走了, 请稍后重试",
  262. icon: "none",
  263. });
  264. },
  265. });
  266. }
  267. },
  268. fail: () => {
  269. uni.hideLoading();
  270. uni.showToast({
  271. title: "网络被数字人偷走了, 请稍后重试",
  272. icon: "none",
  273. });
  274. },
  275. });
  276. }
  277. },
  278. fail: (err) => {
  279. console.error("选择图片失败", err);
  280. uni.hideLoading();
  281. uni.showToast({
  282. title: "选择图片失败, 请稍后重试",
  283. icon: "none",
  284. });
  285. },
  286. });
  287. },
  288. fail: (err) => {
  289. console.error("选择图片失败", err);
  290. uni.showToast({
  291. title: "选择图片失败, 请稍后重试",
  292. icon: "none",
  293. });
  294. },
  295. });
  296. }
  297. // 上传图片
  298. function uploadImg(index) {}
  299. //#endregion ---------------------
  300. //#region 生成写真照片
  301. async function createing(id) {
  302. try {
  303. uni.showLoading({
  304. title: "加载中...",
  305. mask: true,
  306. });
  307. // const res = await findImageApi();
  308. // console.log(res);
  309. // let myImg = res.data.image;
  310. let myImgList = [];
  311. avatarList.value.forEach((item) => {
  312. myImgList.push(item.url);
  313. });
  314. const data = {
  315. title: styleData.value.title,
  316. digitalAvatarId: id,
  317. userImages:
  318. styleData.value.mouldType == 2
  319. ? JSON.stringify(myImgList.slice(0, 2))
  320. : JSON.stringify(myImgList),
  321. };
  322. if (
  323. myImgList[0].length == 0 ||
  324. myImgList[1].length == 0 ||
  325. (styleData.value.mouldType == 3 && myImgList[2].length == 0)
  326. ) {
  327. uni.showToast({
  328. title: "头像未上传",
  329. icon: "none",
  330. mask: true,
  331. });
  332. return;
  333. }
  334. const res2 = await createPhotoApi(data);
  335. console.log(res2);
  336. uni.hideLoading();
  337. uni.navigateTo({
  338. url: `/pages/lookPhoto/index?id=${res2.data.id}`,
  339. });
  340. } catch (error) {
  341. console.log(error);
  342. uni.hideLoading();
  343. uni.showToast({
  344. title: "生成失败,请重试",
  345. icon: "none",
  346. });
  347. }
  348. }
  349. //#endregion ---------------------
  350. //#region
  351. //#endregion ---------------------
  352. </script>
  353. <style lang="scss">
  354. .page {
  355. background-color: rgba(24, 25, 26, 1);
  356. }
  357. .showImgBox {
  358. margin-top: 30rpx;
  359. width: 360rpx;
  360. height: 480rpx;
  361. // background-color: #ccc;
  362. border-radius: 30rpx;
  363. image {
  364. width: 100%;
  365. height: 100%;
  366. border-radius: 30rpx;
  367. }
  368. }
  369. .name {
  370. margin-top: 70rpx;
  371. margin-bottom: 47rpx;
  372. font-size: 44rpx;
  373. font-weight: 800;
  374. }
  375. .imgBox {
  376. margin-bottom: 40rpx;
  377. width: 100%;
  378. // height: 180rpx;
  379. display: flex;
  380. justify-content: space-between;
  381. align-items: flex-start;
  382. .exchange {
  383. width: 60rpx;
  384. height: 60rpx;
  385. margin-top: 67rpx;
  386. }
  387. .imgBoxItem {
  388. position: relative;
  389. width: 180rpx;
  390. height: 250rpx;
  391. display: flex;
  392. flex-direction: column;
  393. align-items: center;
  394. .avatar {
  395. position: absolute;
  396. width: 180rpx;
  397. height: 180rpx;
  398. border-radius: 24rpx;
  399. }
  400. .noUrlBox {
  401. position: absolute;
  402. width: 180rpx;
  403. height: 180rpx;
  404. line-height: 180rpx;
  405. color: #ff4f00;
  406. font-size: 50rpx;
  407. font-weight: 900;
  408. text-align: center;
  409. border-radius: 24rpx;
  410. background-color: #393a3d;
  411. }
  412. .maskTips {
  413. position: absolute;
  414. width: 180rpx;
  415. height: 180rpx;
  416. line-height: 180rpx;
  417. color: #fff;
  418. font-size: 20rpx;
  419. font-weight: 900;
  420. text-align: center;
  421. border-radius: 24rpx;
  422. background-color: rgba(0, 0, 0, 0.3);
  423. }
  424. .reUploadBtn,
  425. .uploadBtn {
  426. margin-top: 200rpx;
  427. width: 150rpx;
  428. height: 50rpx;
  429. text-align: center;
  430. line-height: 50rpx;
  431. border-radius: 50rpx;
  432. background-color: #383a3c;
  433. }
  434. }
  435. }
  436. .tips {
  437. font-size: 22rpx;
  438. }
  439. .orangeBtn {
  440. position: relative;
  441. margin-top: 60rpx;
  442. .free {
  443. position: absolute;
  444. top: -18rpx;
  445. right: -70rpx;
  446. width: 142rpx;
  447. height: 50rpx;
  448. background-color: #000;
  449. border-radius: 25rpx 25rpx 25rpx 0;
  450. font-size: 22rpx;
  451. font-weight: 900;
  452. line-height: 50rpx;
  453. text-align: center;
  454. }
  455. }
  456. .balance {
  457. display: inline-block;
  458. margin-top: 70rpx;
  459. font-size: 30rpx;
  460. font-weight: bold;
  461. line-height: 33rpx;
  462. image {
  463. display: inline-block;
  464. width: 33rpx;
  465. height: 33rpx;
  466. vertical-align: middle;
  467. }
  468. }
  469. </style>