邃芒智像(Uniapp : WX、TT、H5)
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

470 Zeilen
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 {
  109. findByIdApi,
  110. findImageApi,
  111. createPhotoApi,
  112. } from "../../api/closeStyle";
  113. import { findGlodApi } from "../../api/home";
  114. import { userInfoModules } from "@/store/modules/userInfo";
  115. //#endregion
  116. const userInfoModulesPinia = userInfoModules();
  117. //#region 初始化
  118. const styleId = ref(null);
  119. const styleData = ref({});
  120. onLoad((options) => {
  121. // styleId.value = options.id;
  122. // styleId.value = "857147862095679488";
  123. styleId.value = "2003";
  124. // styleId.value = "246";
  125. getInfo();
  126. // getMyCoin();
  127. });
  128. async function getInfo() {
  129. try {
  130. const res = await findByIdApi(styleId.value);
  131. console.log(res);
  132. styleData.value = res.data;
  133. } catch (error) {
  134. uni.showToast({
  135. title: "获取数据失败,请重试",
  136. icon: "none",
  137. });
  138. }
  139. }
  140. // 查询我的金币
  141. async function getMyCoin() {
  142. const res4 = await findGlodApi();
  143. if (!res4.data) {
  144. userInfoModulesPinia.myGlod = 0;
  145. } else {
  146. userInfoModulesPinia.myGlod = res4.data.digitalAvatarResidueGlod
  147. ? res4.data.digitalAvatarResidueGlod
  148. : 0;
  149. }
  150. }
  151. //#endregion ---------------------
  152. //#region 上传图片
  153. const avatarList = ref([
  154. {
  155. url: userInfoModulesPinia.myAvatar,
  156. // url: "https://suimang.oss-accelerate.aliyuncs.com/builtin/digital_avatar/girl/%E9%A3%8E%E9%87%87%E5%87%BA%E4%BC%97.jpg",
  157. isMyAvatar: true,
  158. },
  159. {
  160. url: "",
  161. // url: "https://suimang.oss-accelerate.aliyuncs.com/builtin/digital_avatar/girl/%E9%AA%8F%E9%A9%AC%E4%BD%B3%E4%BA%BA.jpg",
  162. isMyAvatar: false,
  163. },
  164. {
  165. url: "",
  166. // url: "https://suimang.oss-accelerate.aliyuncs.com/builtin/digital_avatar/girl/%E7%B4%AB%E8%96%87%E7%90%B4%E9%9F%B5.png",
  167. isMyAvatar: false,
  168. },
  169. ]);
  170. // 切换位置
  171. function swapItems() {
  172. const temp = avatarList.value[0];
  173. avatarList.value[0] = avatarList.value[1];
  174. avatarList.value[1] = temp;
  175. }
  176. function swapItems2() {
  177. const temp = avatarList.value[1];
  178. avatarList.value[1] = avatarList.value[2];
  179. avatarList.value[2] = temp;
  180. }
  181. // 打开图片选择,包含了百度检测人脸检测和上传图片
  182. function chooseImg(index) {
  183. uni.chooseImage({
  184. count: 1,
  185. success: async (res) => {
  186. console.log(res, "887");
  187. uni.showLoading({
  188. title: "上传中...",
  189. mask: true,
  190. });
  191. // 百度敏感信息检测
  192. uni.uploadFile({
  193. url: "https://test.metavatar.cc/C/api/baidu/checkPhoto", //上传图片api
  194. filePath: res.tempFilePaths[0],
  195. name: "file",
  196. formData: {
  197. user: "test",
  198. },
  199. header: {
  200. // Authorization: userInfoModulesPinia.token,
  201. token: userInfoModulesPinia.token,
  202. },
  203. success: async (res2) => {
  204. if (JSON.parse(res2.data).code != 200) {
  205. uni.hideLoading();
  206. uni.showToast({
  207. title: "图片不符合规范, 请重试",
  208. icon: "none",
  209. });
  210. return;
  211. } else {
  212. // 人脸识别接口
  213. uni.uploadFile({
  214. url: "https://test.metavatar.cc/C/api/userDigital/checkPhoto", //上传图片api
  215. filePath: res.tempFilePaths[0],
  216. name: "file",
  217. formData: {
  218. user: "test",
  219. },
  220. header: {
  221. // Authorization: userInfoModulesPinia.token,
  222. token: userInfoModulesPinia.token,
  223. },
  224. success: (res3) => {
  225. if (JSON.parse(res3.data).code != 200) {
  226. uni.hideLoading();
  227. uni.showToast({
  228. title: "图片不符合规范, 请重试",
  229. icon: "none",
  230. });
  231. return;
  232. } else {
  233. // 上传接口
  234. uni.uploadFile({
  235. url: "https://test.metavatar.cc/C/api/upload/awsImgUpload", //上传图片api
  236. filePath: res.tempFilePaths[0],
  237. name: "file",
  238. formData: {
  239. user: "test",
  240. },
  241. header: {
  242. "Content-Type": "multipart/form-data",
  243. token: userInfoModulesPinia.token,
  244. },
  245. success: async (res4) => {
  246. if (JSON.parse(res4.data).code != 200) {
  247. uni.hideLoading();
  248. uni.showToast({
  249. title: "网络被数字人偷走了, 请稍后重试",
  250. icon: "none",
  251. });
  252. return;
  253. }
  254. // 赋值
  255. avatarList.value[index].url = JSON.parse(
  256. res4.data
  257. ).data.url;
  258. uni.hideLoading();
  259. },
  260. fail: () => {
  261. uni.hideLoading();
  262. uni.showToast({
  263. title: "网络被数字人偷走了, 请稍后重试",
  264. icon: "none",
  265. });
  266. },
  267. });
  268. }
  269. },
  270. fail: () => {
  271. uni.hideLoading();
  272. uni.showToast({
  273. title: "网络被数字人偷走了, 请稍后重试",
  274. icon: "none",
  275. });
  276. },
  277. });
  278. }
  279. },
  280. fail: (err) => {
  281. console.error("选择图片失败", err);
  282. uni.hideLoading();
  283. uni.showToast({
  284. title: "选择图片失败, 请稍后重试",
  285. icon: "none",
  286. });
  287. },
  288. });
  289. },
  290. fail: (err) => {
  291. console.error("选择图片失败", err);
  292. uni.showToast({
  293. title: "选择图片失败, 请稍后重试",
  294. icon: "none",
  295. });
  296. },
  297. });
  298. }
  299. // 上传图片
  300. function uploadImg(index) {}
  301. //#endregion ---------------------
  302. //#region 生成写真照片
  303. async function createing(id) {
  304. try {
  305. uni.showLoading({
  306. title: "加载中...",
  307. mask: true,
  308. });
  309. // const res = await findImageApi();
  310. // console.log(res);
  311. // let myImg = res.data.image;
  312. let myImgList = [];
  313. avatarList.value.forEach((item) => {
  314. myImgList.push(item.url);
  315. });
  316. const data = {
  317. digitalAvatarId: id,
  318. userImages:
  319. styleData.value.mouldType == 2
  320. ? JSON.stringify(myImgList.slice(0, 2))
  321. : JSON.stringify(myImgList),
  322. };
  323. const res2 = await createPhotoApi(data);
  324. console.log(res2);
  325. uni.hideLoading();
  326. uni.navigateTo({
  327. url: `/pages/createing/index?id=${res2.data.id}`,
  328. });
  329. } catch (error) {
  330. console.log(error);
  331. uni.hideLoading();
  332. uni.showToast({
  333. title: "生成失败,请重试",
  334. icon: "none",
  335. });
  336. }
  337. }
  338. //#endregion ---------------------
  339. //#region
  340. //#endregion ---------------------
  341. </script>
  342. <style lang="scss">
  343. .page {
  344. background-color: rgba(24, 25, 26, 1);
  345. }
  346. .showImgBox {
  347. margin-top: 30rpx;
  348. width: 360rpx;
  349. height: 480rpx;
  350. // background-color: #ccc;
  351. border-radius: 30rpx;
  352. image {
  353. width: 100%;
  354. height: 100%;
  355. border-radius: 30rpx;
  356. }
  357. }
  358. .name {
  359. margin-top: 70rpx;
  360. margin-bottom: 47rpx;
  361. font-size: 44rpx;
  362. font-weight: 800;
  363. }
  364. .imgBox {
  365. margin-bottom: 40rpx;
  366. width: 100%;
  367. // height: 180rpx;
  368. display: flex;
  369. justify-content: space-between;
  370. align-items: flex-start;
  371. .exchange {
  372. width: 60rpx;
  373. height: 60rpx;
  374. margin-top: 67rpx;
  375. }
  376. .imgBoxItem {
  377. position: relative;
  378. width: 180rpx;
  379. height: 250rpx;
  380. display: flex;
  381. flex-direction: column;
  382. align-items: center;
  383. .avatar {
  384. position: absolute;
  385. width: 180rpx;
  386. height: 180rpx;
  387. border-radius: 24rpx;
  388. }
  389. .noUrlBox {
  390. position: absolute;
  391. width: 180rpx;
  392. height: 180rpx;
  393. line-height: 180rpx;
  394. color: #ff4f00;
  395. font-size: 50rpx;
  396. font-weight: 900;
  397. text-align: center;
  398. border-radius: 24rpx;
  399. background-color: #393a3d;
  400. }
  401. .maskTips {
  402. position: absolute;
  403. width: 180rpx;
  404. height: 180rpx;
  405. line-height: 180rpx;
  406. color: #fff;
  407. font-size: 20rpx;
  408. font-weight: 900;
  409. text-align: center;
  410. border-radius: 24rpx;
  411. background-color: rgba(0, 0, 0, 0.3);
  412. }
  413. .reUploadBtn,
  414. .uploadBtn {
  415. margin-top: 200rpx;
  416. width: 150rpx;
  417. height: 50rpx;
  418. text-align: center;
  419. line-height: 50rpx;
  420. border-radius: 50rpx;
  421. background-color: #383a3c;
  422. }
  423. }
  424. }
  425. .tips {
  426. font-size: 22rpx;
  427. }
  428. .orangeBtn {
  429. position: relative;
  430. margin-top: 60rpx;
  431. .free {
  432. position: absolute;
  433. top: -18rpx;
  434. right: -70rpx;
  435. width: 142rpx;
  436. height: 50rpx;
  437. background-color: #000;
  438. border-radius: 25rpx 25rpx 25rpx 0;
  439. font-size: 22rpx;
  440. font-weight: 900;
  441. line-height: 50rpx;
  442. text-align: center;
  443. }
  444. }
  445. .balance {
  446. display: inline-block;
  447. margin-top: 70rpx;
  448. font-size: 30rpx;
  449. font-weight: bold;
  450. line-height: 33rpx;
  451. image {
  452. display: inline-block;
  453. width: 33rpx;
  454. height: 33rpx;
  455. vertical-align: middle;
  456. }
  457. }
  458. </style>