feat: 项目初始化。

This commit is contained in:
tianyongbao
2025-12-18 22:11:37 +08:00
parent 22c072a957
commit e41581f26b
633 changed files with 90998 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
src/pages/assets/four.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
src/pages/assets/one.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/pages/assets/three.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
src/pages/assets/two.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
<template>
<view>
<uni-card class="view-title" :title="title">
<text class="uni-body view-content">{{ content }}</text>
</uni-card>
</view>
</template>
<script>
export default {
data() {
return {
title: '',
content: ''
}
},
onLoad(options) {
this.title = options.title
this.content = options.content
uni.setNavigationBarTitle({
title: options.title
})
}
}
</script>
<style scoped>
page {
background-color: #ffffff;
}
.view-title {
font-weight: bold;
}
.view-content {
font-size: 26rpx;
padding: 12px 5px 0;
color: #333;
line-height: 24px;
font-weight: normal;
}
</style>

View File

@@ -0,0 +1,34 @@
<template>
<view v-if="params.url">
<web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
params: {},
webviewStyles: {
progress: {
color: "#FF3333"
}
}
}
},
props: {
src: {
type: [String],
default: null
}
},
onLoad(event) {
this.params = event
if (event.title) {
uni.setNavigationBarTitle({
title: event.title
})
}
}
}
</script>

172
src/pages/login.vue Normal file
View File

@@ -0,0 +1,172 @@
<template>
<view class="normal-login-container">
<view class="login-content">
<!-- Logo区域 -->
<view class="logo-section">
<view class="logo-circle">
<image
class="bluetooth-logo"
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSIjZmZmZmZmIj48cGF0aCBkPSJNMTcuNzEgNy43MUwxMiAyaC0xdjcuNTlMNi40MSA1IDUgNi40MSAxMC41OSAxMiA1IDE3LjU5IDYuNDEgMTkgMTEgMTQuNDFWMjJoMWw1LjcxLTUuNzEtNC4zLTQuMjkgNC4zLTQuMjl6TTEzIDUuODNsMS44OCAxLjg4TDEzIDkuNTlWNS44M3ptMS44OCAxMC40NkwxMyAxOC4xN3YtMy43NmwxLjg4IDEuODh6Ii8+PC9zdmc+"
mode="aspectFit"
/>
</view>
</view>
<!-- 标题 -->
<view class="title-section">
<text class="main-title">搅拌器控制连接</text>
<text class="sub-title">快速搜索并连接附近搅拌器蓝牙设备</text>
</view>
<!-- 登录按钮 -->
<view class="btn-section">
<button @click="handleLogin" class="login-btn">
<uni-icons type="right" size="24" color="#667eea" style="margin-right: 12rpx;"></uni-icons>
<text class="btn-text">进入</text>
</button>
</view>
<!-- 装饰元素 -->
<view class="decoration-dots">
<view class="dot dot-1"></view>
<view class="dot dot-2"></view>
<view class="dot dot-3"></view>
</view>
</view>
</view>
</template>
<script setup>
// 直接跳转到蓝牙设备页面
function handleLogin() {
uni.reLaunch({
url: '/pages/bluetooth/bluetooth'
});
}
</script>
<style lang="scss" scoped>
page {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #667eea;
}
.normal-login-container {
width: 100%;
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
overflow-y: auto;
overflow-x: hidden;
.login-content {
padding: 0 60rpx;
width: 100%;
.logo-section {
display: flex;
justify-content: center;
margin-bottom: 60rpx;
.logo-circle {
width: 200rpx;
height: 200rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10rpx);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3),
inset 0 0 40rpx rgba(255, 255, 255, 0.1);
padding: 25rpx;
border: 3rpx solid rgba(255, 255, 255, 0.3);
.bluetooth-logo {
width: 120rpx;
height: 120rpx;
filter: drop-shadow(0 8rpx 16rpx rgba(0, 0, 0, 0.2));
}
}
}
.title-section {
text-align: center;
margin-bottom: 80rpx;
.main-title {
display: block;
font-size: 52rpx;
font-weight: 700;
color: #ffffff;
margin-bottom: 20rpx;
letter-spacing: 2rpx;
text-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.2);
}
.sub-title {
display: block;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.85);
line-height: 1.6;
}
}
.btn-section {
margin-bottom: 40rpx;
.login-btn {
width: 100%;
height: 100rpx;
background: #ffffff;
border-radius: 50rpx;
border: none;
box-shadow: 0 16rpx 40rpx rgba(0, 0, 0, 0.25);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&::after {
border: none;
}
&:active {
transform: translateY(4rpx);
box-shadow: 0 12rpx 32rpx rgba(0, 0, 0, 0.2);
}
.btn-text {
color: #667eea;
font-size: 34rpx;
font-weight: 600;
}
}
}
.decoration-dots {
display: flex;
justify-content: center;
gap: 16rpx;
.dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
}
}
}
}
</style>

