瀏覽代碼

upload

dev_YWQ
HolyKnightIX 1 年之前
當前提交
cac77d3ca9
共有 39 個文件被更改,包括 7803 次插入0 次删除
  1. +6
    -0
      .env.development
  2. +21
    -0
      .gitignore
  3. +5
    -0
      H5_config.json
  4. +17
    -0
      README.md
  5. +32
    -0
      index.html
  6. +75
    -0
      package.json
  7. +10
    -0
      shims-uni.d.ts
  8. +22
    -0
      src/App.vue
  9. +26
    -0
      src/api/camera.js
  10. +34
    -0
      src/api/closeStyle.js
  11. +26
    -0
      src/api/createing.js
  12. +42
    -0
      src/api/login.js
  13. +66
    -0
      src/api/lookPhoto.js
  14. 二進制
      src/assets/img/QRCode.jpg
  15. 二進制
      src/assets/img/c867236efb4fc5707257ef8daf26db4.png
  16. 二進制
      src/assets/img/homeImg.jpg
  17. 二進制
      src/assets/img/logo-4.png
  18. 二進制
      src/assets/img/people.png
  19. 二進制
      src/assets/img/photoBtn.png
  20. 二進制
      src/assets/img/reTry.png
  21. 二進制
      src/assets/img/selectImg.png
  22. 二進制
      src/assets/img/success.png
  23. +15
    -0
      src/main.js
  24. +72
    -0
      src/manifest.json
  25. +57
    -0
      src/pages.json
  26. +947
    -0
      src/pages/camera/index.vue
  27. +435
    -0
      src/pages/chooseStyle/index.vue
  28. +547
    -0
      src/pages/created/index.vue
  29. +521
    -0
      src/pages/createing/index.vue
  30. +166
    -0
      src/pages/login/index.vue
  31. +6
    -0
      src/shime-uni.d.ts
  32. +10
    -0
      src/store/index.js
  33. +51
    -0
      src/store/modules/userInfo.js
  34. +109
    -0
      src/style/my.scss
  35. +77
    -0
      src/uni.scss
  36. +0
    -0
      src/utils/index.js
  37. +64
    -0
      src/utils/request.js
  38. +30
    -0
      vite.config.js
  39. +4314
    -0
      yarn.lock

+ 6
- 0
.env.development 查看文件

@@ -0,0 +1,6 @@
## 开发环境
NODE_ENV='development'

VITE_APP_TITLE = 'Metavatar-PC'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = 'https://test.metavatar.cc/C'

+ 21
- 0
.gitignore 查看文件

@@ -0,0 +1,21 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.DS_Store
dist
*.local

# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

+ 5
- 0
H5_config.json 查看文件

@@ -0,0 +1,5 @@
{
"Name": "Metavatar_Screen_Android",
"Version": "1.0.0",
"H5_Url": "https://zhixiang.malls.iformall.com"
}

+ 17
- 0
README.md 查看文件

@@ -0,0 +1,17 @@
# Suimang-wxapp

# setStorageSync 键名

SN --设备识别码
androidId --安卓识别码
token --token
UserId --扫码登录后获取的用户id
createTimes --用户剩余生成次数

在线地址:https://zhixiangtest.malls.iformall.com

wx-"appid": "",

git commit -m "feat: "
git commit --no-verify -m "提交时的注释" 跳过检验
git merge origin/dev_

+ 32
- 0
index.html 查看文件

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<script>
function androidCallback(name, result_str) {
window.localStorage.setItem('androidIdByWindow', result_str)
// alert("callBack " + name + " : " + result_str + "\n");
}
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>

<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/src/main.js"></script>
</body>

</html>

+ 75
- 0
package.json 查看文件

@@ -0,0 +1,75 @@
{
"name": "uni-preset-vue",
"version": "0.0.0",
"scripts": {
"dev:app": "uni -p app",
"dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-jd": "uni -p mp-jd",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:app-android": "uni build -p app-android",
"build:app-ios": "uni build -p app-ios",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-jd": "uni build -p mp-jd",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3081220230817001",
"@dcloudio/uni-app-plus": "3.0.0-3081220230817001",
"@dcloudio/uni-components": "3.0.0-3081220230817001",
"@dcloudio/uni-h5": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-alipay": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-baidu": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-jd": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-lark": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-qq": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3081220230817001",
"@dcloudio/uni-mp-weixin": "3.0.0-3081220230817001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3081220230817001",
"clipboard": "^2.0.11",
"dayjs": "^1.11.10",
"pinia": "2.0.33",
"uview-plus": "^3.1.37",
"video.js": "^8.5.2",
"vue": "^3.2.45",
"vue-i18n": "^9.1.9",
"webcamjs": "^1.0.26"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "3.0.0-3081220230817001",
"@dcloudio/uni-cli-shared": "3.0.0-3081220230817001",
"@dcloudio/uni-stacktracey": "3.0.0-3081220230817001",
"@dcloudio/vite-plugin-uni": "3.0.0-3081220230817001",
"@vue/runtime-core": "^3.2.45",
"pinia-plugin-unistorage": "0.0.17",
"sass": "^1.68.0",
"sass-loader": "^13.3.2",
"vite": "4.1.4"
}
}

+ 10
- 0
shims-uni.d.ts 查看文件

@@ -0,0 +1,10 @@
/// <reference types='@dcloudio/types' />
import 'vue'

declare module '@vue/runtime-core' {
type Hooks = App.AppInstance & Page.PageInstance;

interface ComponentCustomOptions extends Hooks {

}
}

+ 22
- 0
src/App.vue 查看文件

@@ -0,0 +1,22 @@
<script>
export default {
onLaunch: function () {
// console.log('App Launch')
uni.setStorageSync("plat", 4);
},
onShow: function () {
// console.log('App Show')
},
onHide: function () {
// console.log('App Hide')
},
};
</script>

<style>
/*每个页面公共css */
</style>
<style lang="scss">
/* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
@import "uview-plus/index.scss";
</style>

+ 26
- 0
src/api/camera.js 查看文件

@@ -0,0 +1,26 @@
import { request } from "../utils/request"

/**
* @description:获取上传二维码
* @param machineQrcodeId
* @return: status
*/
export function getImageQrcode(data) {
return request({
url: `/api/screenImg/imageQrcode`,
method: 'post',
data
})
}

/**
* @description:轮询-获取扫码上传照片
* @param id
* @return: imgUrl
*/
export function findImage(id) {
return request({
url: `/api/screenImg/findImage?id=${id}`,
method: 'get'
})
}

+ 34
- 0
src/api/closeStyle.js 查看文件

@@ -0,0 +1,34 @@
import { request } from "../utils/request"

// 获取风格列表
export function getListApi(pageNum, pageSize, sex, mouldType) {
return request({
url: `api/digitalAvatarMould/list?pageNum=${pageNum}&pageSize=${pageSize}&sex=${sex}&mouldType=${mouldType}`,
method: 'GET',
})
}

// 根据iD获取详情
export function findByIdApi(id) {
return request({
url: `api/digitalAvatarMould/findById?id=${id}`,
method: 'GET',
})
}

// 查询用户头像照片,生成写真时需要
export function findImageApi() {
return request({
url: `api/userDigital/findImage`,
method: 'GET',
})
}

// 生成写真
export function createPhotoApi(data) {
return request({
url: `api/digitalAvatarPhoto/createPhoto`,
method: 'POST',
data
})
}

+ 26
- 0
src/api/createing.js 查看文件

@@ -0,0 +1,26 @@
import { request } from "../utils/request"

/**
* @description:获取二维码
* @param {*} (appId, openId,phone,code)
* @return: list
*/
export function getQRCodeApi(data) {
return request({
url: `api/machineqrcode/getQRCode`,
method: 'POST',
data
})
}

/**
* @description:获取用户状态
* @param {*} (appId, openId,phone,code)
* @return: list
*/
export function getUserApi(UserId) {
return request({
url: `api/machineuser/getUser?tmpUserId=${UserId}`,
method: 'get',
})
}

+ 42
- 0
src/api/login.js 查看文件

@@ -0,0 +1,42 @@
import { request } from "../utils/request"


// 微信登录
export function loginApi(data) {
return request({
url: `api/miniApp/login`,
method: 'POST',
data
})
}

// 授权手机号登陆
export function loginPhoneApi(data) {
return request({
url: `api/miniApp/loginPhone`,
method: 'POST',
data
})
}

// 获取短信验证码
export function getCodeApi(phone) {
return request({
url: `api/user/sendLoginPhoneCode?phone=${phone}`,
method: 'get',
})
}


/**
* @description:短信登录
* @param {*} (appId, openId,phone,code)
* @return: list
*/
export function loginByCodeApi(data) {
return request({
url: `api/miniApp/loginPhoneCode`,
method: 'POST',
data
})
}

+ 66
- 0
src/api/lookPhoto.js 查看文件

@@ -0,0 +1,66 @@
import { request } from "../utils/request"


/**
* @description:得到写真信息
* @param id
* @return: data
*/
export function getPhotoListApi(id) {
return request({
url: `/api/digitalAvatarPhoto/findById?id=${id}`,
method: 'get',
})
}


/**
* @description:超分
* @param id
* @return: data
*/
export function photoSupperApi(data) {
return request({
url: `/api/digitalAvatarPhoto/photoSupper`,
method: 'post',
data
})
}

/**
* @description:超分 查询超分状态
* @param id
* @return: data
*/
export function getSupperPhotoStateApi(id) {
return request({
url: `/api/digitalAvatarPhoto/getSupperPhoto?id=${id}`,
method: 'get',
})
}

/**
* @description:生成画报
* @param {appId,img}
* @return: data
*/
export function getUserQrcodeApi(data) {
return request({
url: `/api/miniApp/getUserQrcode`,
method: 'POST',
responseType: "arraybuffer",
data
})
}

