update
This commit is contained in:
5
.env
5
.env
@@ -1,2 +1,3 @@
|
|||||||
VITE_API_URL=https://m1.apifoxmock.com
|
VITE_API_URL=http://192.168.1.105/api
|
||||||
VITE_AES_KEY=4e2c3d4e5f6a7b8c9d0e1f2g3h4i5j6k7l8m9n0o1p2q3r4s5t6u7v8w9x0y1z2
|
VITE_TINYMCE_KEY=agmu6i1c6k7bcp36oenzyz7yi1yplptq7goyx88y1g6ofnqu
|
||||||
|
VITE_AES_KEY=st123456654321st
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4050420250306001",
|
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4050420250306001",
|
||||||
"@tailwindcss/vite": "^4.0.15",
|
"@tailwindcss/vite": "^4.0.15",
|
||||||
"@uni-helper/vite-plugin-uni-tailwind": "^0.15.2",
|
"@uni-helper/vite-plugin-uni-tailwind": "^0.15.2",
|
||||||
|
"axios": "^1.9.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"deep-pick-omit": "^1.2.1",
|
"deep-pick-omit": "^1.2.1",
|
||||||
@@ -68,6 +69,7 @@
|
|||||||
"tailwindcss": "^4.0.15",
|
"tailwindcss": "^4.0.15",
|
||||||
"tailwindcss-rem2px-preset": "^1.0.3",
|
"tailwindcss-rem2px-preset": "^1.0.3",
|
||||||
"thorui-uni": "^3.0.0",
|
"thorui-uni": "^3.0.0",
|
||||||
|
"uniapp-axios-adapter": "^0.3.2",
|
||||||
"uqrcodejs": "^4.0.7",
|
"uqrcodejs": "^4.0.7",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
|
|||||||
42
pnpm-lock.yaml
generated
42
pnpm-lock.yaml
generated
@@ -62,6 +62,9 @@ importers:
|
|||||||
'@uni-helper/vite-plugin-uni-tailwind':
|
'@uni-helper/vite-plugin-uni-tailwind':
|
||||||
specifier: ^0.15.2
|
specifier: ^0.15.2
|
||||||
version: 0.15.2(rollup@4.37.0)(tailwindcss@4.1.5)(vite@6.3.5(@types/node@22.13.11)(jiti@2.4.2)(lightningcss@1.29.2)(sass-embedded@1.86.0)(terser@5.39.0)(yaml@2.7.1))
|
version: 0.15.2(rollup@4.37.0)(tailwindcss@4.1.5)(vite@6.3.5(@types/node@22.13.11)(jiti@2.4.2)(lightningcss@1.29.2)(sass-embedded@1.86.0)(terser@5.39.0)(yaml@2.7.1))
|
||||||
|
axios:
|
||||||
|
specifier: ^1.9.0
|
||||||
|
version: 1.9.0
|
||||||
crypto-js:
|
crypto-js:
|
||||||
specifier: ^4.2.0
|
specifier: ^4.2.0
|
||||||
version: 4.2.0
|
version: 4.2.0
|
||||||
@@ -95,6 +98,9 @@ importers:
|
|||||||
thorui-uni:
|
thorui-uni:
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
|
uniapp-axios-adapter:
|
||||||
|
specifier: ^0.3.2
|
||||||
|
version: 0.3.2(axios@1.9.0)
|
||||||
uqrcodejs:
|
uqrcodejs:
|
||||||
specifier: ^4.0.7
|
specifier: ^4.0.7
|
||||||
version: 4.0.7
|
version: 4.0.7
|
||||||
@@ -2257,6 +2263,9 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.1.0
|
postcss: ^8.1.0
|
||||||
|
|
||||||
|
axios@1.9.0:
|
||||||
|
resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==}
|
||||||
|
|
||||||
babel-jest@27.5.1:
|
babel-jest@27.5.1:
|
||||||
resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
|
resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==}
|
||||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||||
@@ -2904,6 +2913,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==}
|
resolution: {integrity: sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
form-data@4.0.2:
|
||||||
|
resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==}
|
||||||
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
forwarded@0.2.0:
|
forwarded@0.2.0:
|
||||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||||
engines: {node: '>= 0.6'}
|
engines: {node: '>= 0.6'}
|
||||||
@@ -4163,6 +4176,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
|
|
||||||
|
proxy-from-env@1.1.0:
|
||||||
|
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||||
|
|
||||||
psl@1.15.0:
|
psl@1.15.0:
|
||||||
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
|
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
|
||||||
|
|
||||||
@@ -4729,6 +4745,11 @@ packages:
|
|||||||
undici-types@6.20.0:
|
undici-types@6.20.0:
|
||||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
||||||
|
|
||||||
|
uniapp-axios-adapter@0.3.2:
|
||||||
|
resolution: {integrity: sha512-Wbq8tkjxTw80KaWqpBbrzB575FlJ0YZ+i/EhPFqJmP8iL/x8yzf04RgdrKP7KlI9VArTpEO5PcSe44ciRzTJ8Q==}
|
||||||
|
peerDependencies:
|
||||||
|
axios: '*'
|
||||||
|
|
||||||
unicode-canonical-property-names-ecmascript@2.0.1:
|
unicode-canonical-property-names-ecmascript@2.0.1:
|
||||||
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
|
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -7960,6 +7981,14 @@ snapshots:
|
|||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
postcss-value-parser: 4.2.0
|
postcss-value-parser: 4.2.0
|
||||||
|
|
||||||
|
axios@1.9.0:
|
||||||
|
dependencies:
|
||||||
|
follow-redirects: 1.15.9
|
||||||
|
form-data: 4.0.2
|
||||||
|
proxy-from-env: 1.1.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- debug
|
||||||
|
|
||||||
babel-jest@27.5.1(@babel/core@7.26.10):
|
babel-jest@27.5.1(@babel/core@7.26.10):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.10
|
'@babel/core': 7.26.10
|
||||||
@@ -8670,6 +8699,13 @@ snapshots:
|
|||||||
es-set-tostringtag: 2.1.0
|
es-set-tostringtag: 2.1.0
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
|
|
||||||
|
form-data@4.0.2:
|
||||||
|
dependencies:
|
||||||
|
asynckit: 0.4.0
|
||||||
|
combined-stream: 1.0.8
|
||||||
|
es-set-tostringtag: 2.1.0
|
||||||
|
mime-types: 2.1.35
|
||||||
|
|
||||||
forwarded@0.2.0: {}
|
forwarded@0.2.0: {}
|
||||||
|
|
||||||
fraction.js@4.3.7: {}
|
fraction.js@4.3.7: {}
|
||||||
@@ -10187,6 +10223,8 @@ snapshots:
|
|||||||
forwarded: 0.2.0
|
forwarded: 0.2.0
|
||||||
ipaddr.js: 1.9.1
|
ipaddr.js: 1.9.1
|
||||||
|
|
||||||
|
proxy-from-env@1.1.0: {}
|
||||||
|
|
||||||
psl@1.15.0:
|
psl@1.15.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
@@ -10748,6 +10786,10 @@ snapshots:
|
|||||||
|
|
||||||
undici-types@6.20.0: {}
|
undici-types@6.20.0: {}
|
||||||
|
|
||||||
|
uniapp-axios-adapter@0.3.2(axios@1.9.0):
|
||||||
|
dependencies:
|
||||||
|
axios: 1.9.0
|
||||||
|
|
||||||
unicode-canonical-property-names-ecmascript@2.0.1: {}
|
unicode-canonical-property-names-ecmascript@2.0.1: {}
|
||||||
|
|
||||||
unicode-match-property-ecmascript@2.0.0:
|
unicode-match-property-ecmascript@2.0.0:
|
||||||
|
|||||||
@@ -8,7 +8,48 @@ const system = {
|
|||||||
url: "/m1/5995958-5684445-default/getList",
|
url: "/m1/5995958-5684445-default/getList",
|
||||||
data: data,
|
data: data,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
getBarrageList: async () => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/index/getBarrageList",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
sendSms: async (data) => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/login/sendSms",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
register: async (data) => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/login/register",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
smsLogin: async (data) => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/login/smsLogin",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
accountLogin: async (data) => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/login/login",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editPassword: async (data) => {
|
||||||
|
return request({
|
||||||
|
method: MethodsENUM.POST,
|
||||||
|
url: "/login/editPassword",
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default system;
|
export default system;
|
||||||
|
|||||||
@@ -1,14 +1,49 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import {ref} from "vue";
|
||||||
import XLink from "./XLink.vue";
|
import XLink from "./XLink.vue";
|
||||||
import XInput from "./XInput.vue";
|
import XInput from "./XInput.vue";
|
||||||
|
import Api from "../api/index.js";
|
||||||
|
import {showToast} from "../utils/uils.js";
|
||||||
|
|
||||||
const modalValue = defineModel();
|
const modalValue = defineModel();
|
||||||
|
const timer = ref(null);
|
||||||
|
const props = defineProps({
|
||||||
|
mobile: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const sendMsg = async () => {
|
||||||
|
const {msg} = await Api.system.sendSms({
|
||||||
|
mobile: props.mobile,
|
||||||
|
type: props.type,
|
||||||
|
});
|
||||||
|
showToast(msg);
|
||||||
|
timer.value = 60;
|
||||||
|
const send = () => {
|
||||||
|
if (timer.value === 0) {
|
||||||
|
timer.value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
timer.value--;
|
||||||
|
setTimeout(send, 1000);
|
||||||
|
}
|
||||||
|
setTimeout(send, 1000);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<x-input v-bind="$attrs" v-model:model-value="modalValue" placeholder="验证码">
|
<x-input v-bind="$attrs" v-model:model-value="modalValue" placeholder="验证码">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<x-link>发送验证码</x-link>
|
<x-link @click="sendMsg">{{
|
||||||
|
timer ? `${timer}秒后重试` : `发送验证码`
|
||||||
|
}}
|
||||||
|
</x-link>
|
||||||
</template>
|
</template>
|
||||||
</x-input>
|
</x-input>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,12 +3,21 @@ import {reactive} from "vue";
|
|||||||
import XNav from "../../components/XNav.vue";
|
import XNav from "../../components/XNav.vue";
|
||||||
import XLink from "../../components/XLink.vue";
|
import XLink from "../../components/XLink.vue";
|
||||||
import XInput from "../../components/XInput.vue";
|
import XInput from "../../components/XInput.vue";
|
||||||
|
import Api from "../../api/index.js";
|
||||||
|
import {backPage, showToast} from "../../utils/uils.js";
|
||||||
|
import SendMsg from "../../components/SendMsg.vue";
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
phone: null,
|
mobile: null,
|
||||||
verificationCode: null,
|
captcha: null,
|
||||||
password: null,
|
password: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const success = async () => {
|
||||||
|
const {msg} = await Api.system.editPassword(form);
|
||||||
|
showToast(msg);
|
||||||
|
backPage();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -22,19 +31,21 @@ const form = reactive({
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="!flex flex-col gap-[56rpx] !mt-[60rpx]">
|
<view class="!flex flex-col gap-[56rpx] !mt-[60rpx]">
|
||||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
<x-input v-model:model-value="form.mobile" placeholder="请输入手机号"></x-input>
|
||||||
<x-input v-model:model-value="form.verificationCode" placeholder="验证码">
|
<send-msg v-model:model-value="form.captcha" :mobile="form.mobile" :type="3"></send-msg>
|
||||||
<template #suffix>
|
<x-input v-model:model-value="form.password" placeholder="请输入密码"></x-input>
|
||||||
<x-link>发送验证码</x-link>
|
|
||||||
</template>
|
|
||||||
</x-input>
|
|
||||||
<x-input v-model:model-value="form.phone" placeholder="请输入密码"></x-input>
|
|
||||||
|
|
||||||
<tui-button>确定修改</tui-button>
|
<tui-button @click="success">确定修改</tui-button>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.title {
|
.title {
|
||||||
color: rgb(29, 33, 41);
|
color: rgb(29, 33, 41);
|
||||||
|
|||||||
@@ -2,23 +2,36 @@
|
|||||||
import {reactive} from "vue";
|
import {reactive} from "vue";
|
||||||
import XInput from "../../components/XInput.vue";
|
import XInput from "../../components/XInput.vue";
|
||||||
import XLink from "../../components/XLink.vue";
|
import XLink from "../../components/XLink.vue";
|
||||||
import {toPage} from "../../utils/uils.js";
|
import {showToast, toPage} from "../../utils/uils.js";
|
||||||
|
import Api from "../../api/index.js";
|
||||||
|
import {useUserStore} from "../../pinia/UserStore/index.js";
|
||||||
|
|
||||||
|
const UserStore = useUserStore();
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
phone: null,
|
mobile: null,
|
||||||
verificationCode: null,
|
password: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const success = async () => {
|
||||||
|
const {msg, data} = await Api.system.accountLogin(form);
|
||||||
|
showToast(msg);
|
||||||
|
UserStore.isLogin = true;
|
||||||
|
UserStore.token = data.token;
|
||||||
|
Object.assign(UserStore.userInfo, data);
|
||||||
|
await toPage('/pages/home/index');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
||||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
<x-input v-model:model-value="form.mobile" placeholder="请输入手机号"></x-input>
|
||||||
<x-input v-model:model-value="form.verificationCode" placeholder="密码">
|
<x-input v-model:model-value="form.password" placeholder="密码">
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<x-link @click="toPage('/pages/forgotPassword/index')">忘记密码?</x-link>
|
<x-link @click="toPage('/pages/forgotPassword/index')">忘记密码?</x-link>
|
||||||
</template>
|
</template>
|
||||||
</x-input>
|
</x-input>
|
||||||
<tui-button class="!mt-[80rpx]">登录</tui-button>
|
<tui-button class="!mt-[80rpx]" @click="success">登录</tui-button>
|
||||||
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
||||||
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
||||||
</tui-button>
|
</tui-button>
|
||||||
|
|||||||
@@ -1,42 +1,34 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import dm1 from '../../static/icons/弹幕1.png';
|
import {reactive, onMounted} from "vue";
|
||||||
import dm2 from '../../static/icons/弹幕2.png';
|
import Api from "../../api/index.js";
|
||||||
import dm3 from '../../static/icons/弹幕3.png';
|
|
||||||
import dm4 from '../../static/icons/弹幕4.png';
|
|
||||||
import dm5 from '../../static/icons/弹幕5.png';
|
|
||||||
import dm6 from '../../static/icons/弹幕6.png';
|
|
||||||
import dm7 from '../../static/icons/弹幕7.png';
|
|
||||||
import dm8 from '../../static/icons/弹幕8.png';
|
|
||||||
import dm9 from '../../static/icons/弹幕9.png';
|
|
||||||
import {reactive} from "vue";
|
|
||||||
|
|
||||||
const MAP = [dm1,dm2,dm3,dm4,dm5,dm6,dm7,dm8,dm9];
|
|
||||||
const list1 = reactive([]);
|
const list1 = reactive([]);
|
||||||
const list2 = reactive([]);
|
const list2 = reactive([]);
|
||||||
|
onMounted(() => {
|
||||||
for (let i = 0; i <= 100; i++) {
|
Api.system.getBarrageList().then(({data}) => {
|
||||||
list1.push(MAP[Math.floor(Math.random() * 9)]);
|
for (let i = 0; i <= 1000; i++) {
|
||||||
list2.push(MAP[Math.floor(Math.random() * 9)]);
|
list1.push(data[Math.floor(Math.random() * data.length)]);
|
||||||
|
list2.push(data[Math.floor(Math.random() * data.length)]);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="!mt-[68rpx] !flex flex-col gap-[20rpx]">
|
<view class="!mt-[68rpx] !flex flex-col gap-[20rpx]">
|
||||||
<view class="!flex gap-[30rpx] scrollX">
|
<view class="!flex gap-[30rpx] scrollX">
|
||||||
<image
|
<view
|
||||||
v-for="item in list1"
|
v-for="item in list1"
|
||||||
class="!h-[72rpx]"
|
class="!h-[72rpx] qp">
|
||||||
mode="heightFix"
|
{{ item }}
|
||||||
:src="item">
|
</view>
|
||||||
</image>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="!flex gap-[30rpx] scrollX">
|
<view class="!flex gap-[30rpx] scrollX">
|
||||||
<image
|
<view
|
||||||
v-for="item in list2"
|
v-for="item in list2"
|
||||||
class="!h-[72rpx]"
|
class="!h-[72rpx] qp">
|
||||||
mode="heightFix"
|
{{ item }}
|
||||||
:src="item">
|
</view>
|
||||||
</image>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -44,7 +36,7 @@ for (let i = 0; i <= 100; i++) {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.scrollX {
|
.scrollX {
|
||||||
width: max-content !important;
|
width: max-content !important;
|
||||||
animation: scroll 150s linear infinite;
|
animation: scroll 800s linear infinite;
|
||||||
|
|
||||||
image {
|
image {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@@ -59,4 +51,11 @@ for (let i = 0; i <= 100; i++) {
|
|||||||
transform: translateX(-100%); /* 滚动到左侧结束 */
|
transform: translateX(-100%); /* 滚动到左侧结束 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.qp {
|
||||||
|
@apply px-[36rpx] flex items-center rounded-full;
|
||||||
|
background: linear-gradient(to right, #B8C5E9, #CAE2E9, #D0D6E2);
|
||||||
|
box-shadow: inset 0 0 10px 15rpx rgba(255, 255, 255);
|
||||||
|
backdrop-filter: blur(20px);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,27 +1,32 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {reactive} from "vue";
|
import {reactive} from "vue";
|
||||||
import XInput from "../../components/XInput.vue";
|
import XInput from "../../components/XInput.vue";
|
||||||
import {toPage} from "../../utils/uils.js";
|
import {showToast, toPage} from "../../utils/uils.js";
|
||||||
import SendMsg from "../../components/SendMsg.vue";
|
import SendMsg from "../../components/SendMsg.vue";
|
||||||
import {useUserStore} from "../../pinia/UserStore/index.js";
|
import {useUserStore} from "../../pinia/UserStore/index.js";
|
||||||
|
import Api from "../../api/index.js";
|
||||||
|
|
||||||
const {login} = useUserStore();
|
const UserStore = useUserStore();
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
phone: null,
|
mobile: null,
|
||||||
verificationCode: null,
|
captcha: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const success = async () => {
|
const success = async () => {
|
||||||
login();
|
const {msg, data} = await Api.system.accountLogin(form);
|
||||||
toPage('/pages/home/index');
|
showToast(msg);
|
||||||
|
UserStore.isLogin = true;
|
||||||
|
UserStore.token = data.token;
|
||||||
|
Object.assign(UserStore.userInfo, data);
|
||||||
|
await toPage('/pages/home/index');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
||||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
<x-input v-model:model-value="form.mobile" placeholder="请输入手机号"></x-input>
|
||||||
<send-msg v-model:model-value="form.verificationCode"></send-msg>
|
<send-msg v-model:model-value="form.captcha" :mobile="form.mobile" :type="2"></send-msg>
|
||||||
<tui-button class="!mt-[80rpx]" @click="success">登录</tui-button>
|
<tui-button class="!mt-[80rpx]" @click="success">登录</tui-button>
|
||||||
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
<tui-button @click="toPage('/pages/register/index')" class="!mt-[40rpx]" plain link>
|
||||||
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
<image class="!h-[26rpx]" mode="heightFix" src="../../static/icons/去注册.png"></image>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import BGICON from "../../static/icons/bg.png";
|
||||||
import XNav from "../../components/XNav.vue";
|
import XNav from "../../components/XNav.vue";
|
||||||
import BulletChat from "./BulletChat.vue";
|
import BulletChat from "./BulletChat.vue";
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
@@ -20,13 +21,13 @@ const tabs = [
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!--登陆-->
|
<!--登陆-->
|
||||||
<XNav></XNav>
|
<XNav :showBack="false"></XNav>
|
||||||
|
|
||||||
<view class="h-[390rpx] relative overflow-hidden">
|
<view class="h-[390rpx] relative overflow-hidden">
|
||||||
<image class="!absolute left-1/2 top-1/2 -translate-1/2 !w-[1198rpx] !h-[806rpx] -z-10 !pb-[40rpx]"
|
<image class="!absolute left-1/2 top-1/2 -translate-1/2 !w-[1198rpx] !h-[806rpx] !pb-[40rpx]"
|
||||||
src="/static/icons/bg.png"></image>
|
:src="BGICON"></image>
|
||||||
|
|
||||||
<view class="!flex gap-[16rpx] items-center !mt-[56rpx] !ml-[16rpx]">
|
<view class="!flex gap-[16rpx] items-center !mt-[56rpx] !ml-[16rpx] relative z-10">
|
||||||
<image class="!w-[68rpx] !h-[68rpx]" src="/static/icons/hi.png"></image>
|
<image class="!w-[68rpx] !h-[68rpx]" src="/static/icons/hi.png"></image>
|
||||||
<view class="title">欢迎登录系统</view>
|
<view class="title">欢迎登录系统</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -34,8 +35,9 @@ const tabs = [
|
|||||||
<BulletChat></BulletChat>
|
<BulletChat></BulletChat>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="h-full bg-white !-mt-[20rpx] rounded-t-[20rpx]">
|
<view class="h-full bg-white !-mt-[20rpx] rounded-t-[20rpx] relative z-10">
|
||||||
<tui-tabs class="!mx-auto !mb-[40rpx]" :tabs="tabs" :currentTab="currentTab" itemWidth="50%" @change="({index}) => currentTab=index" :width="300" :sliderWidth="130"></tui-tabs>
|
<tui-tabs class="!mx-auto !mb-[40rpx]" :tabs="tabs" :currentTab="currentTab" itemWidth="50%"
|
||||||
|
@change="({index}) => currentTab=index" :width="300" :sliderWidth="130"></tui-tabs>
|
||||||
|
|
||||||
<PhoneLogin v-if="currentTab === 0"></PhoneLogin>
|
<PhoneLogin v-if="currentTab === 0"></PhoneLogin>
|
||||||
<AccountLogin v-else></AccountLogin>
|
<AccountLogin v-else></AccountLogin>
|
||||||
|
|||||||
@@ -4,17 +4,20 @@ import XNav from "../../components/XNav.vue";
|
|||||||
import BulletChat from "../login/BulletChat.vue";
|
import BulletChat from "../login/BulletChat.vue";
|
||||||
import XInput from "../../components/XInput.vue";
|
import XInput from "../../components/XInput.vue";
|
||||||
import SendMsg from "../../components/SendMsg.vue";
|
import SendMsg from "../../components/SendMsg.vue";
|
||||||
|
import Api from "../../api/index.js";
|
||||||
|
import {showToast} from "../../utils/uils.js";
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
phone: null,
|
mobile: null,
|
||||||
wxCode: null,
|
wechat: null,
|
||||||
verificationCode: null,
|
captcha: null,
|
||||||
password: null,
|
password: null,
|
||||||
code: null,
|
invite: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const success = () => {
|
const success = async () => {
|
||||||
|
const {msg} = await Api.system.register(form);
|
||||||
|
showToast(msg);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -23,10 +26,10 @@ const success = () => {
|
|||||||
<XNav></XNav>
|
<XNav></XNav>
|
||||||
|
|
||||||
<view class="h-[390rpx] relative overflow-hidden">
|
<view class="h-[390rpx] relative overflow-hidden">
|
||||||
<image class="!absolute left-1/2 top-1/2 -translate-1/2 !w-[1198rpx] !h-[806rpx] -z-10 !pb-[40rpx]"
|
<image class="!absolute left-1/2 top-1/2 -translate-1/2 !w-[1198rpx] !h-[806rpx] !pb-[40rpx]"
|
||||||
src="/static/icons/bg.png"></image>
|
src="/static/icons/bg.png"></image>
|
||||||
|
|
||||||
<view class="!flex gap-[16rpx] items-center !mt-[56rpx] !ml-[16rpx]">
|
<view class="!flex gap-[16rpx] items-center !mt-[56rpx] !ml-[16rpx] relative z-10">
|
||||||
<image class="!w-[68rpx] !h-[68rpx]" src="/static/icons/hi.png"></image>
|
<image class="!w-[68rpx] !h-[68rpx]" src="/static/icons/hi.png"></image>
|
||||||
<view class="title">欢迎注册</view>
|
<view class="title">欢迎注册</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -34,13 +37,13 @@ const success = () => {
|
|||||||
<BulletChat></BulletChat>
|
<BulletChat></BulletChat>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="h-full bg-white !-mt-[20rpx] rounded-t-[20rpx] !pt-[44rpx]">
|
<view class="h-full bg-white !-mt-[20rpx] rounded-t-[20rpx] !pt-[44rpx] relative z-10">
|
||||||
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
<view class="!px-[34rpx] !flex flex-col gap-[40rpx]">
|
||||||
<x-input v-model:model-value="form.wxCode" placeholder="请输入微信号"></x-input>
|
<x-input v-model:model-value="form.wechat" placeholder="请输入微信号"></x-input>
|
||||||
<x-input v-model:model-value="form.phone" placeholder="请输入手机号"></x-input>
|
<x-input v-model:model-value="form.mobile" placeholder="请输入手机号"></x-input>
|
||||||
<send-msg v-model:model-value="form.verificationCode"></send-msg>
|
<send-msg v-model:model-value="form.captcha" :mobile="form.mobile"></send-msg>
|
||||||
<x-input v-model:model-value="form.password" placeholder="请输入登录密码"></x-input>
|
<x-input v-model:model-value="form.password" placeholder="请输入登录密码"></x-input>
|
||||||
<x-input v-model:model-value="form.code" placeholder="请输入邀请码"></x-input>
|
<x-input v-model:model-value="form.invite" placeholder="请输入邀请码"></x-input>
|
||||||
|
|
||||||
<tui-button class="!mt-[52rpx]" @click="success">确认注册</tui-button>
|
<tui-button class="!mt-[52rpx]" @click="success">确认注册</tui-button>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
import {defineStore} from "pinia";
|
import {defineStore} from "pinia";
|
||||||
import {ref} from "vue";
|
import {ref, reactive} from "vue";
|
||||||
|
|
||||||
export const useUserStore = defineStore('UserStore', () => {
|
export const useUserStore = defineStore('UserStore', () => {
|
||||||
const isLogin = ref(false);
|
const isLogin = ref(false);
|
||||||
const userInfo = ref(null);
|
const token = ref(null);
|
||||||
|
const userInfo = reactive({});
|
||||||
const login = () => {
|
|
||||||
isLogin.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isLogin,
|
isLogin,
|
||||||
userInfo,
|
userInfo,
|
||||||
login,
|
token,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
persist: {
|
persist: {
|
||||||
key: 'UserStore',
|
key: 'UserStore',
|
||||||
|
pick: ['isLogin', 'userInfo', 'token'],
|
||||||
storage: {
|
storage: {
|
||||||
getItem(key) {
|
getItem(key) {
|
||||||
return uni.getStorageSync(key);
|
return uni.getStorageSync(key);
|
||||||
@@ -25,6 +23,5 @@ export const useUserStore = defineStore('UserStore', () => {
|
|||||||
uni.setStorageSync(key, value);
|
uni.setStorageSync(key, value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pick: ['isLogin', 'userInfo']
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +1,58 @@
|
|||||||
import AES from 'crypto-js/aes.js';
|
import Crypto from 'crypto-js';
|
||||||
import utf8 from 'crypto-js/enc-utf8.js';
|
|
||||||
|
|
||||||
class AESCrypto {
|
class AESCrypto {
|
||||||
/**
|
/**
|
||||||
* 密钥
|
* 密钥
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
static #AES_KEY = import.meta.env.VITE_AES_KEY;
|
static _AES_KEY = import.meta.env.VITE_AES_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES加密
|
* AES加密
|
||||||
* @param context {string} 加密内容
|
* @param context {string} 加密内容
|
||||||
*/
|
*/
|
||||||
static encrypt = (context) => {
|
static encrypt = (context) => {
|
||||||
return AES.encrypt(context, this.#AES_KEY).toString();
|
const IV = this.createIV();
|
||||||
|
return {
|
||||||
|
context: Crypto.AES.encrypt(
|
||||||
|
context,
|
||||||
|
Crypto.enc.Utf8.parse(this._AES_KEY),
|
||||||
|
{
|
||||||
|
iv: Crypto.enc.Utf8.parse(IV),
|
||||||
|
mode: Crypto.mode.CBC,
|
||||||
|
padding: Crypto.pad.Pkcs7
|
||||||
|
}
|
||||||
|
).toString(),
|
||||||
|
iv: IV,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES解密
|
* AES解密
|
||||||
* @param context {string}
|
* @param context {string}
|
||||||
|
* @param iv {string}
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
static decrypt = (context) => {
|
static decrypt = (context, iv) => {
|
||||||
const bytes = AES.decrypt(context, this.#AES_KEY);
|
return Crypto.AES.decrypt(
|
||||||
return bytes.toString(utf8);
|
context,
|
||||||
|
Crypto.enc.Utf8.parse(this._AES_KEY),
|
||||||
|
{
|
||||||
|
iv: Crypto.enc.Utf8.parse(iv),
|
||||||
|
mode: Crypto.mode.CBC,
|
||||||
|
padding: Crypto.pad.Pkcs7
|
||||||
|
}
|
||||||
|
).toString(Crypto.enc.Utf8);
|
||||||
|
};
|
||||||
|
|
||||||
|
static createIV = (length = 16) => {
|
||||||
|
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
const randomIndex = Math.floor(Math.random() * characters.length);
|
||||||
|
result += characters[randomIndex];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +1,69 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import {UniAdapter} from "uniapp-axios-adapter";
|
||||||
import {showToast} from "./uils.js";
|
import {showToast} from "./uils.js";
|
||||||
|
import AESCrypto from "./AESCrypto.js";
|
||||||
|
import {useUserStore} from "../pinia/UserStore/index.js";
|
||||||
|
|
||||||
const request = (options) => {
|
export const BASEURL = import.meta.env.MODE === 'development' ? '/baseApi/api' : import.meta.env.VITE_API_URL;
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const {url, method, data, params} = options;
|
|
||||||
|
|
||||||
uni.request({
|
const request = axios.create({
|
||||||
method: method,
|
baseURL: BASEURL,
|
||||||
data: data,
|
timeout: '6000',
|
||||||
params: params,
|
adapter: UniAdapter,
|
||||||
url: `${import.meta.env.VITE_API_URL}${url}`,
|
});
|
||||||
success: ({data}) => {
|
|
||||||
if (data.code !== 0) {
|
request.interceptors.request.use(
|
||||||
showToast(data.msg);
|
(config) => {
|
||||||
reject(data.msg);
|
const {token} = useUserStore();
|
||||||
|
|
||||||
|
// 如果 token 存在,则将其添加到请求头中
|
||||||
|
if (token) {
|
||||||
|
config.headers['Access-Token'] = token;
|
||||||
}
|
}
|
||||||
resolve(data);
|
|
||||||
|
console.log('请求拦截器', config.data);
|
||||||
|
|
||||||
|
if (!config.UN_AES) {
|
||||||
|
const {context, iv} = AESCrypto.encrypt(JSON.stringify(config.data));
|
||||||
|
|
||||||
|
config.data = {
|
||||||
|
requestData: context, iv: iv,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
(error) => {
|
||||||
reject(err);
|
// 处理请求错误
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
request.interceptors.response.use((response) => {
|
||||||
|
const {data: {msg, code, data}, config: {url}} = response;
|
||||||
|
console.log('接口返回', response)
|
||||||
|
if (code === 401) {
|
||||||
|
const {logout} = useUserStore();
|
||||||
|
logout();
|
||||||
|
}
|
||||||
|
if (code !== 1) {
|
||||||
|
showToast(msg);
|
||||||
|
return Promise.reject(msg);
|
||||||
|
}
|
||||||
|
if (!data.data) {
|
||||||
|
return {msg, code, data}
|
||||||
|
} else {
|
||||||
|
const resp = JSON.parse(AESCrypto.decrypt(data.data, data.iv));
|
||||||
|
console.log(`接口${url}返回`, resp);
|
||||||
|
return {data: resp};
|
||||||
|
}
|
||||||
|
}, (error) => {
|
||||||
|
if (error.response) {
|
||||||
|
return Promise.reject(error.response.data); // 返回错误信息
|
||||||
|
} else { // 网络错误
|
||||||
|
return Promise.reject(error.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export default request;
|
export default request;
|
||||||
|
|||||||
@@ -4,22 +4,25 @@ import {UnifiedViteWeappTailwindcssPlugin} from 'weapp-tailwindcss/vite';
|
|||||||
import tailwindcss from '@tailwindcss/postcss'
|
import tailwindcss from '@tailwindcss/postcss'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [uni.default({
|
||||||
uni.default(),
|
script: {
|
||||||
UnifiedViteWeappTailwindcssPlugin({
|
defineModel: true,
|
||||||
|
}
|
||||||
|
}), UnifiedViteWeappTailwindcssPlugin({
|
||||||
rem2rpx: true,
|
rem2rpx: true,
|
||||||
})
|
})], css: {
|
||||||
],
|
|
||||||
css: {
|
|
||||||
postcss: {
|
postcss: {
|
||||||
plugins: [
|
plugins: [tailwindcss()]
|
||||||
tailwindcss()
|
}, preprocessorOptions: {
|
||||||
]
|
|
||||||
},
|
|
||||||
preprocessorOptions: {
|
|
||||||
scss: {
|
scss: {
|
||||||
silenceDeprecations: ['legacy-js-api'],
|
silenceDeprecations: ['legacy-js-api'],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
}, server: {
|
||||||
|
proxy: {
|
||||||
|
'/baseApi': {
|
||||||
|
target: 'http://192.168.1.105', changeOrigin: true, rewrite: (path) => path.replace(/^\/baseApi/, ''),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user