131
src/pages/mine.vue Normal file
View File

@@ -0,0 +1,131 @@
<template>
<view class="mine-container">
<!-- 顶部个人信息栏 -->
<view class="header-section">
<view class="user-info">
<view class="avatar">
<uni-icons type="person-filled" size="40" color="#ffffff"></uni-icons>
</view>
<view class="user-details">
<text class="user-name">{{ userInfo.name }}</text>
<text class="user-id">ID: {{ userInfo.userId }}</text>
</view>
</view>
</view>
<!-- 内容区域 -->
<view class="content-section">
<view class="info-card">
<view class="info-item">
<text class="info-label">手机号</text>
<text class="info-value">{{ userInfo.phone }}</text>
</view>
<view class="info-divider"></view>
<view class="info-item">
<text class="info-label">邮箱</text>
<text class="info-value">{{ userInfo.email }}</text>
</view>
<view class="info-divider"></view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 模拟个人信息
const userInfo = ref({
name: '智聪',
userId: '10001',
phone: '138****5678',
email: 'qdintc@126.com'
})
</script>
<style lang="scss" scoped>
page {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #f5f7fa;
}
.mine-container {
width: 100%;
height: 100vh;
background-color: #f5f7fa;
overflow-y: auto;
.header-section {
padding: 40rpx 32rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
.user-info {
display: flex;
align-items: center;
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50rpx;
background: rgba(255, 255, 255, 0.3);
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
}
.user-details {
flex: 1;
.user-name {
display: block;
color: #ffffff;
font-size: 32rpx;
font-weight: 600;
margin-bottom: 8rpx;
}
.user-id {
color: rgba(255, 255, 255, 0.8);
font-size: 24rpx;
}
}
}
}
.content-section {
padding: 32rpx;
.info-card {
background: #ffffff;
border-radius: 16rpx;
padding: 32rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
.info-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 0;
.info-label {
color: #666;
font-size: 28rpx;
}
.info-value {
color: #333;
font-size: 28rpx;
}
}
.info-divider {
height: 1rpx;
background-color: #f0f0f0;
}
}
}
}
</style>

1355
src/pages/mixer/mixer.vue Normal file

File diff suppressed because it is too large Load Diff

297
src/pages/register.vue Normal file
View File

