@@ -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' |
@@ -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? |
@@ -0,0 +1,5 @@ | |||
{ | |||
"Name": "Metavatar_Screen_Android", | |||
"Version": "1.0.0", | |||
"H5_Url": "https://zhixiang.malls.iformall.com" | |||
} |
@@ -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_ |
@@ -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> |
@@ -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" | |||
} | |||
} |
@@ -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 { | |||
} | |||
} |
@@ -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> |
@@ -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' | |||
}) | |||
} |
@@ -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 | |||
}) | |||
} |
@@ -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', | |||
}) | |||
} |
@@ -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 | |||
}) | |||
} |
@@ -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', | |||
}) | |||
} |
@@ -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, | |||
}; | |||
} |
@@ -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" | |||
} |
@@ -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" | |||
] | |||
} | |||
} |
@@ -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" | |||
>取 消</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> |
@@ -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> |
@@ -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> |
@@ -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" | |||
>取 消</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> |
@@ -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> |
@@ -0,0 +1,6 @@ | |||
export {}; | |||
declare module "vue" { | |||
type Hooks = App.AppInstance & Page.PageInstance; | |||
interface ComponentCustomOptions extends Hooks {} | |||
} |
@@ -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 }; |
@@ -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, | |||
} | |||
); |
@@ -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; | |||
} | |||
} |
@@ -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 +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 } |
@@ -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/, ""), | |||
}, | |||
}, | |||
} | |||
} | |||
}) |