/**
* @description:获取订阅消息模版id
* @param
* @return: data
*/
export function getTemplateMsgApi() {
return request({
url: `api/templateMsg/list?projectType=5&plat=${uni.getStorageSync("plat")}&type=1`,
method: 'get',
})
}

二進制
src/assets/img/QRCode.jpg 查看文件

Before After
Width: 258  |  Height: 258  |  Size: 42 KiB

二進制
src/assets/img/c867236efb4fc5707257ef8daf26db4.png 查看文件

Before After
Width: 2400  |  Height: 2200  |  Size: 1.8 MiB

二進制
src/assets/img/homeImg.jpg 查看文件

Before After
Width: 1125  |  Height: 2145  |  Size: 2.5 MiB

二進制
src/assets/img/logo-4.png 查看文件

Before After
Width: 800  |  Height: 800  |  Size: 19 KiB

二進制
src/assets/img/people.png 查看文件

Before After
Width: 762  |  Height: 753  |  Size: 46 KiB

二進制
src/assets/img/photoBtn.png 查看文件

Before After
Width: 400  |  Height: 400  |  Size: 12 KiB

二進制
src/assets/img/reTry.png 查看文件

Before After
Width: 400  |  Height: 400  |  Size: 9.8 KiB

二進制
src/assets/img/selectImg.png 查看文件

Before After
Width: 400  |  Height: 400  |  Size: 14 KiB

二進制
src/assets/img/success.png 查看文件

Before After
Width: 400  |  Height: 400  |  Size: 14 KiB

+ 15
- 0
src/main.js 查看文件

@@ -0,0 +1,15 @@
import {
createSSRApp
} from "vue";
import uviewPlus from 'uview-plus'
import "./style/my.scss";
import App from "./App.vue";
import { store } from '../src/store/index'
export function createApp() {
const app = createSSRApp(App);
app.use(store)
app.use(uviewPlus)
return {
app,
};
}

+ 72
- 0
src/manifest.json 查看文件

@@ -0,0 +1,72 @@
{
"name" : "",
"appid" : "",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics": {
"enable": false
},
"vueVersion" : "3"
}

+ 57
- 0
src/pages.json 查看文件

@@ -0,0 +1,57 @@
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "智像相册"
}
},
{
"path": "pages/chooseStyle/index",
"style": {
"navigationBarTitleText": "智像相册"
}
},
{
"path": "pages/createing/index",
"style": {
"navigationBarTitleText": "智像相册"
}
},
{
"path": "pages/created/index",
"style": {
"navigationBarTitleText": "智像相册"
}
},
{
"path": "pages/camera/index",
"style": {
"navigationBarTitleText": "智像相册"
}
}
],
"easycom": {
// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
}
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "智像相册",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"navigationStyle": "custom",
"rpxCalcMaxDeviceWidth": 2160,
"rpxCalcBaseDeviceWidth": 2160,
"rpxCalcIncludeWidth": 2160
},
"app": {
"requiredBackgroundModes": [
"camera"
]
}
}

+ 947
- 0
src/pages/camera/index.vue 查看文件

@@ -0,0 +1,947 @@
<template>
<div class="page">
<div class="bottom">
<!-- 人物框 -->
<!-- <image
v-if="!isSuccess"
class="frameImg"
src="../../assets/img/people.png"
mode="scaleToFill"
/> -->
<video
v-if="!isSuccess"
id="video"
muted
autoplay="autoplay"
:controls="false"
:enable-progress-gesture="false"
></video>
<div v-if="!isSuccess">
<!-- -->
<div v-show="modelMouldType == 1" class="selectImg" @click="uploadImg">
<img src="../../assets/img/selectImg.png" />
<div class="uploadText">上传照片</div>
</div>
<div id="action" @click="takePicture">
<view v-show="showTakeTips" class="takeTips1"> 请正视摄像头</view>
<view v-show="showTakeTips" class="takeTips2"> 点击开始拍照 </view>
<div class="circleInside"></div>
</div>
</div>

<div v-if="isSuccess">
<div class="selectImg" @click="uploadImg">
<img src="../../assets/img/selectImg.png" />
<div class="uploadText">上传照片</div>
</div>

<div class="confirm" @click="confirmPhoto">
<!-- <img src="../../assets/img/success.png" /> -->
<!-- <div class="sure">确定</div>

<div class="uploadText">
就这张了 <img src="../../assets/img/success.png" />
</div> -->
<div class="sure">
<div class="uploadText">就这张了 ✔</div>
</div>
</div>

<div class="reTry" @click="reTry">
<img src="../../assets/img/reTry.png" />
<div class="uploadText">重新拍摄</div>
</div>
</div>

<canvas
v-if="isShowCanvas"
id="canvas"
style="width: 1530; height: 950"
></canvas>

<div v-if="isSuccess" class="preview">
<img v-if="!isUpload" class="fromCamera" :src="CimgSrc" />
<img v-if="isUpload" class="fromUpload" :src="UimgSrc" />
</div>
</div>

<div class="top">
<div class="example">
<img src="../../assets/img/c867236efb4fc5707257ef8daf26db4.png" />
</div>
<div class="model" @click="goSelectModel">
<img :src="modelUrl" alt="" />
<div class="reSelect">点击重新选择模板</div>
</div>
</div>
<!-- Top section -->
<u-overlay class="overlay" :show="showQrCode" opacity="0.9">
<view class="content">
<view class="imageBox">
<image :src="QRCodeUrl" mode="scaleToFill" />
</view>
<text>打开微信扫码上传照片</text>
<view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
>取&nbsp;消</view
>
</view>
</u-overlay>
</div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { BASE_URL } from "../../utils/request";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";

import { getImageQrcode, findImage } from "../../api/camera.js";

let CimgSrc = ref(""); // 相机拍照的图片路径,上传前需校验
let CimgSrcYASUO = ref(""); // 压缩后的图片
let UimgSrc = ref(""); // 用户上传的图片路径,上传无需校验
let isSuccess = ref(false);
let isShowCanvas = ref(true);
let isUpload = ref(false);

let modelUrl = ref("");
let modelId = ref("");
let modelMouldType = ref("");

let QRCodeUrl = ref("");
let showQrCode = ref(false);

let timer = ref(null);
const getView = () => {
uni.getSystemInfo({
success: (res) => {
const viewportWidth = res.windowWidth; // 视口宽度
const viewportHeight = res.windowHeight; // 视口高度
alert(viewportWidth);
alert(viewportHeight);
},
});
};

const showTakeTips = ref(true);

const startCamera = () => {
function getUserMedia(constraints, success, error) {
if (navigator.mediaDevices.getUserMedia) {
//最新的标准API
navigator.mediaDevices
.getUserMedia({
audio: false,
video: {
facingMode: "user",
// width: 1000,
// height: 1000,
width: 1080,
height: 1305,
// width: 2100,
// height: 2100,
},
})
.then(success)
.catch(error);
} else if (navigator.webkitGetUserMedia) {
//webkit核心浏览器
navigator.webkitGetUserMedia(constraints, success, error);
} else if (navigator.mozGetUserMedia) {
//firfox浏览器
navigator.mozGetUserMedia(constraints, success, error);
} else if (navigator.getUserMedia) {
//旧版API
navigator.getUserMedia(constraints, success, error);
}
}

const video = document.querySelector("video.uni-video-video");
// video.style.transform = "scaleX(-1)";
// video.style.transform = "rotateY(180deg)"; //镜像
let canvas = document.querySelector("canvas.uni-canvas-canvas");
const action = document.querySelector("#action");
let context = canvas.getContext("2d");

function success(stream) {
//兼容webkit核心浏览器
let CompatibleURL = window.URL || window.webkitURL;
//将视频流设置为video元素的源
console.log(stream);

//video.src = CompatibleURL.createObjectURL(stream);
video.srcObject = stream;
video.play();
}

function error(error) {
console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
}

if (
navigator.mediaDevices.getUserMedia ||
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia
) {
//调用用户媒体设备, 访问摄像头
getUserMedia(
{
audio: false,
video: {
facingMode: "user",
// width: 240,
// height: 450,
width: 1080,
height: 1305,
// width: 2100,
// height: 2100,
},
},
success,
error
);
} else {
alert("不支持访问用户媒体");
}

action.addEventListener("click", function () {
showTakeTips.value = false;
uni.showToast({
title: "准备开始拍照",
icon: "success",
});
setTimeout(() => {
let i = 3;
const timer = setInterval(() => {
uni.showLoading({
title: i,
});
i--;
console.log(i);
if (i == 0) {
clearInterval(timer);

setTimeout(async () => {
uni.hideLoading();
// canvas.width = 1530;
// canvas.height = 950;
canvas.width = 1500;
canvas.height = 1500;
context.drawImage(video, 0, 0);
let dataURL = canvas.toDataURL("image/png");
// console.log(dataURL);
CimgSrc.value = dataURL;
UimgSrc.value = "";

setTimeout(() => {
isShowCanvas.value = false;
isSuccess.value = true;
showTakeTips.value = true;
}, 10);
}, 1000);
}
}, 1100);
}, 1000);
});

// 备用方案
// action.addEventListener("click", function () {
// context.drawImage(video, -50, -50, 310, 220);
// const dataURL = canvas.toDataURL("image/png");
// imgSrc.value = dataURL;

// setTimeout(() => {
// isShowCanvas.value = false;
// isSuccess.value = true;
// }, 10);
// console.log(dataURL);
// });
};
//压缩图片
function compressBase64Image(base64String, maxWidth, maxHeight) {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = base64String;

img.onload = function () {
const canvas = document.createElement("canvas");
let width = img.width;
let height = img.height;

if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}

if (height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}

const ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);