@@ -0,0 +1,297 @@
<template>
<view class="register-container">
<view class="background-decoration"></view>
<view class="header-section">
<text class="page-title">用户注册</text>
<text class="page-subtitle">创建你的账号</text>
</view>
<view class="form-section">
<view class="form-card">
<uni-forms ref="form" :value="user" labelWidth="80px">
<uni-forms-item name="username" required label="账号">
<uni-easyinput v-model="user.username" placeholder="请输入账号" />
</uni-forms-item>
<uni-forms-item name="password" required label="密码">
<uni-easyinput type="password" v-model="user.password" placeholder="请输入密码" />
</uni-forms-item>
<uni-forms-item name="confirmPassword" required label="确认密码">
<uni-easyinput type="password" v-model="user.confirmPassword" placeholder="请确认密码" />
</uni-forms-item>
</uni-forms>
<view class="tips-card">
<view class="tips-header">
<uni-icons type="info" size="16" color="#667eea"></uni-icons>
<text class="tips-title">密码要求</text>
</view>
<view class="tips-list">
<view class="tip-item">
<text class="tip-dot"></text>
<text class="tip-text">账号长度为 6-20 个字符</text>
</view>
<view class="tip-item">
<text class="tip-dot"></text>
<text class="tip-text">密码长度为 6-20 个字符</text>
</view>
<view class="tip-item">
<text class="tip-dot"></text>
<text class="tip-text">两次密码输入必须一致</text>
</view>
</view>
</view>
<view class="action-btn">
<button class="register-btn" @click="handleRegister">
<text class="btn-text">立即注册</text>
</button>
</view>
</view>
</view>
<view class="footer-section">
<text class="copyright-text">Copyright © 2024 qdintc All Rights Reserved.</text>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import { register } from "@/api/login"
export default {
data() {
return {
user: {
username: '',
password: '',
resource: '1',
confirmPassword: '',
code: '',
uuid: ''
},
rules: {
username: {
rules: [{
required: true,
errorMessage: '账号不能为空',
},
{
minLength: 6,
maxLength: 20,
errorMessage: '账号长度在 6 到 20 个字符'
}
]
},
password: {
rules: [{
required: true,
errorMessage: '密码不能为空',
},
{
minLength: 6,
maxLength: 20,
errorMessage: '长度在 6 到 20 个字符'
}
]
},
confirmPassword: {
rules: [{
required: true,
errorMessage: '确认密码不能为空'
}, {
validateFunction: (rule, value, data) => data.password === value,
errorMessage: '两次输入的密码不一致'
}
]
}
}
}
},
onReady() {
this.$refs.form.setRules(this.rules)
},
methods: {
handleRegister() {
this.$refs.form.validate().then(res => {
register(this.user)
.then((res) => {
uni.showToast({
title: '注册成功,请登录',
icon: 'success',
duration: 2000
});
uni.navigateTo({ url: `/pages/login` })
})
})
}
}
}
</script>
<style lang="scss" scoped>
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100%;
height: auto;
}
.register-container {
width: 100%;
display: flex;
flex-direction: column;
position: relative;
.background-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at top right, rgba(255, 255, 255, 0.1) 0%, transparent 60%);
pointer-events: none;
}
.header-section {
padding: 100rpx 48rpx 60rpx;
position: relative;
z-index: 1;
.page-title {
display: block;
font-size: 48rpx;
font-weight: 700;
color: #ffffff;
margin-bottom: 12rpx;
}
.page-subtitle {
display: block;
font-size: 26rpx;
color: rgba(255, 255, 255, 0.8);
}
}
.form-section {
flex: 1;
padding: 0 48rpx 32rpx;
position: relative;
z-index: 1;
overflow-y: auto;
overflow-x: hidden;
min-height: 0;
/* 隐藏滚动条 */
&::-webkit-scrollbar {
display: none !important;
width: 0 !important;
height: 0 !important;
}
scrollbar-width: none !important;
-ms-overflow-style: none !important;
.form-card {
background: #ffffff;
border-radius: 32rpx;
padding: 48rpx 40rpx;
box-shadow: 0 16rpx 48rpx rgba(0, 0, 0, 0.15);
}
}
.tips-card {
background: linear-gradient(135deg, rgba(102, 126, 234, 0.08) 0%, rgba(118, 75, 162, 0.08) 100%);
border-radius: 20rpx;
padding: 24rpx;
margin-top: 32rpx;
border: 2rpx solid rgba(102, 126, 234, 0.2);
}
.tips-header {
display: flex;
align-items: center;
margin-bottom: 16rpx;
.tips-title {
color: #667eea;
font-size: 26rpx;
font-weight: 600;
margin-left: 8rpx;
}
}
.tips-list {
.tip-item {
display: flex;
align-items: flex-start;
margin-bottom: 8rpx;
&:last-child {
margin-bottom: 0;
}
.tip-dot {
color: #667eea;
font-size: 24rpx;
margin-right: 8rpx;
line-height: 36rpx;
}
.tip-text {
flex: 1;
color: #606266;
font-size: 24rpx;
line-height: 36rpx;
}
}
}
.action-btn {
margin-top: 48rpx;
.register-btn {
width: 100%;
height: 96rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 48rpx;
border: none;
box-shadow: 0 12rpx 32rpx rgba(102, 126, 234, 0.4);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&::after {
border: none;
}
&:active {
transform: scale(0.98);
box-shadow: 0 8rpx 24rpx rgba(102, 126, 234, 0.3);
}
.btn-text {
color: #ffffff;
font-size: 32rpx;
font-weight: 600;
}
}
}
.footer-section {
padding: 60rpx 48rpx 80rpx;
text-align: center;
position: relative;
z-index: 1;
.copyright-text {
color: rgba(255, 255, 255, 0.7);
font-size: 24rpx;
}
}
}
</style>

View File

@@ -0,0 +1,131 @@
export default [
{
groupName: 'geek组件',
groupName_en: 'Page',
list: [
{
path: '/pages_geek/pages/index/index',
icon: 'wxCenter',
title: '组件展示',
title_en: 'index',
},
{
path: '/pages_geek/pages/code/index',
icon: 'wxCenter',
title: '二维码',
title_en: 'index',
}
]
},
{
groupName: '部件',
groupName_en: 'Parts',
list: [
{
path: '/pages_template/pages/coupon/index',
icon: 'coupon',
title: 'Coupon 优惠券',
title_en: 'Coupon',
},
{
path: '/pages_template/pages/citySelect/index',
icon: 'citySelect',
title: 'CitySelect 城市选择',
title_en: 'CitySelect',
},
{
path: '/pages_template/pages/submitBar/index',
icon: 'submitBar',
title: 'SubmitBar 提交订单栏',
title_en: 'SubmitBar',
},
{
path: '/pages_template/pages/keyboardPay/index',
icon: 'keyboardPay',
title: 'KeyboardPay 自定义键盘支付模板',
title_en: 'KeyboardPay',
},
]
},
{
groupName: '报表',
groupName_en: 'Parts',
list: [
{
path: '/pages_qiun/pages/finance/index',
icon: 'coupon',
title: '财务报告',
title_en: 'finace',
},
{
path: '/pages_qiun/pages/main/index',
icon: 'coupon',
title: '数据报表中心',
title_en: 'main',
},
{
path: '/pages_qiun/pages/school/index',
icon: 'coupon',
title: '智慧教育报表中心',
title_en: 'school',
},
{
path: '/pages_qiun/pages/sport/index',
icon: 'coupon',
title: '运动报告',
title_en: 'sport',
},
]
},
{
groupName: '页面',
groupName_en: 'Page',
list: [
{
path: '/pages_template/pages/wxCenter/index',
icon: 'wxCenter',
title: 'WxCenter 仿微信个人中心',
title_en: 'WxCenter',
},
{
path: '/pages_template/pages/mallMenu/index1',
icon: 'mall_menu_1',
title: 'MallMenu 垂直分类(左右独立)',
title_en: 'MallMenu 1',
}, {
path: '/pages_template/pages/mallMenu/index2',
icon: 'mall_menu_2',
title: 'MallMenu 垂直分类(左右联动)',
title_en: 'MallMenu 2',
}, {
path: '/pages_template/pages/comment/index',
icon: 'comment',
title: 'Comment 评论列表',
title_en: 'Comment',
}, {
path: '/pages_template/pages/order/index',
icon: 'order',
title: 'Order 订单列表',
title_en: 'Order',
},
{
path: '/pages_template/pages/login/index1',
icon: 'login',
title: 'Login 登录界面',
title_en: 'Login',
},
{
path: '/pages_template/pages/login/index2',
icon: 'login',
title: 'Login 水滴登录',
title_en: 'Login',
},
{
path: '/pages_template/pages/address/index',
icon: 'address',
title: 'Address 收货地址',
title_en: 'Address',
},
]
},
]

65
src/pages/template.vue Normal file
View File

@@ -0,0 +1,65 @@
<template>
<view class="wrap">
<view class="list-wrap">
<u-cell-group title-bg-color="rgb(243, 244, 246)" :title="getGroupTitle(item)" v-for="(item, index) in list"
:key="index">
<u-cell :titleStyle="{ fontWeight: 500 }" @click="openPage(item1.path)" :title="getFieldTitle(item1)"
v-for="(item1, index1) in item.list" :key="index1">
<template v-slot:icon>
<image class="u-cell-icon" :src="getIcon(item1.icon)" mode="widthFix"></image>
</template>
</u-cell>
</u-cell-group>
</view>
<u-gap height="70"></u-gap>
<!-- <u-tabbar :list="vuex_tabbar" :mid-button="true"></u-tabbar> -->
</view>
</template>
<script>
import list from "./template.config.js";
export default {
data() {
return {
list: list,
// desc: '收集众多的常用页面和布局,减少开发者的重复工作,让你专注逻辑,事半功倍'
}
},
computed: {
getIcon() {
return path => {
return '../static/uview/demo/' + path + '.png';
return 'https://cdn.uviewui.com/uview/example/' + path + '.png';
}
},
},
methods: {
openPage(path) {
this.$u.route({
url: path
})
},
getGroupTitle(item) {
return item.groupName
},
getFieldTitle(item) {
return item.title
}
}
}
</script>
<style>
/* page {
background-color: rgb(240, 242, 244);
} */
</style>
<style lang="scss" scoped>
.u-cell-icon {
width: 36rpx;
height: 36rpx;
margin-right: 8rpx;
}
</style>