const compressedBase64 = canvas.toDataURL("image/jpeg");
resolve(compressedBase64);
};

img.onerror = function (error) {
reject(error);
};
});
}

const takePicture = () => {
console.log("Take Picture !");
};

const goSelectModel = () => {
uni.navigateTo({
url: `/pages/chooseStyle/index`,
});
};

// 确认照片
const confirmPhoto = () => {
// alert("点击确定");
// alert(UimgSrc.value, "UimgSrc.value");
// alert(CimgSrc.value, "CimgSrc.value");
try {
if (UimgSrc.value) {
uni.navigateTo({
url: `/pages/createing/index?imageUrl=${UimgSrc.value}&id=${modelId.value}`,
});
} else if (CimgSrc.value) {
// 本地存储中的拍照照片
// alert(uni.getStorageSync("CcurrentUrl"), "CcurrentUrl");
// // let CimageUrl = uni.getStorageSync("CcurrentUrl");
// // 用户上一次使用相机拍照的照片,从本地回显,已通过校验,直接放行
if (uni.getStorageSync("CcurrentUrl")) {
uni.navigateTo({
url: `/pages/createing/index?imageUrl=${CimgSrc.value}&id=${modelId.value}`,
});
// // 用户使用相机拍照的照片,未校验,走完校验流程放行
} else {
dealImage(CimgSrc.value);
}
// dealImage(CimgSrcYASUO.value);
}
} catch (e) {
uni.showToast({
title: e,
icon: "success",
mask: true,
});
}
// 用户上传的照片,已通过校验,直接放行
};

const dealImage = async (imageUrl) => {
try {
uni.showLoading({
title: "上传中,马上就好",
});
await compressBase64Image(imageUrl, 1200, 1200)
.then((compressedBase64) => {
CimgSrcYASUO.value = compressedBase64;
})
.catch((error) => {
console.error("压缩失败", error);
});
// 将二进制数据转换为 Blob 对象
// let blob = await dataURLtoBlob(imageUrl);
// checkImageByBaidu(blob);
// let blob = await dataURLtoBlob(imageUrl);
// console.log(dataURLtoBlob(imageUrl));
checkImageByBaidu(dataURLtoBlob(CimgSrcYASUO.value));
} catch (error) {
console.error("压缩失败", error);
}
};

/**
* Base64字符串转二进制流
* @param {String} dataurl Base64字符串(字符串包含Data URI scheme,例如:data:image/png;base64, )
*/
const dataURLtoBlob = (dataurl) => {
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime,
});
};

// 百度图片校验
const checkImageByBaidu = async (file) => {
try {
uni.showLoading({
title: "正在检测图片合法性 1/3",
});
uni.uploadFile({
url: BASE_URL + "api/baidu/checkPhoto",
file,
header: {
authorization: uni.getStorageSync("token"),
},
timeout: 30000,
// formData: data,
success: (res) => {
console.log(res, "上传成功");
const data = JSON.parse(res.data);
if (data.code == 200) {
uni.hideLoading();
checkImageByMetavatar(file);
} else {
uni.hideLoading();
uni.showToast({
title: "图片不合规哦,请更换一张",
icon: "error",
});
}
},
fail: (res) => {
uni.hideLoading();
uni.showToast({
title: "上传失败,请稍后再试",
icon: "none",
});
console.log(res, "上传失败");
},
});
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "请求失败,请稍后再试",
icon: "none",
});
}
};

// 邃芒人脸校验
const checkImageByMetavatar = async (file) => {
uni.showLoading({
title: "正在检测人脸位置 2/3",
});
uni.uploadFile({
url: BASE_URL + "api/userDigital/checkPhoto",
file,
header: {
authorization: uni.getStorageSync("token"),
},
timeout: 30000,
// formData: data,
success: (res) => {
console.log(res, "上传成功");
const data = JSON.parse(res.data);
if (data.code == 200) {
uni.hideLoading();
uoloadImageAws(file);
} else {
uni.hideLoading();
uni.showToast({
title: "请参考提示区域调整站位哦",
icon: "error",
});
}
},
fail: (res) => {
uni.hideLoading();
uni.showToast({
title: "上传失败,请稍后再试",
icon: "none",
});
console.log(res, "上传失败");
},
});
};

// 上传图片到服务器(两步校验通过后)
const uoloadImageAws = async (file) => {
uni.showLoading({
title: "检测完成,上传中 3/3",
});
uni.uploadFile({
url: BASE_URL + "api/upload/awsImgUpload",
file,
header: {
authorization: uni.getStorageSync("token"),
},
timeout: 30000,
// formData: data,
success: (res) => {
console.log(res, "上传成功");
uni.hideLoading();
const data = JSON.parse(res.data);
if (data.code == 200) {
uni.showToast({
title: "上传成功!",
icon: "success",
duration: 1500,
});
setTimeout(() => {
// 将拍照照片地址存储到本地并清空上传照片地址
// uni.setStorageSync("CcurrentUrl", data.data.url);
uni.setStorageSync("CcurrentUrl", data.data.url);
uni.setStorageSync("UcurrentUrl", null);
uni.navigateTo({
url: `/pages/createing/index?imageUrl=${data.data.url}&id=${modelId.value}`,
});
}, 1000);
} else {
uni.hideLoading();
uni.showToast({
title: "网络波动,请稍后再试",
icon: "error",
});
}
},
fail: (res) => {
uni.hideLoading();
uni.showToast({
title: "上传失败,请稍后再试",
icon: "none",
});
console.log(res, "上传失败");
},
});
};

// 不满意,重新拍一张
const reTry = () => {
isSuccess.value = false;
isUpload.value = false;
isShowCanvas.value = true;
CimgSrc.value = "";
UimgSrc.value = "";
CimgSrcYASUO.value = "";
uni.setStorageSync("CcurrentUrl", null);
setTimeout(() => {
startCamera();
}, 10);
};

// 点击上传照片按钮
const uploadImg = async () => {
const data = {
machineQrcodeId: localStorage.getItem("UserId"),
mouldType: modelMouldType.value,
};
// const UserId = localStorage.getItem("UserId");
// const mouldType = modelMouldType.value;
try {
const res = await getImageQrcode(data);
QRCodeUrl.value = res.data.wxQrcode;
showQrCode.value = true;

// 成功展示二维码之后,轮询获取上传照片状态
timer.value = setInterval(() => {
refreshUploadStatus(res.data.id);
}, 1000);
console.log(res, "res");
} catch (error) {
console.log(error, "error");
}
};

// 刷新状态,直到返回用户上传的图片url
const refreshUploadStatus = async (id) => {
try {
const res = await findImage(id);
console.log(res, "res");
if (res.data.imageList && res.data.imageList.length) {
const imageUrl = res.data.imageList[0];
clearInterval(timer.value);
uni.showToast({
title: "上传成功!",
icon: "success",
});
showQrCode.value = false;
UimgSrc.value = imageUrl;
CimgSrc.value = "";
CimgSrcYASUO.value = "";
isShowCanvas.value = false;
isSuccess.value = true;
isUpload.value = true;

// 将上传照片地址存储到本地并清空拍照照片地址
uni.setStorageSync("CcurrentUrl", null);
uni.setStorageSync("UcurrentUrl", UimgSrc.value);
}
} catch (error) {
console.log(error, "error");
}
};

// 点击取消,关闭二维码弹窗并取消轮询
const cancelUplaod = () => {
showQrCode.value = false;
clearInterval(timer.value);
};

onLoad((options) => {
console.log(options, "options");
modelUrl.value = options.modelUrl;
modelId.value = options.id;
modelMouldType.value = options.mouldType;
});

onMounted(() => {
clearInterval(timer.value);

const CimageUrl = uni.getStorageSync("CcurrentUrl");
const UimageUrl = uni.getStorageSync("UcurrentUrl");
if (!CimageUrl) {
startCamera();
}
if (CimageUrl || UimageUrl) {
setTimeout(async () => {
showQrCode.value = false;
if (CimageUrl) {
UimgSrc.value = "";
CimgSrc.value = CimageUrl;
isUpload.value = false;
} else if (UimageUrl) {
UimgSrc.value = UimageUrl;
CimgSrc.value = "";
CimgSrcYASUO.value = "";
isUpload.value = true;
}

isShowCanvas.value = false;
isSuccess.value = true;
}, 1000);
}
});

//#region 页面初始化和卸载
const resetTimer = ref(null);
onMounted(() => {
window.document.addEventListener("touchstart", () => {
// 用户点击时,清除之前的定时器
clearTimeout(resetTimer.value);
// 重新设定120秒后触发的定时器
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
onUnload(() => {
uni.hideLoading();
clearTimeout(resetTimer.value);
});
//#endregion -----------------------
</script>

<style lang="scss" scoped>
:deep(.uni-toast) {
width: 500rpx;
font-size: 70rpx;
font-weight: 900;
padding: 20rpx 30rpx;
color: #ff4f00;

.uni-toast__icon {
width: 70rpx !important;
height: 70rpx !important;
}
}
.page {
width: 100vw;
height: 100vh;
padding: 0;

.top {
display: flex;
width: 100%;
height: 32%;
.example {
width: 60%;
height: 100%;
color: #000;
background-color: #fff;
img {
width: 100%;
height: 100%;
}
}
.model {
position: relative;
width: 40%;
height: 100%;
background-color: #000000;
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
}
.reSelect {
position: absolute;
width: 250rpx;
left: 50%;
bottom: 10rpx;
text-align: center;
transform: translateX(-50%);
}
}
}
.bottom {
position: relative;
width: 100%;
height: 68%;
overflow: hidden;
.frameImg {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
width: 60%;
height: 40%;
z-index: 3;
}
video {
width: 100%;
height: 100%;
// width: 1080px;
// height: 1305px;
:deep(.uni-video-video) {
position: absolute;
left: 0;
top: -50px;
width: 100% !important;
height: 720px !important;
}
}
.selectImg {
position: absolute;
left: 65rpx;
bottom: 75rpx;
width: 68rpx;
height: 68rpx;
border: 5rpx solid #ffffff;
border-radius: 5rpx;
z-index: 99;
img {
position: absolute;
left: 50%;
bottom: 50%;
transform: translate(-50%, 50%);
width: 70%;
height: 70%;
}
.uploadText {
position: absolute;
left: 50%;
bottom: -40rpx;
width: 150%;
font-size: 20rpx;
transform: translateX(-40%);
}
}

#action {
position: absolute;
left: 50%;
bottom: 45rpx;
width: 120rpx;
height: 120rpx;
transform: translateX(-50%);
background-color: #ffffff;
border-radius: 60rpx;
z-index: 99;
.takeTips1 {
position: absolute;
width: 300rpx;
top: -70rpx;
left: 50%;
transform: translateX(-50%);
text-align: center;
color: #ff4f00;
}
.takeTips2 {
position: absolute;
width: 300rpx;
top: -40rpx;
left: 50%;
transform: translateX(-50%);
text-align: center;
color: #ff4f00;
}
.circleInside {
position: absolute;
left: 50%;
bottom: 50%;
transform: translate(-50%, 50%);
width: 100rpx;
height: 100rpx;
background-color: #ffffff;
border-radius: 50%;
border: 6rpx solid #000;
}
}

.confirm {
position: absolute;
left: 50%;
bottom: 75rpx;
width: 180rpx;
height: 80rpx;
// border: 5rpx solid #ffffff;
transform: translateX(-50%);
border-radius: 60rpx;
z-index: 9999999;
img {
// position: absolute;
// left: 50%;
// bottom: 50%;
// transform: translate(-50%, 50%);
width: 100%;
height: 100%;
width: 30rpx;
height: 30rpx;
vertical-align: text-top;
}
.sure {
margin-top: 30rpx;
text-align: center;
width: 100%;
height: 50rpx;
line-height: 50rpx;
line-height: 50rpx;
background-color: #ff4f00;
border-radius: 15rpx;
.uploadText {
// position: absolute;
// left: 50%;
// bottom: -40rpx;
// width: 150%;

width: 100%;
height: 30rpx;
line-height: 50rpx;
font-size: 20rpx;
// transform: translateX(-32%);
text-align: center;
}
}
.uploadText {
// position: absolute;
// left: 50%;
// bottom: -40rpx;
// width: 150%;

width: 100%;
height: 30rpx;
line-height: 30rpx;
font-size: 20rpx;
// transform: translateX(-32%);
text-align: center;
}
}

.reTry {
position: absolute;
right: 65rpx;
bottom: 75rpx;
width: 68rpx;
height: 68rpx;
border: 5rpx solid #ffffff;
border-radius: 5rpx;
z-index: 99;
img {
position: absolute;
left: 50%;
bottom: 50%;
transform: translate(-50%, 50%);
width: 70%;
height: 70%;
}
.uploadText {
position: absolute;
left: 50%;
bottom: -40rpx;
width: 150%;
font-size: 20rpx;
transform: translateX(-40%);
}
}

.preview {
position: relative;
width: 100%;
height: 100%;
z-index: 1;
.fromCamera {
// position: absolute;
// top: 110rpx;
// left: 130rpx;
width: 100%;
}
.fromUpload {
position: absolute;
top: 110rpx;
left: 50%;
transform: translateX(-50%);
width: 45%;
}
}
}
.overlay {
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.imageBox {
position: relative;
margin-top: 200rpx;
width: 300rpx;
height: 300rpx;
border-radius: 30rpx;
background-color: #fff;
.mask {
position: absolute;
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: rgba($color: #000000, $alpha: 0.7);
z-index: 2;
}
image {
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: #fff;
}
}
text {
margin-top: 20rpx;
font-weight: 900;
font-size: 32rpx;
}
// .orangeBtn {
// margin-top: 100rpx;
// }
}
}
}
</style>

+ 435
- 0
src/pages/chooseStyle/index.vue 查看文件

@@ -0,0 +1,435 @@
<template>
<view class="page" id="page">
<!-- tab栏 -->
<view class="tabBox">
<u-tabs
:list="sexList"
lineWidth="50"
lineColor="#ff4f00"
:itemStyle="{ width: '150rpx', height: '90rpx', padding: '0' }"
:activeStyle="{ color: '#ff4f00', fontsize: '30rpx' }"
:inactiveStyle="{ color: '#fff', fontsize: '30rpx' }"
@click="chooseTab"
></u-tabs>
<view class="moreTabs">
<!-- <view class="moreIcon" @click="showPopup = true"> 更多 </view> -->
<view class="moreIcon" @click="showPopup = true"> 更多 </view>
</view>
</view>
<!-- 更多tab弹出层 -->
<u-popup
closeable="true"
mode="top"
:round="20"
:show="showPopup"
@close="closePopup"
@open="openPopup"
>
<view class="popupBox">
<view class="type">性别</view>
<view class="typeBox">
<view
v-show="item.name"
class="typeBox-item"
:class="item.id == sex ? 'itemActive' : ''"
@click="chooseSex(item)"
v-for="item in sexList2"
:key="item.id"
>{{ item.name }}</view
>
</view>
<view class="type">类型</view>
<view class="typeBox">
<view
v-show="item.name"
class="typeBox-item"
:class="item.id == mouldType ? 'itemActive' : ''"
@click="chooseMouldType(item)"
v-for="item in mouldTypeList"
:key="item.id"
>{{ item.name }}</view
>
</view>
</view>
</u-popup>
<!-- 模版选择 -->
<u-list
class="styleListBox"
@scrolltolower="scrolltolower"
lowerThreshold="100"
>
<u-list-item class="glodYBox">
<u-list-item
v-for="item in styleList"
:key="item.id"
class="styleListBoxItme"
>
<view class="styleInfo" @click="createPhoto(item)">
<image :src="item.coverImg" mode="aspectFit" />
<text class="name">{{ item.title }}</text>
<text class="single">{{ peopleNum(item.mouldType) }}</text>
</view>
</u-list-item>
<view
v-if="styleList.length == 0"
style="width: 100%; text-align: center"
>暂无数据</view
>
</u-list-item>
</u-list>
</view>
</template>

<script setup>
//#region 导入
import { ref, watch, onMounted } from "vue";
import { getListApi } from "../../api/closeStyle";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import { userInfoModules } from "@/store/modules/userInfo";
const userInfoModulesPinia = userInfoModules();
//#endregion -----------------------

//#region tab栏
// 性别
const sex = ref(2);
const sexList = ref([
{ name: "女", id: 2 },
{ name: "男", id: 1 },
{ name: "单人", id: 3 },
{ name: "多人", id: 4 },
]);
const sexList2 = ref([
{ name: "女", id: 2 },
{ name: "男", id: 1 },
]);

// 类型
const mouldType = ref("");
const mouldTypeList = ref([
{ name: "单人", id: 1 },
{ name: "多人", id: 2 },
]);
// 点击tab
function chooseTab(item) {
if (item.id < 3) {
sex.value = item.id;
mouldType.value = "";
} else if (item.id == 3) {
mouldType.value = 1;
sex.value = "";
} else if (item.id == 4) {
mouldType.value = 2;
sex.value = "";
}
}
// 更多里的tab 性别
function chooseSex(item) {
if (sex.value == item.id) {
if (mouldType.value == "") {
return;
} else {
sex.value = "";
}
} else {
sex.value = item.id;
mouldType.value = "";
}
}
// 更多里的tab 类型
function chooseMouldType(item) {
if (mouldType.value == item.id) {
if (sex.value == "") {
return;
} else {
mouldType.value = "";
}
} else {
mouldType.value = item.id;
sex.value = "";
}
}
//#endregion

//#region 更多tab弹出层
const showPopup = ref(false);
function closePopup() {
showPopup.value = false;
}
function openPopup() {}
function toCreated() {
// uni.navigateTo({ url: "/pages/createing/index" });
}
//#endregion -----------------------

//#region 列表加载
const pageNum = ref(1);
const pageSize = ref(20);
// const sex = ref(2); //1男2女
const styleList = ref([]);
// 得到列表
async function getList() {
try {
uni.showLoading({
title: "加载中...",
mask: true,
});
const res = await getListApi(
pageNum.value,
pageSize.value,
sex.value,
mouldType.value
);
styleList.value = res.data.list;
uni.hideLoading();
} catch (error) {
uni.hideLoading();
uni.showToast({
title: "获取列表失败,请重试",
icon: "none",
});
}
}
// 监听性别tab变化
watch(
() => mouldType.value,
(old) => {
pageNum.value = 1;
pageSize.value = 20;
getList();
}
);
watch(
() => sex.value,
() => {
pageNum.value = 1;
pageSize.value = 20;
getList();
}
);
getList();
// 触底加载更多
const scrolltolower = async () => {
try {
uni.showLoading({
title: "加载中...",
mask: true,
});
pageNum.value += 1;
const res = await getListApi(
pageNum.value,
pageSize.value,
sex.value,
mouldType.value
);
styleList.value.push(...res.data.list);
setTimeout(function () {
uni.hideLoading();
}, 500);

if (res.data.list.length == 0) {
pageNum.value -= 1;
uni.showToast({
title: "已加载全部内容",
icon: "none",
mask: false,
});
}
} catch (error) {
setTimeout(function () {
uni.hideLoading();
}, 500);
uni.showToast({
title: "获取数据失败,请重试",
icon: "none",
});
}
};

// 处理单人双人多人
function peopleNum(num) {
if (num == 1) {
return "单人";
} else if (num == 2) {
return "双人";
} else if (num == 3) {
return "三人";
}
}
//#endregion ---------------------

//#region 点击图片
function createPhoto(item) {
uni.navigateTo({
url: `/pages/createing/index?id=${item.id}`,
});
// if (item.mouldType == 1) {
// } else {
// uni.navigateTo({
// url: `/pages/closeStyle/multiplayer?id=${item.id}`,
// });
// }
}
//#endregion ---------------------

//#region 页面初始化和卸载
const resetTimer = ref(null);
onMounted(() => {
window.document.addEventListener("touchstart", () => {
// 用户点击时,清除之前的定时器
clearTimeout(resetTimer.value);
// 重新设定120秒后触发的定时器
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
onUnload(() => {
uni.hideLoading();
clearTimeout(resetTimer.value);
});
//#endregion -----------------------
</script>

<style lang="scss" scoped>
// <!-- tab栏 -->
.tabBox {
position: relative;
width: 100vw;

.u-tabs {
:deep(.u-tabs__wrapper__nav__item__text) {
font-size: 30rpx;
}
// width: calc(100% - 100rpx);
width: 100%;
color: #fff !important;
margin-bottom: 30rpx;
// :deep(.u-tabs__wrapper__nav__item-7) {
// color: #00ff33 !important;
// margin-right: 90rpx !important;
// }
}
.moreTabs {
position: absolute;
top: 0;
right: 0;
width: 200rpx;
height: 90rpx;
background: linear-gradient(90deg, transparent 20%, #333 100%);
// background-color: red;
.moreIcon {
margin-left: 50rpx;
margin-top: 15rpx;
width: 130rpx;
height: 60rpx;
border-radius: 40rpx;
background-color: #ff4f00;
text-align: center;
line-height: 60rpx;
}
}
}
// <!-- 更多tab弹出层 -->
.u-popup {
:deep(.u-popup__content__close--top-right) {
top: 35rpx;
right: 35rpx;
}
:deep(.uicon-close) {
font-size: 30rpx !important;
}
}
.popupBox {
padding-bottom: 30rpx;
.type {
padding: 30rpx 30rpx 0 30rpx;
color: #000;
font-weight: 900;
font-size: 32rpx;
}
.typeBox {
padding: 0 0 0 30rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
color: #1f1212;
font-size: 26rpx;
&-item {
margin-top: 20rpx;
margin-right: 30rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
// margin: 0 30rpx;
width: 200rpx;
border: 2rpx solid #ccc;
border-radius: 30rpx;
}
.itemActive {
color: #ff4f00;
border: 2rpx solid #ff4f00;
}
}
}
// <!-- 模版选择 -->
.u-list {
overflow: hidden;
height: calc(100vh - 200rpx) !important;
width: 650rpx;
.glodYBox {
display: flex !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: space-between !important;
}
.u-list-item {
display: flex !important;
flex-direction: row !important;
flex-wrap: wrap !important;
justify-content: space-between !important;
}
.styleInfo {
position: relative;
display: flex !important;
flex-wrap: wrap !important;
width: 300rpx;
height: 480rpx;
margin-bottom: 50rpx;
border-radius: 24rpx;
overflow: hidden;
image {
width: 300rpx;
height: 400rpx;
}
.name {
background-color: #393b3d;
width: 100%;
height: 80rpx;
text-align: center;
line-height: 80rpx;
font-size: 30rpx;
font-weight: bold;
}
.single {
position: absolute;
top: 11rpx;
right: 13rpx;
width: 72rpx;
height: 41rpx;
text-align: center;
line-height: 41rpx;
background: rgba(0, 0, 0, 0.4);
font-size: 22rpx;
// opacity: 0.4;
border-radius: 12rpx;
}
}
}
</style>

+ 547
- 0
src/pages/created/index.vue 查看文件

@@ -0,0 +1,547 @@
<template>
<view class="page">
<!-- 用户信息 -->
<view class="userInfoBox" v-show="userInfoModulesPinia.token">
<!-- <view class="phone">用户:{{ userInfoModulesPinia.phone }}</view> -->
<view class="createTimes"
>剩余写真次数:{{ userInfoModulesPinia.createTimes }}</view
>
<view class="loginOut" @click="loginOut">{{
userInfoModulesPinia.createTimes == 0 ? "查看相册" : "结束拍摄"
}}</view>
</view>
<!-- 轮播图 -->
<u-swiper
v-if="createState == 2"
indicator
indicatorMode="dot"
circular
:radius="30"
:autoplay="false"
:list="swiperList"
keyName="image"
@change="getSwiperIndex"
@click="previewImage"
></u-swiper>
<image
class="logo"
v-if="createState != 2"
:src="modelImgUrl"
mode="aspectFit"
/>

<view v-if="createState == 2" class="checkMore">左右滑动查看更多</view>

<view class="orangeBtn" @click="goChooseStyle"
>{{ userInfoModulesPinia.createTimes == 0 ? "再玩一次" : "再来一套" }}
</view>
<view class="grayBtn" @click="loginOut">
{{
userInfoModulesPinia.createTimes == 0 ? "查看相册" : "结束拍摄"
}}</view
>

<u-overlay class="overlay" :show="showQrCode" opacity="0.9">
<view class="content">
<view class="imageBox">
<image src="../../assets/img/QRCode.jpg" mode="scaleToFill" />
</view>
<text>微信扫码查看我的写真相册</text>
<view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
>我知道了</view
>
</view>
</u-overlay>
</view>
</template>

<script setup>
//#region 导入
import { onLoad, onUnload } from "@dcloudio/uni-app";
import { ref, watch, onMounted } from "vue";
import {
getPhotoListApi,
photoSupperApi,
getSupperPhotoStateApi,
} from "../../api/lookPhoto.js";
import { getUserApi } from "../../api/createing";
import { userInfoModules } from "@/store/modules/userInfo";
const userInfoModulesPinia = userInfoModules();
//#endregion

//#region 轮播图
const createState = ref(1); //制作状态:1生成中,2完成,3失败
const workId = ref(null); //作品id
const showQrCode = ref(false);
const QRCodeUrl = ref("");

const modelImgUrl = ref("");
onLoad(async (options) => {
workId.value = options.id;
modelImgUrl.value = options.imgUrl;
// await getTemplateMsg();
getUser();
await getSwiperList();
await getSupperPhotoState(swiperList.value[0].id);
// uni.setStorageSync("createTimes", userInfoModulesPinia.createTimes);
});
onUnload(() => {
clearTimeout(timer.value);
timer.value = null;
});
const swiperList = ref([]); //轮播图
const previewImageList = ref([]); //预览图片列表

const timer = ref(null);
async function getSwiperList() {
uni.showLoading({
title: "生成中,请稍后",
});
const res = await getPhotoListApi(workId.value);
createState.value = res.data.status;

if (res.data.photoList) {
uni.hideLoading();
uni.showToast({
title: "生成成功!",
icon: "success",
});
swiperList.value = res.data.photoList;
swiperList.value.forEach((item) => {
if (item.imageSuper) {
previewImageList.value.push(item.imageSuper);
} else {
previewImageList.value.push(item.image);
}
});
}

if (res.data.status != 2) {
timer.value = setTimeout(() => {
getSwiperList();
}, 3000);
} else {
clearTimeout(timer.value);
timer.value = null;
}
}
//#endregion ---------------------

//#region 预览
const swiperIndex = ref(0);
function getSwiperIndex(index) {
swiperIndex.value = index.current;
}
function previewImage(index) {
uni.previewImage({
current: index, //预览图片的下标
urls: previewImageList.value, //预览图片的地址,必须要数组形式,如果不是数组形式就转换成数组形式就可以
loop: true,
});
}
//#endregion ---------------------

//#region 获取次数
async function getUser() {
try {
const res = await getUserApi(uni.getStorageSync("UserId"));
// 如果接口200就说明已登录
if (res.code == 200 && res.data) {
// 查询支付状态 0:待支付,2:支付中,3:已支付
if (res.data.payStatus == 3) {
uni.setStorageSync("createTimes", res.data.createTimes);
userInfoModulesPinia.createTimes = res.data.createTimes;
console.log();
}
}
} catch (err) {
console.log(err);
}
}
//#endregion ---------------------

//#region 页面跳转
function goChooseStyle() {
uni.navigateTo({
url: "/pages/chooseStyle/index",
});
}

const cancelUplaod = () => {
showQrCode.value = false;
userInfoModulesPinia.clearStorage();
uni.navigateTo({ url: "/pages/login/index" });
};

//#endregion ---------------------

//#region 超分相关
const supperPhotoState = ref(false);
async function photoSupper() {
if (supperPhotoState.value == 1 || supperPhotoState.value == 2) {
return;
}
// uni.showModal({
// title: "提示",
// content: "确定高清处理?",
// success: function (res) {
// if (res.confirm) {
// checkboxValue.value = ["同意智像相机用户使用协议"];
// // handleLogin();
// getphonenumber(e);
// } else if (res.cancel) {
// }
// },
// fail: (err) => {},
// });
try {
uni.showLoading({
title: "高清处理中...",
mask: true,
});
const res = await photoSupperApi({
id: swiperList.value[swiperIndex.value].id,
});
console.log(res);
uni.hideLoading();
uni.showToast({
title: "高清处理请求成功,请稍后",
title: "高清处理请求成功,请稍等",
icon: "none",
});

getSupperPhotoState(swiperList.value[swiperIndex.value].id);
} catch (error) {
console.log(error, "超分失败");
uni.hideLoading();
uni.showToast({
title: "高清处理失败,请重试",
icon: "none",
});
}
}

async function getSupperPhotoState(id) {
try {
const res = await getSupperPhotoStateApi(id);
supperPhotoState.value = res.data.status;
console.log(supperPhotoState.value, "状态");
} catch (error) {
console.log(error, "超分失败");
}
}

function supperTips(params) {
if (supperPhotoState.value == 0 || supperPhotoState.value == 3) {
return "一键高清";
} else if (supperPhotoState.value == 1) {
return "高清处理中,请稍后";
} else if (supperPhotoState.value == 2) {
return "已高清处理";
}
}

watch(
() => swiperIndex.value,
(index) => {
getSupperPhotoState(swiperList.value[index].id);
}
);
//#endregion ---------------------

//#region 退出登录
function loginOut() {
if (userInfoModulesPinia.createTimes) {
uni.showModal({
title: "是否结束拍摄?",
content: `您还有${userInfoModulesPinia.createTimes}次拍摄机会`,
confirmColor: "#ff4f00",
confirmText: "再来一套",
cancelText: "结束拍摄",
success: function (res) {
if (res.confirm) {
console.log("用户点击确定");
uni.navigateTo({ url: "/pages/chooseStyle/index" });
} else if (res.cancel) {
console.log("用户点击取消");
showQrCode.value = true;
}
},
});
} else {
showQrCode.value = true;
}
}
//#endregion ---------------------

//#region 页面初始化和卸载
const resetTimer = ref(null);
onMounted(() => {
window.document.addEventListener("touchstart", () => {
// 用户点击时,清除之前的定时器
clearTimeout(resetTimer.value);
// 重新设定120秒后触发的定时器
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
onUnload(() => {
uni.hideLoading();
clearTimeout(resetTimer.value);
clearTimeout(timer.value);
});
//#endregion -----------------------
</script>

<style lang="scss">
.page {
padding: 30rpx 30rpx;
background-color: rgba(24, 25, 26, 1);
}
.userInfoBox {
position: relative;
padding: 0 50rpx;
width: 100%;
display: flex;
height: 50rpx;
line-height: 50rpx;
align-items: center;
border-radius: 20rpx;
background-color: rgba($color: #ccc, $alpha: 0.4);
.createTimes {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.loginOut {
position: absolute;
right: 20rpx;
height: 40rpx;
line-height: 40rpx;
background-color: #ff4f00;
color: #ffffff;
padding: 0 15rpx;
border-radius: 20rpx;
}
}
// 轮播图
.u-swiper {
margin-top: 70rpx;
width: 540rpx;
height: 720rpx !important;
border-radius: 50rpx;
swiper {
width: 100%;
height: 720rpx !important;
image {
width: 100%;
height: 720rpx !important;
}
}

// h5
:deep(.u-swiper__wrapper) {
width: 100%;
height: 720rpx !important;
image {
width: 100%;
height: 720rpx !important;
}
}
}
.logo {
margin-top: 70rpx;
border-radius: 30rpx;
width: 540rpx;
height: 720rpx !important;
}
.logoBox {
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
// margin-top: 70rpx;
width: 540rpx;
height: 720rpx !important;
.logo {
border-radius: 30rpx;
width: 100%;
// margin: 90rpx;
// animation: rotateAnimation 3s 0s infinite;
// opacity: 0.7;
}
}
@keyframes rotateAnimation {
0% {
transform: rotate(0deg);
}
66.66% {
transform: rotate(360deg);
}
100% {
transform: rotate(360deg);
}
}
.checkMore,
.wait {
text-align: center;
color: #ffffff;
margin-top: 30rpx;
.creating {
font-size: 40rpx;
margin-bottom: 10rpx;
}
}

// 俩按钮
.uploadBtn {
position: relative;
margin-top: 100rpx;
width: 520rpx;
height: 100rpx;
line-height: 100rpx;
text-align: center;
background: #ff4f00;
border-radius: 50rpx;
font-size: 30rpx;
color: #fff;
font-weight: 900;
.free {
position: absolute;
top: -18rpx;
right: -70rpx;
width: 142rpx;
height: 50rpx;
background-color: #000;
border-radius: 25rpx 25rpx 25rpx 0;
font-size: 22rpx;
font-weight: 900;
line-height: 50rpx;
text-align: center;
}
}
.orangeBtn {
margin-top: 60rpx;
}
.grayBtn {
margin-bottom: 220rpx;
.free {
position: absolute;
color: #fff;
top: -18rpx;
right: -70rpx;
width: 142rpx;
height: 50rpx;
background-color: #ff4f00;
border-radius: 25rpx 25rpx 25rpx 0;
font-size: 22rpx;
font-weight: 900;
line-height: 50rpx;
text-align: center;
}
}

.bottomBox {
// flex: 1;
position: absolute;
bottom: 60rpx;
width: 100%;
display: flex;
justify-content: space-evenly;
padding: 65rpx 40rpx 0;
.tips {
position: absolute;
top: 0rpx;
right: 60rpx;
width: 313rpx;
height: 50rpx;
background-color: #000;
border-radius: 25rpx 25rpx 25rpx 0;
font-size: 22rpx;
font-weight: 900;
line-height: 50rpx;
text-align: center;
}
.shareBtn {
margin: 0;
color: #fff;
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
border-radius: 70rpx;
font-size: 26rpx;
background-color: rgba(255, 255, 255, 0.1);
}
}

.pictorialBox {
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background-color: rgba($color: #000000, $alpha: 0.9);
image {
margin-top: 80rpx;
width: 630rpx;
height: 940rpx;
border-radius: 24rpx;
margin-bottom: 50rpx;
}
text {
margin-bottom: 30rpx;
}
z-index: 9;
}

.overlay {
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.imageBox {
position: relative;
margin-top: 200rpx;
width: 300rpx;
height: 300rpx;
border-radius: 30rpx;
background-color: #fff;
.mask {
position: absolute;
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: rgba($color: #000000, $alpha: 0.7);
z-index: 2;
}
image {
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: #fff;
}
}
text {
margin-top: 20rpx;
font-weight: 900;
font-size: 32rpx;
}
// .orangeBtn {
// margin-top: 100rpx;
// }
}
}
</style>

+ 521
- 0
src/pages/createing/index.vue 查看文件

@@ -0,0 +1,521 @@
<template>
<view class="page">
<!-- 毛玻璃 -->
<view class="glass">
<image src="../../assets/img/homeImg.jpg" mode="scaleToFill" />
</view>
<!-- 用户信息 -->
<view class="userInfoBox" v-show="userInfoModulesPinia.token">
<!-- <view class="phone">用户:{{ userInfoModulesPinia.phone }}</view> -->
<view class="createTimes"
>剩余写真次数:{{ userInfoModulesPinia.createTimes }}</view
>
<view class="loginOut" @click="loginOut">{{
userInfoModulesPinia.createTimes == 0 ? "查看相册" : "结束拍摄"
}}</view>
</view>
<text class="name">{{ styleData.title }}</text>
<!-- 展示图 -->
<view class="showImgBox imgContenBox"
><image :src="styleData.coverImg"
/></view>
<view class="orangeBtn" @click="createing1" style="margin-top: 50rpx"
>开始制作
</view>
<view class="grayBtn" @click="toChooseModel" style="margin-top: 30rpx"
>重新选择模版
</view>
<!-- 登录二维码弹出层 -->
<u-overlay class="overlay" :show="showQrCode" opacity="0.9">
<view class="content">
<view class="imageBox" :class="payMask ? 'glass' : ''">
<view class="mask" v-show="payMask"></view>
<image :src="qrCode" mode="scaleToFill" />
</view>
<!-- <text v-show="!userInfoModulesPinia.token">打开微信扫码登录小程序</text> -->
<text v-show="!userInfoModulesPinia.token" style="color: #ff4f00"
>19.9元可玩三次</text
>
<text v-show="!userInfoModulesPinia.token">打开微信扫码支付</text>
<!-- <text
v-show="
userInfoModulesPinia.token && userInfoModulesPinia.createTimes == 0
"
>剩余生成次数不足,请扫码充值!</text
> -->
<text style="margin-top: 30rpx" v-show="payCount != 300"
>{{ payCount }}秒后过期</text
>
<view
class="orangeBtn"
style="margin-top: 60rpx"
@click="showQrCode = false"
>取&nbsp;消</view
>
</view>
</u-overlay>

<u-overlay class="overlay" :show="showQrCodeII" opacity="0.9">
<view class="content">
<view class="imageBox">
<image src="../../assets/img/QRCode.jpg" mode="scaleToFill" />
</view>
<text>微信扫码查看我的写真相册</text>
<view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
>我知道了</view
>
</view>
</u-overlay>
</view>
</template>

<script setup>
//#region 导入
import { ref, watch, onMounted } from "vue";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import {
findByIdApi,
findImageApi,
createPhotoApi,
} from "../../api/closeStyle";
import { getQRCodeApi, getUserApi } from "../../api/createing";
import { userInfoModules } from "@/store/modules/userInfo";
const userInfoModulesPinia = userInfoModules();
//#endregion

//#region 初始化
const styleId = ref(null);
const styleData = ref({});
const cameraImg = ref(null);
onLoad(async (options) => {
styleId.value = options.id;
// getInfo();
cameraImg.value = options.imageUrl;
if (options.imageUrl) {
await getInfo();
createing2();
}
if (uni.getStorageSync("UserId")) {
getUser2();
}
});
onShow(() => {
getInfo();
});

async function getInfo() {
try {
const res = await findByIdApi(styleId.value);
styleData.value = res.data;
} catch (error) {
uni.showToast({
title: "获取数据失败,请重试",
icon: "none",
});
}
}

//#endregion ---------------------

//#region 生成写真照片
async function createing1() {
// 没有token则扫码登录
if (!uni.getStorageSync("token")) {
showQrCode.value = true;
return;
} else if (uni.getStorageSync("createTimes") == 0) {
showQrCode.value = true;
} else {
toCamera();
}
}
async function createing2() {
try {
uni.showLoading({
title: "生成中...",
mask: true,
});
// const res = await findImageApi();
// let myImg =
// "https://suimang.oss-accelerate.aliyuncs.com/capi/2023-09-18/bd50b0024ea4470cbd391bcb00382f72.jpg?x-oss-process=image/resize,w_10000/quality,q_60";
let myImg = cameraImg.value;
const data = {
machineQrcodeId: uni.getStorageSync("UserId"),
plat: uni.getStorageSync("plat"),
digitalAvatarId: styleData.value.id,
userImages: JSON.stringify([myImg]),
title: styleData.value.title,
};
const res2 = await createPhotoApi(data);
if (res2.data) {
console.log(res2);
// userInfoModulesPinia.createTimes = userInfoModulesPinia.createTimes - 1;
uni.navigateTo({
url: `/pages/created/index?id=${res2.data.id}&imgUrl=${styleData.value.coverImg}`,
});
} else {
throw new Error();
}
uni.hideLoading();
} catch (error) {
console.log(error);
uni.hideLoading();
uni.showToast({
title: "生成失败,请重试",
icon: "none",
});
}
}
//#endregion ---------------------

//#region 获取二维码
const qrCode = ref(null); //二维码路径
const showQrCode = ref(false);
const showQrCodeII = ref(false);

async function getQRCode() {
uni.showLoading({
title: "加载中",
mask: true,
});
try {
const data = {
// sn: "112233",
// sn: window.android.getIMEI(),
sn: window.localStorage.getItem("androidIdByWindow") || "112233",
type: 1,
};
const res = await getQRCodeApi(data);
uni.hideLoading();
if (res.code == 1013) {
uni.showToast({
title: "操作频繁,请稍等....",
icon: "none",
mask: true,
duration: 3000,
});
setTimeout(() => {
getQRCode();
}, 3000);
return;
}
if (res.data && res.data.tmpUserId) {
uni.setStorageSync("UserId", res.data.tmpUserId);
qrCode.value = res.data.qrCodeUrl;
getUser();
payCountTimer.value = setInterval(() => {
payCount.value--;
}, 1000);
} else if (res.code == 1013) {
uni.showToast({
title: "请勿重复操作",
icon: "error",
mask: true,
});
}
} catch (err) {
console.log(err);
uni.hideLoading();
uni.showToast({
title: "获取登录失败,请刷新页面重试",
icon: "error",
mask: true,
});
}
}
// getQRCode();
//#endregion ---------------------

//#region 获取用户信息

const payMask = ref(false); //支付状态遮罩层
const payCount = ref(300); //支付倒计时数
const payCountTimer = ref(null); //支付倒计时
// 获取登录信息
async function getUser() {
// 页面跳转停止递归
if (
getCurrentPages()[getCurrentPages().length - 1].route !=
"pages/createing/index"
) {
return;
}

// 如果二维码框隐藏,不再执行
if (showQrCode.value == false) {
return;
}
try {
const res = await getUserApi(uni.getStorageSync("UserId"));
// 如果接口200就说明已登录
if (res.code == 200 && res.data) {
// 查询支付状态 0:待支付,2:支付中,3:已支付
uni.setStorageSync("token", res.data.token);
uni.setStorageSync("createTimes", res.data.createTimes);
uni.setStorageSync("phone", res.data.phone);
userInfoModulesPinia.token = res.data.token;
userInfoModulesPinia.phone = res.data.phone;
userInfoModulesPinia.createTimes = res.data.createTimes;
if (res.data.payStatus == 3) {
clearInterval(payCountTimer.value);
payCountTimer.value = null;
uni.hideLoading();
payMask.value = false;
showQrCode.value = false;
uni.showToast({
title: "支付成功!",
icon: "success",
mask: true,
});
// 成功直接照相
// toCamera();
} else if (res.data.payStatus == 0) {
payMask.value = true;
uni.showLoading({
title: `待支付...`,
});
if (showQrCode.value == false) {
payMask.value = false;
uni.hideLoading();
return;
}
getUser();
} else if (res.data.payStatus == 2) {
payMask.value = true;
uni.showLoading({
title: `支付中...`,
});
if (showQrCode.value == false) {
payMask.value = false;
uni.hideLoading();
return;
}
getUser();
}
} else {
getUser();
}
} catch (err) {
console.log(err);
}
}
// 监听二维码弹窗显示隐藏
watch(
() => showQrCode.value,
() => {
if (showQrCode.value == true) {
getQRCode();
} else if (showQrCode.value == false) {
uni.hideLoading();
qrCode.value = null;
payMask.value = false;
clearInterval(payCountTimer.value);
payCountTimer.value = null;
payCount.value = 300;
}
}
);
// 监听支付倒计时
watch(
() => payCount.value,
() => {
if (payCount.value <= 0) {
uni.hideLoading();
showQrCode.value = false;
}
}
);
onUnload(() => {
uni.hideLoading();
clearInterval(payCountTimer.value);
payCountTimer.value = null;
showQrCode.value == false; // 停止getUser()的递归
// uni.setStorageSync("UserId", null);
});

//#endregion ---------------------

//#region 获取次数
async function getUser2() {
try {
const res = await getUserApi(uni.getStorageSync("UserId"));
// 如果接口200就说明已登录
if (res.code == 200 && res.data) {
// 查询支付状态 0:待支付,2:支付中,3:已支付
if (res.data.payStatus == 3) {
uni.setStorageSync("createTimes", res.data.createTimes);
userInfoModulesPinia.createTimes = res.data.createTimes;
}
}
} catch (err) {
console.log(err);
}
}
//#endregion ---------------------

//#region 路由跳转
function toChooseModel() {
uni.navigateTo({
url: `/pages/chooseStyle/index`,
});
}
function toCamera() {
const url = styleData.value.coverImg;
const id = styleData.value.id;
const mouldType = styleData.value.mouldType;
uni.navigateTo({
url: `/pages/camera/index?modelUrl=${url}&id=${id}&mouldType=${mouldType}`,
});
}
//#endregion ---------------------

const cancelUplaod = () => {
showQrCodeII.value = false;
userInfoModulesPinia.clearStorage();
uni.navigateTo({ url: "/pages/login/index" });
};

//#region 退出登录
function loginOut() {
if (userInfoModulesPinia.createTimes) {
uni.showModal({
title: "是否结束拍摄?",
content: `您还有${userInfoModulesPinia.createTimes}次拍摄机会`,
confirmColor: "#ff4f00",
confirmText: "再来一套",
cancelText: "结束拍摄",
success: function (res) {
if (res.confirm) {
console.log("用户点击确定");
uni.navigateTo({ url: "/pages/chooseStyle/index" });
} else if (res.cancel) {
console.log("用户点击取消");
showQrCodeII.value = true;
}
},
});
} else {
showQrCodeII.value = true;
}
}
//#endregion ---------------------

//#region

//#endregion ---------------------

//#region 页面初始化和卸载
const resetTimer = ref(null);
onMounted(() => {
window.document.addEventListener("touchstart", () => {
// 用户点击时,清除之前的定时器
clearTimeout(resetTimer.value);
// 重新设定120秒后触发的定时器
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
resetTimer.value = setTimeout(() => {
userInfoModulesPinia.clearStorage();
window.webview.raiseEvent("pageRefresh", "test_params");
uni.redirectTo({ url: "/pages/login/index" });
}, 300000);
});
onUnload(() => {
uni.hideLoading();
clearTimeout(resetTimer.value);
});
//#endregion -----------------------
</script>

<style lang="scss">
.userInfoBox {
position: relative;
padding: 0 50rpx;
width: 100%;
display: flex;
height: 50rpx;
line-height: 50rpx;
align-items: center;
border-radius: 20rpx;
background-color: rgba($color: #ccc, $alpha: 0.4);
.createTimes {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.loginOut {
position: absolute;
right: 20rpx;
height: 80%;
line-height: 160%;
background-color: #ff4f00;
color: #ffffff;
padding: 0 15rpx;
border-radius: 20rpx;
}
}
.showImgBox {
margin-top: 30rpx;
width: 540rpx;
height: 720rpx;
// background-color: #ccc;
border-radius: 30rpx;
image {
width: 100%;
height: 100%;
border-radius: 30rpx;
}
}
.name {
margin-top: 80rpx;
margin-bottom: 20rpx;
font-size: 44rpx;
font-weight: 800;
}
.orangeBtn {
position: relative;
}
.overlay {
.content {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.imageBox {
position: relative;
margin-top: 200rpx;
width: 300rpx;
height: 300rpx;
border-radius: 30rpx;
background-color: #fff;
.mask {
position: absolute;
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: rgba($color: #000000, $alpha: 0.7);
z-index: 2;
}
image {
width: 100%;
height: 100%;
border-radius: 30rpx;
background-color: #fff;
}
}
text {
margin-top: 20rpx;
font-weight: 900;
font-size: 32rpx;
}
// .orangeBtn {
// margin-top: 100rpx;
// }
}
}
</style>

+ 166
- 0
src/pages/login/index.vue 查看文件

@@ -0,0 +1,166 @@
<template>
<view class="page">
<image src="../../assets/img/homeImg.jpg" mode="scaleToFill" />
<view class="bottomBox">
<view class="orangeBtn" @click="toChooseStyle">拍摄数码写真</view>
<view class="IMEI" @click="Imei"
>1.0.10<text @click="reFresh">i</text>
</view>
<!-- <view style="margin-top: 20rpx" @click="reFresh">刷新</view> -->
<!-- <view style="margin-top: 20rpx" @click="runGetAndroidId()">获取</view> -->
</view>
</view>
</template>

<script setup>
//#region 导入
import { ref } from "vue";
import { isPlainObject, onLoad, onUnload } from "@dcloudio/uni-app";
import { userInfoModules } from "@/store/modules/userInfo";

const userInfoModulesPinia = userInfoModules();
//#endregion ----------------------------------

function toChooseStyle() {
uni.navigateTo({ url: "/pages/chooseStyle/index" });
}

function fileReaderTest() {
try {
plus.io.resolveLocalFileSystemURL(
"file:///storage/Documents",
function (entry) {
/* 获取文件目录 */
var directoryReader = entry.createReader(); //获取读取对象
directoryReader.readEntries(
function (entries) {
//历遍子目录即可
for (var i = 0; i < entries.length; i++) {
console.log("文件信息:" + entries[i].name);
uni.showToast({
// title: uni.getStorageSync("androidId"),
title: "文件信息:" + entries[i].name,
icon: "success",
});
}
},
function (err) {
console.log("访问目录失败");
uni.showToast({
title: err,
icon: "error",
});
}
);
},
function (err) {
console.log("访问指定目录失败:" + err.message);
uni.showToast({
title: err,
icon: "error",
});
}
);
} catch (error) {
console.log(error, "error");
}
}

//#region 初始化
onLoad(() => {
runGetAndroidId();
// fileReaderTest();
userInfoModulesPinia.clearStorage();
});
//#endregion ----------------------------------

//#region app交互
const IMEI = ref(null);
function Imei() {
try {
runGetAndroidId();
// window.webview.raiseEvent("getSerial", "test_params");
// window.webview.raiseEvent("getTestStr", "test_params");
// const IMEI = window.android.getIMEI();
// const IMEI = window.android.getSerial();
// const IMEI = window.android.getTestStr();
uni.showToast({
// title: uni.getStorageSync("androidId"),
title: window.localStorage.getItem("androidIdByWindow"),
icon: "success",
});
} catch (error) {
uni.showToast({
title: "Error",
icon: "error",
});
}

// cordova.exec(
// function (imei) {
// console.log("IMEI:", imei);
// },
// function (error) {
// console.error("Failed to get IMEI:", error);
// },
// "MyPlugin",
// "getIMEI",
// []
// );
}
function runGetAndroidId() {
window.webview.raiseEvent("getAndroidId", "test_params");
// alert("获取成功");
}
// function androidCallback(name, result_str) {
// IMEI.value = result_str;
// alert(result_str);
// alert("callBack " + name + " : " + result_str + "\n");
// // document.getElementById("text").value +=
// }

function reFresh() {
console.log("刷新");
window.webview.raiseEvent("pageRefresh", "test_params"); //刷新页面
// alert("刷新成功");
}
//#endregion ----------------------------------

//#region 登录

//#endregion ----------------------------------
</script>

<style lang="scss" scoped>
.page {
padding: 0;
position: relative;
width: 100vw;
height: 100vh;
image {
position: absolute;
width: 100%;
height: 100%;
}
.bottomBox {
position: absolute;
bottom: 0;
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 0;
width: 100%;
height: 300rpx;
background-color: rgba($color: #000000, $alpha: 0.5);
.IMEI {
position: absolute;
bottom: 20rpx;
right: 30rpx;
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
text-align: center;
}
}
}
</style>

+ 6
- 0
src/shime-uni.d.ts 查看文件

@@ -0,0 +1,6 @@
export {};

declare module "vue" {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentCustomOptions extends Hooks {}
}

+ 10
- 0
src/store/index.js 查看文件

@@ -0,0 +1,10 @@
import { createPinia } from 'pinia'
import * as Pinia from 'pinia'
import { createUnistorage } from 'pinia-plugin-unistorage'
// import { createPersistedState } from 'pinia-plugin-persistedstate'

const store = createPinia();
// const store = Pinia.createPinia()
store.use(createUnistorage())

export { store, Pinia };

+ 51
- 0
src/store/modules/userInfo.js 查看文件

@@ -0,0 +1,51 @@

import { defineStore } from "pinia";
import { ref } from "vue";

/**
* @description:用户信息持久化数据
*/

export const userInfoModules = defineStore("userInfoStore", () => {


/**
* @description:token
* @example
*/
const token = ref(null)

/**
* @description:用户手机号
* @example
*/
const phone = ref(null)

/**
* @description:剩余次数
* @example
*/
const createTimes = ref(0)

/**
* @description:清除所有
* @example
*/
function clearStorage() {
console.log('clearStorage!')
token.value = null
phone.value = null
createTimes.value = 0
uni.setStorageSync("token", null);
uni.setStorageSync("createTimes", 0);
uni.setStorageSync("phone", null);
uni.setStorageSync("UserId", null);
uni.setStorageSync("CcurrentUrl", null)
uni.setStorageSync("UcurrentUrl", null)
}
return { token, phone, createTimes, clearStorage };
},
{
unistorage: true,
}
);

+ 109
- 0
src/style/my.scss 查看文件

@@ -0,0 +1,109 @@
.page {
display: flex;
flex-direction: column;
align-items: center;
// justify-content: center;
padding: 30rpx;
// background-color: #fff;
font-size: 26rpx;
color: #fff;
position: relative;
min-height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
}


// 毛玻璃
.glass {
position: fixed;
width: 100vw;
height: 100vh;
z-index: -9;

image {
width: 100vw;
height: 100vh;
// position: fixed;
// background-size: 100% 100%;
// z-index: -1;
/* 通过滤镜增加毛玻璃效果 */
filter: blur(20rpx);
}
}

view {
box-sizing: border-box;
}

.imgContenBox {
position: relative;

image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}

.orangeBtn {
background-color: #FF4F00;
// background-color: #FF4F00;
width: 480rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
font-weight: bold;
text-align: center;
border-radius: 80rpx;
}

.grayBtn {
position: relative;
margin-top: 30rpx;
background-color: transparent;
width: 480rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
font-weight: bold;
text-align: center;
border-radius: 80rpx;
color: #FF4F00;
border: 2rpx solid #FF4F00;
}

// 部分样式1080下适配
.uni-toast {
width: 280rpx;
font-size: 30rpx;
padding: 20rpx 30rpx;

.uni-toast__icon {
width: 50rpx !important;
height: 50rpx !important;
}
}

.uni-simple-toast__text {
padding: 10rpx 20rpx;
font-size: 30rpx;
}

.uni-modal {
width: 500rpx;
max-width: 500rpx;

.uni-modal__title {
font-size: 28rpx;
}

.uni-modal__bd {
font-size: 28rpx;
}

.uni-modal__btn {
padding: 20rpx;
font-size: 28rpx;
}
}

+ 77
- 0
src/uni.scss 查看文件

@@ -0,0 +1,77 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/

/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/

/* 颜色变量 */
/* uni.scss */
@import 'uview-plus/theme.scss';
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

/* 文字基本颜色 */
$uni-text-color: #333; // 基本色
$uni-text-color-inverse: #fff; // 反色
$uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable: #c0c0c0;

/* 背景颜色 */
$uni-bg-color: #fff;
$uni-bg-color-grey: #f8f8f8;
$uni-bg-color-hover: #f1f1f1; // 点击状态颜色
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色

/* 边框颜色 */
$uni-border-color: #c8c7cc;

/* 尺寸变量 */

/* 文字尺寸 */
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16;

/* 图片尺寸 */
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;

/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;

/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;

/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;

/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度

/* 文章场景相关 */
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555; // 二级标题颜色
$uni-font-size-subtitle: 18px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;

+ 0
- 0
src/utils/index.js 查看文件


+ 64
- 0
src/utils/request.js 查看文件

@@ -0,0 +1,64 @@

// import { userInfoModules } from "@/store/modules/userInfo";
// import { store } from '@/store/index';

// const BASE_URL = 'https://test.metavatar.cc/C/';
const BASE_URL = 'https://zhixiang.malls.iformall.com/C/';
// const BASE_URL = '192.168.1.105:7600/C/';

// const userInfoModulesPinia = userInfoModules(store);
// const BASE_URL = 'https://test.metavatar.cc/';

// 通用的网络请求函数,接收请求的URL和请求参数,返回一个Promise
const timeoutNum = 30000;
const request = (requestObj) => {
return new Promise((resolve, reject) => {
// const timer = setTimeout(() => {
// reject(new Error('请求超时'));
// console.log('请求超时');
// uni.showToast({
// title: '请求超时,请稍后再试',
// icon: 'none',
// })
// }, timeoutNum);

uni.request({
url: BASE_URL + requestObj.url,
method: requestObj.method, // 这里可以根据需要更改请求方法
data: requestObj.data,
timeout: timeoutNum,
header: {
token: uni.getStorageSync("token"),
},
success: (res) => {
if (res.data.code == 1052) {
uni.setStorageSync("token", null)
uni.reLaunch({
url: "/pages/login/index?type=tokenFfalse",
});
return
}
if (res.statusCode == 200) {
// if (res.data.code == 200) {
resolve(res.data)
} else {
reject(new Error('请求失败'));
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
})
}
},
fail: (err) => {
reject(err, "拦截器返回错误");
uni.showToast({
title: '请求失败,请稍后再试',
icon: 'none',
})
},

})

})
};
export { BASE_URL, request }

+ 30
- 0
vite.config.js 查看文件

@@ -0,0 +1,30 @@
import { defineConfig, loadEnv } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd()) // 获取 .env里面定义是参数

console.log('env', env, mode, command)

return {
transpileDependencies: ['uview-ui'],
plugins: [
uni(),
],
server: {
host: "0.0.0.0",
port: '8591',
open: false, // 运行是否自动打开浏览器
proxy: {
// 反向代理解决跨域
"/api": {
target: env.VITE_APP_BASE_URL, // 线上接口地址
// target: "https://zhixiangtest.malls.iformall.com/C", // 线上接口地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ""),
},
},
}
}
})

+ 4314
- 0
yarn.lock
文件差異過大導致無法顯示
查看文件


Loading…
取消
儲存