调整部分样式

This commit is contained in:
dftre 2025-08-22 16:22:00 +08:00
parent df252d049e
commit 2e05794a09
14 changed files with 1566 additions and 1613 deletions

View File

@ -1,90 +1,78 @@
# uni-app 二维码生成器 # uni-app 二维码生成器
改自作者诗小柒的tki-qrcode二维码生成器 改自作者诗小柒的tki-qrcode二维码生成器
### 作者:董玉可 ### 作者Dftre
1. H5、微信小程序、支付宝小程序、APP其它平台的小程序没有测试 1. H5、微信小程序、支付宝小程序、APP其它平台的小程序没有测试
2. 使用canvas生成 2. 使用canvas生成
3. 可设置二维码背景色,前景色,角标色 3. 可设置二维码背景色,前景色,角标色
4. 可设置二维码logo 4. 可设置二维码logo
## 重要的事情说3遍 重要的事情说3遍 重要的事情说3遍 ### 使用方法
1. IOS、Android真机都可以正常生成二维码 `template` 中使用
2. 使用的时候出现无法生成二维码或空白的请先github直接打包下载问题依旧请github上直接提出问题并配图
3. 有问题请说明问题原因,这样我才好定位,否则我也无法解决 ```javascript
4. 如果此插件有帮助到你请打5分或赞赏我你的支持是我更新的动力 <view class="qrimg">
<geek-qrcode
+ 图片1 是微信小程序真机实测 ref="qrcode"
+ 图片2 是微信小程序模拟实测 :cid="cid"
+ 图片3 是支付宝小程序模拟器实测 :val="val"
+ 图片4 是安卓真机实测 :size="size"
+ 图片5 H5 :unit="unit"
:background="background"
### 使用方法 :foreground="foreground"
:pdground="pdground"
`template` 中使用 :icon="icon"
:iconSize="iconsize"
```javascript :lv="lv"
<view class="qrimg"> :onval="onval"
<geek-qrcode :loadMake="loadMake"
ref="qrcode" :usingComponents="usingComponents"
:cid="cid" :showLoading="showLoading"
:val="val" :loadingText="loadingText"
:size="size" @result="qrR" />
:unit="unit" </view>
:background="background" ```
:foreground="foreground"
:pdground="pdground" ### 属性
:icon="icon"
:iconSize="iconsize" | 属性名 | 类型 | 默认值 | 可选值 | 说明 |
:lv="lv" | :-------------- | :-----: | :---------------: | :----: | :-------------------------------------------------------------------------------------------------- |
:onval="onval" | cid | String | tki-qrcode-canvas | | canvasId页面存在多个二维码组件时需设置不同的ID |
:loadMake="loadMake" | size | Number | 200 | | 生成的二维码大小 |
:usingComponents="usingComponents" | unit | String | upx | px | 大小单位尺寸 |
:showLoading="showLoading" | show | Boolean | true | | 默认使用组件中的image标签显示二维码 |
:loadingText="loadingText" | val | String | 二维码 | | 要生成的内容 |
@result="qrR" /> | background | String | #000000 | | 二维码背景色 |
</view> | foreground | String | #ffffff | | 二维码前景色 |
``` | pdground | String | #ffffff | | 二维码角标色 |
| icon | String | | | 二维码图标URL必须是本地图片网络图需要先下载至本地 |
### 属性 | iconSize | Number | 40 | | 二维码图标大小注意此大小不会跟随二维码size 动态变化,设置时需要注意大小,不要太大,以免无法识别) |
| lv | Number | 3 | | 容错级别(一般不用设置) |
| 属性名 | 类型 | 默认值 | 可选值 | 说明 | | onval | Boolean | false | | 监听val值变化自动重新生成二维码 |
| :-------------- | :-----: | :---------------: | :----: | :-------------------------------------------------------------------------------------------------- | | loadMake | Boolean | false | | 组件初始化完成后自动生成二维码val需要有值 |
| cid | String | tki-qrcode-canvas | | canvasId页面存在多个二维码组件时需设置不同的ID | | usingComponents | Boolean | true | false | 是否使用了自定义组件模式(主要是为了修复非自定义组件模式时 v-if 无法生成二维码的问题) |
| size | Number | 200 | | 生成的二维码大小 | | showLoading | Boolean | true | false | 是否显示loading |
| unit | String | upx | px | 大小单位尺寸 | | loadingText | String | 二维码生成中 | | loading文字 |
| show | Boolean | true | | 默认使用组件中的image标签显示二维码 |
| val | String | 二维码 | | 要生成的内容 | ### 方法
| background | String | #000000 | | 二维码背景色 |
| foreground | String | #ffffff | | 二维码前景色 | | 方法名 | 参数 | 默认值 | 说明 |
| pdground | String | #ffffff | | 二维码角标色 | | :----------- | :--: | :----: | :-------------------------------------------------- |
| icon | String | | | 二维码图标URL必须是本地图片网络图需要先下载至本地 | | _makeCode() | | | 生成二维码 |
| iconSize | Number | 40 | | 二维码图标大小注意此大小不会跟随二维码size 动态变化,设置时需要注意大小,不要太大,以免无法识别) | | _clearCode() | | | 清空二维码清空二维码会触发result回调 返回值为空) |
| lv | Number | 3 | | 容错级别(一般不用设置) | | _saveCode() | | | 保存二维码到图库 |
| onval | Boolean | false | | 监听val值变化自动重新生成二维码 |
| loadMake | Boolean | false | | 组件初始化完成后自动生成二维码val需要有值 | ### 事件
| usingComponents | Boolean | true | false | 是否使用了自定义组件模式(主要是为了修复非自定义组件模式时 v-if 无法生成二维码的问题) |
| showLoading | Boolean | true | false | 是否显示loading | | 事件名 | 返回值 | 说明 |
| loadingText | String | 二维码生成中 | | loading文字 | | :----- | :----------------------------: | --------------------------------------: |
| result | 生成的图片base64或图片临时地址 | 返回二维码路径 注_clearCode()后返回空 |
### 方法
### 感谢
| 方法名 | 参数 | 默认值 | 说明 |
| :----------- | :--: | :----: | :-------------------------------------------------- | [uni-app](https://uniapp.dcloud.io/ "uni-app")
| _makeCode() | | | 生成二维码 | [qrcode](https://github.com/aralejs/qrcode "qrcode")
| _clearCode() | | | 清空二维码清空二维码会触发result回调 返回值为空) | tki-qrcode
| _saveCode() | | | 保存二维码到图库 |
### 事件
| 事件名 | 返回值 | 说明 |
| :----- | :----------------------------: | --------------------------------------: |
| result | 生成的图片base64或图片临时地址 | 返回二维码路径 注_clearCode()后返回空 |
### 感谢
[uni-app](https://uniapp.dcloud.io/ "uni-app")
[qrcode](https://github.com/aralejs/qrcode "qrcode")

View File

@ -1,205 +1,205 @@
<template xlang="wxml" minapp="mpvue"> <template xlang="wxml" minapp="mpvue">
<view class="geek-qrcode"> <view class="geek-qrcode">
<canvas class="geek-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" /> <canvas class="geek-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" />
<image v-show="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" /> <image v-show="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
</view> </view>
</template> </template>
<script> <script>
import QRCode from "./qrcode.js" import QRCode from "./qrcode.js"
let qrcode let qrcode
export default { export default {
name: "geek-qrcode", name: "geek-qrcode",
props: { props: {
cid: { cid: {
type: String, type: String,
default: 'geek-qrcode-canvas' default: 'geek-qrcode-canvas'
}, },
size: { size: {
type: Number, type: Number,
default: 200 default: 200
}, },
unit: { unit: {
type: String, type: String,
default: 'upx' default: 'upx'
}, },
show: { show: {
type: Boolean, type: Boolean,
default: true default: true
}, },
val: { val: {
type: String, type: String,
default: '' default: ''
}, },
background: { background: {
type: String, type: String,
default: '#ffffff' default: '#ffffff'
}, },
foreground: { foreground: {
type: String, type: String,
default: '#000000' default: '#000000'
}, },
pdground: { pdground: {
type: String, type: String,
default: '#000000' default: '#000000'
}, },
icon: { icon: {
type: String, type: String,
default: '' default: ''
}, },
iconSize: { iconSize: {
type: Number, type: Number,
default: 40 default: 40
}, },
lv: { lv: {
type: Number, type: Number,
default: 3 default: 3
}, },
onval: { onval: {
type: Boolean, type: Boolean,
default: false default: false
}, },
loadMake: { loadMake: {
type: Boolean, type: Boolean,
default: false default: false
}, },
usingComponents: { usingComponents: {
type: Boolean, type: Boolean,
default: true default: true
}, },
showLoading: { showLoading: {
type: Boolean, type: Boolean,
default: true default: true
}, },
loadingText: { loadingText: {
type: String, type: String,
default: '二维码生成中' default: '二维码生成中'
}, },
}, },
data() { data() {
return { return {
result: '', result: '',
} }
}, },
methods: { methods: {
_makeCode() { _makeCode() {
let that = this let that = this
if (!this._empty(this.val)) { if (!this._empty(this.val)) {
qrcode = new QRCode({ qrcode = new QRCode({
context: that, // context: that, //
canvasId:that.cid, // canvas-id canvasId:that.cid, // canvas-id
usingComponents: that.usingComponents, // usingComponents: that.usingComponents, //
showLoading: that.showLoading, // loading showLoading: that.showLoading, // loading
loadingText: that.loadingText, // loading loadingText: that.loadingText, // loading
text: that.val, // text: that.val, //
size: that.cpSize, // size: that.cpSize, //
background: that.background, // background: that.background, //
foreground: that.foreground, // foreground: that.foreground, //
pdground: that.pdground, // pdground: that.pdground, //
correctLevel: that.lv, // correctLevel: that.lv, //
image: that.icon, // image: that.icon, //
imageSize: that.iconSize,// imageSize: that.iconSize,//
cbResult: function (res) { // cbResult: function (res) { //
that._result(res) that._result(res)
}, },
}); });
} else { } else {
uni.showToast({ uni.showToast({
title: '二维码内容不能为空', title: '二维码内容不能为空',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000
}); });
} }
}, },
_clearCode() { _clearCode() {
this._result('') this._result('')
qrcode.clear() qrcode.clear()
}, },
_saveCode() { _saveCode() {
let that = this; let that = this;
if (this.result != "") { if (this.result != "") {
uni.saveImageToPhotosAlbum({ uni.saveImageToPhotosAlbum({
filePath: that.result, filePath: that.result,
success: function () { success: function () {
uni.showToast({ uni.showToast({
title: '二维码保存成功', title: '二维码保存成功',
icon: 'success', icon: 'success',
duration: 2000 duration: 2000
}); });
} }
}); });
} }
}, },
_result(res) { _result(res) {
this.result = res; this.result = res;
this.$emit('result', res) this.$emit('result', res)
}, },
_empty(v) { _empty(v) {
let tp = typeof v, let tp = typeof v,
rt = false; rt = false;
if (tp == "number" && String(v) == "") { if (tp == "number" && String(v) == "") {
rt = true rt = true
} else if (tp == "undefined") { } else if (tp == "undefined") {
rt = true rt = true
} else if (tp == "object") { } else if (tp == "object") {
if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
} else if (tp == "string") { } else if (tp == "string") {
if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
} else if (tp == "function") { } else if (tp == "function") {
rt = false rt = false
} }
return rt return rt
} }
}, },
watch: { watch: {
size: function (n, o) { size: function (n, o) {
if (n != o && !this._empty(n)) { if (n != o && !this._empty(n)) {
this.cSize = n this.cSize = n
if (!this._empty(this.val)) { if (!this._empty(this.val)) {
setTimeout(() => { setTimeout(() => {
this._makeCode() this._makeCode()
}, 100); }, 100);
} }
} }
}, },
val: function (n, o) { val: function (n, o) {
if (this.onval) { if (this.onval) {
if (n != o && !this._empty(n)) { if (n != o && !this._empty(n)) {
setTimeout(() => { setTimeout(() => {
this._makeCode() this._makeCode()
}, 0); }, 0);
} }
} }
} }
}, },
computed: { computed: {
cpSize() { cpSize() {
if(this.unit == "upx"){ if(this.unit == "upx"){
return uni.upx2px(this.size) return uni.upx2px(this.size)
}else{ }else{
return this.size return this.size
} }
} }
}, },
mounted: function () { mounted: function () {
if (this.loadMake) { if (this.loadMake) {
if (!this._empty(this.val)) { if (!this._empty(this.val)) {
setTimeout(() => { setTimeout(() => {
this._makeCode() this._makeCode()
}, 0); }, 0);
} }
} }
}, },
} }
</script> </script>
<style> <style>
.geek-qrcode { .geek-qrcode {
position: relative; position: relative;
} }
.geek-qrcode-canvas { .geek-qrcode-canvas {
position: fixed; position: fixed;
top: -99999upx; top: -99999upx;
left: -99999upx; left: -99999upx;
z-index: -99999; z-index: -99999;
} }
</style> </style>

View File

@ -1,75 +1,73 @@
<template> <script setup>
<view class="content"> import { ref, onMounted } from 'vue';
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area"> const chartData = ref({});
<text class="title"> RuoYi-Geek-App</text>
</view> onMounted(() => { getServerData() });
<view class="text-area">
<up-text type="primary" text="uview-plus"></up-text> function getServerData() {
</view> //
<view class="charts-box"> setTimeout(() => {
<qiun-data-charts type="column" :chartData="chartData" /> let res = {
</view> categories: ['2016', '2017', '2018', '2019', '2020', '2021'],
</view> series: [
</template> {
name: '目标值',
<script setup> data: [35, 36, 31, 33, 13, 34],
import { ref, onMounted } from 'vue'; },
{
const chartData = ref({}); name: '完成量',
data: [18, 27, 21, 24, 6, 28],
onMounted(() => { getServerData() }); },
],
function getServerData() { };
// chartData.value = JSON.parse(JSON.stringify(res));
setTimeout(() => { }, 500);
let res = { }
categories: ['2016', '2017', '2018', '2019', '2020', '2021'], </script>
series: [ <template>
{ <view class="content">
name: '目标值', <image class="logo" src="@/static/logo.png"></image>
data: [35, 36, 31, 33, 13, 34], <view class="text-area">
}, <text class="title"> RuoYi-Geek-App</text>
{ </view>
name: '完成量', <view class="text-area">
data: [18, 27, 21, 24, 6, 28], <up-text type="primary" text="uview-plus"></up-text>
}, </view>
], <view class="charts-box">
}; <qiun-data-charts type="column" :chartData="chartData" />
chartData.value = JSON.parse(JSON.stringify(res)); </view>
}, 500); </view>
} </template>
</script> <style scoped lang="scss">
.content {
<style scoped> display: flex;
.content { flex-direction: column;
display: flex; align-items: center;
flex-direction: column; justify-content: center;
align-items: center; }
justify-content: center;
} .logo {
height: 200rpx;
.logo { width: 200rpx;
height: 200rpx; margin-top: 200rpx;
width: 200rpx; margin-left: auto;
margin-top: 200rpx; margin-right: auto;
margin-left: auto; margin-bottom: 50rpx;
margin-right: auto; }
margin-bottom: 50rpx;
} .text-area {
display: flex;
.text-area { justify-content: center;
display: flex; }
justify-content: center;
} .title {
font-size: 36rpx;
.title { color: #8f8f94;
font-size: 36rpx; }
color: #8f8f94;
} .charts-box {
width: 100%;
.charts-box { height: 300px;
width: 100%; }
height: 300px; </style>
}
</style>

View File

@ -1,208 +1,206 @@
<template> <script setup>
<view class="normal-login-container"> import modal from '@/plugins/modal'
<view class="logo-content align-center justify-center flex"> import { getCodeImg } from '@/api/login'
<image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix"> import { ref } from "vue";
</image> import config from '@/config.js'
<text class="title">若依移动端登录</text> import useUserStore from '@/store/modules/user'
</view> import { getWxCode } from '@/utils/geek';
<view class="login-form-content"> import { wxLogin } from '@/api/oauth';
<view class="input-item flex align-center"> import { setToken } from '@/utils/auth';
<view class="iconfont icon-user icon"></view> const userStore = useUserStore()
<input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" /> const codeUrl = ref("");
</view> const captchaEnabled = ref(true); //
<view class="input-item flex align-center"> const useWxLogin = ref(false); // 使
<view class="iconfont icon-password icon"></view> const globalConfig = ref(config);
<input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" /> const loginForm = ref({
</view> username: "admin",
<view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled"> password: "admin123",
<view class="iconfont icon-code icon"></view> code: "",
<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" /> uuid: ''
<view class="login-code"> });
<image :src="codeUrl" @click="getCode" class="login-code-img"></image>
</view> if (useWxLogin.value) {
</view> getWxCode().then(res => {
<view class="action-btn"> console.log(res);
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button> wxLogin('miniapp', res).then(res => {
</view> if (res.token != null) {
</view> setToken(res.token);
loginSuccess()
<view class="xieyi text-center"> }
<text class="text-grey1">登录即代表同意</text> });
<text @click="handleUserAgrement" class="text-blue">用户协议</text> })
<text @click="handlePrivacy" class="text-blue">隐私协议</text> }
</view>
</view>
</template> //
function getCode() {
<script setup> getCodeImg().then(res => {
import modal from '@/plugins/modal' captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
import { getCodeImg } from '@/api/login' if (captchaEnabled.value) {
import { ref } from "vue"; codeUrl.value = 'data:image/gif;base64,' + res.img
import config from '@/config.js' loginForm.value.uuid = res.uuid
import useUserStore from '@/store/modules/user' }
import { getWxCode } from '@/utils/geek'; })
import { wxLogin } from '@/api/oauth'; };
import { setToken } from '@/utils/auth';
const userStore = useUserStore() async function handleLogin() {
const codeUrl = ref(""); if (loginForm.value.username === "") {
const captchaEnabled = ref(true); // modal.msgError("请输入您的账号")
const useWxLogin = ref(false); // 使 } else if (loginForm.value.password === "") {
const globalConfig = ref(config); modal.msgError("请输入您的密码")
const loginForm = ref({ } else if (loginForm.value.code === "" && captchaEnabled.value) {
username: "admin", modal.msgError("请输入验证码")
password: "admin123", } else {
code: "", modal.loading("登录中,请耐心等待...")
uuid: '' pwdLogin()
}); }
};
if (useWxLogin.value) { //
getWxCode().then(res => { async function pwdLogin() {
console.log(res); userStore.login(loginForm.value).then(() => {
wxLogin('miniapp',res).then(res => { modal.closeLoading()
if(res.token != null){ loginSuccess()
setToken(res.token); }).catch(() => {
loginSuccess() if (captchaEnabled.value) {
} modal.closeLoading()
}); getCode()
}) }
} })
};
// function loginSuccess(result) {
function getCode() { //
getCodeImg().then(res => { userStore.getInfo().then(res => {
captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled uni.switchTab({
if (captchaEnabled.value) { url: '/pages/index'
codeUrl.value = 'data:image/gif;base64,' + res.img });
loginForm.value.uuid = res.uuid })
} }
})
}; //
function handlePrivacy() {
async function handleLogin() { let site = globalConfig.value.appInfo.agreements[0];
if (loginForm.value.username === "") { uni.navigateTo({
modal.msgError("请输入您的账号") url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
} else if (loginForm.value.password === "") { });
modal.msgError("请输入您的密码") };
} else if (loginForm.value.code === "" && captchaEnabled.value) { //
modal.msgError("请输入验证码") function handleUserAgrement() {
} else { let site = globalConfig.value.appInfo.agreements[1]
modal.loading("登录中,请耐心等待...") uni.navigateTo({
pwdLogin() url: `/pages/common/webview/index?title=${site.title}&url=${site.url}`
} });
}; };
//
async function pwdLogin() { getCode();
userStore.login(loginForm.value).then(() => { </script>
modal.closeLoading() <template>
loginSuccess() <view class="normal-login-container">
}).catch(() => { <view class="logo-content align-center justify-center flex">
if (captchaEnabled.value) { <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
modal.closeLoading() </image>
getCode() <text class="title">若依移动端登录</text>
} </view>
}) <view class="login-form-content">
}; <view class="input-item flex align-center">
<view class="iconfont icon-user icon"></view>
function loginSuccess(result) { <input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
// </view>
userStore.getInfo().then(res => { <view class="input-item flex align-center">
uni.switchTab({ <view class="iconfont icon-password icon"></view>
url: '/pages/index' <input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
}); </view>
}) <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
} <view class="iconfont icon-code icon"></view>
<input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
// <view class="login-code">
function handlePrivacy() { <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
let site = globalConfig.value.appInfo.agreements[0]; </view>
uni.navigateTo({ </view>
url: `/pages/common/webview/index?title=${site.title}&url=${site.url}` <view class="action-btn">
}); <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
}; </view>
// </view>
function handleUserAgrement() {
let site = globalConfig.value.appInfo.agreements[1] <view class="xieyi text-center">
uni.navigateTo({ <text class="text-grey1">登录即代表同意</text>
url: `/pages/common/webview/index?title=${site.title}&url=${site.url}` <text @click="handleUserAgrement" class="text-blue">用户协议</text>
}); <text @click="handlePrivacy" class="text-blue">隐私协议</text>
}; </view>
</view>
getCode(); </template>
</script> <style lang="scss" scoped>
page {
<style lang="scss"> background-color: #ffffff;
page { }
background-color: #ffffff;
} .normal-login-container {
width: 100%;
.normal-login-container {
width: 100%; .logo-content {
width: 100%;
.logo-content { font-size: 21px;
width: 100%; text-align: center;
font-size: 21px; padding-top: 15%;
text-align: center;
padding-top: 15%; image {
border-radius: 4px;
image { }
border-radius: 4px;
} .title {
margin-left: 10px;
.title { }
margin-left: 10px; }
}
} .login-form-content {
text-align: center;
.login-form-content { margin: 20px auto;
text-align: center; margin-top: 15%;
margin: 20px auto; width: 80%;
margin-top: 15%;
width: 80%; .input-item {
margin: 20px auto;
.input-item { background-color: #f5f6f7;
margin: 20px auto; height: 45px;
background-color: #f5f6f7; border-radius: 20px;
height: 45px;
border-radius: 20px; .icon {
font-size: 38rpx;
.icon { margin-left: 10px;
font-size: 38rpx; color: #999;
margin-left: 10px; }
color: #999;
} .input {
width: 100%;
.input { font-size: 14px;
width: 100%; line-height: 20px;
font-size: 14px; text-align: left;
line-height: 20px; padding-left: 15px;
text-align: left; }
padding-left: 15px;
} }
} .login-btn {
margin-top: 40px;
.login-btn { height: 45px;
margin-top: 40px; }
height: 45px;
} .xieyi {
color: #333;
.xieyi { margin-top: 20px;
color: #333; }
margin-top: 20px;
} .login-code {
height: 38px;
.login-code { float: right;
height: 38px;
float: right; .login-code-img {
height: 38px;
.login-code-img { position: absolute;
height: 38px; margin-left: 10px;
position: absolute; width: 200rpx;
margin-left: 10px; }
width: 200rpx; }
} }
} }
} </style>
}
</style>

View File

@ -1,97 +1,8 @@
<template>
<view class="mine-container" :style="{ height: `${windowHeight}px` }">
<!--顶部个人信息栏-->
<view class="header-section">
<view class="flex padding justify-between">
<view class="flex align-center">
<view v-if="!avatar" class="cu-avatar xl round bg-white">
<view class="iconfont icon-people text-gray icon"></view>
</view>
<image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
</image>
<view v-if="!name" @click="handleToLogin" class="login-tip">
点击登录
</view>
<view v-if="name" @click="handleToInfo" class="user-info">
<view class="u_title">
用户名{{ name }}
</view>
</view>
</view>
<view @click="handleToInfo" class="flex align-center">
<text>个人信息</text>
<view class="iconfont icon-right"></view>
</view>
</view>
</view>
<view class="content-section">
<view class="mine-actions grid col-4 text-center">
<view class="action-item" @click="handleJiaoLiuQun">
<view class="iconfont icon-friendfill text-pink icon"></view>
<text class="text">交流群</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-service text-blue icon"></view>
<text class="text">在线客服</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-community text-mauve icon"></view>
<text class="text">反馈社区</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-dianzan text-green icon"></view>
<text class="text">点赞我们</text>
</view>
</view>
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToEditInfo">
<view class="menu-item-box">
<view class="iconfont icon-user menu-icon"></view>
<view>编辑资料</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleHelp">
<view class="menu-item-box">
<view class="iconfont icon-help menu-icon"></view>
<view>常见问题</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleAbout">
<view class="menu-item-box">
<view class="iconfont icon-aixin menu-icon"></view>
<view>关于我们</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToSetting">
<view class="menu-item-box">
<view class="iconfont icon-setting menu-icon"></view>
<view>应用设置</view>
</view>
</view>
</view>
</view>
</view>
<!-- <view>
<uni-popup ref="popup" type="dialog">
<uni-popup-dialog type="info" cancelText="关闭" confirmText="退出"
title="通知" content="确定注销并退出系统吗"
@confirm="dialogConfirm"
@close="dialogClose">
</uni-popup-dialog>
</uni-popup>
</view> -->
</template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import config from '@/config.js'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
const userStore = useUserStore() const userStore = useUserStore()
const name = userStore.name; const name = userStore.name;
const version = config.appInfo.version;
const avatar = ref(userStore.avatar); const avatar = ref(userStore.avatar);
const windowHeight = ref(uni.getSystemInfoSync().windowHeight - 50); const windowHeight = ref(uni.getSystemInfoSync().windowHeight - 50);
@ -169,8 +80,83 @@ function handleBuilding() {
} }
</script> </script>
<template>
<view class="mine-container" :style="{ height: `${windowHeight}px` }">
<!--顶部个人信息栏-->
<view class="header-section">
<view class="flex padding justify-between">
<view class="flex align-center">
<view v-if="!avatar" class="cu-avatar xl round bg-white">
<view class="iconfont icon-people text-gray icon"></view>
</view>
<image v-if="avatar" @click="handleToAvatar" :src="avatar" class="cu-avatar xl round" mode="widthFix">
</image>
<view v-if="!name" @click="handleToLogin" class="login-tip">
点击登录
</view>
<view v-if="name" @click="handleToInfo" class="user-info">
<view class="u_title">
用户名{{ name }}
</view>
</view>
</view>
<view @click="handleToInfo" class="flex align-center">
<text>个人信息</text>
<view class="iconfont icon-right"></view>
</view>
</view>
</view>
<style lang="scss"> <view class="content-section">
<view class="mine-actions grid col-4 text-center">
<view class="action-item" @click="handleJiaoLiuQun">
<view class="iconfont icon-friendfill text-pink icon"></view>
<text class="text">交流群</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-service text-blue icon"></view>
<text class="text">在线客服</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-community text-mauve icon"></view>
<text class="text">反馈社区</text>
</view>
<view class="action-item" @click="handleBuilding">
<view class="iconfont icon-dianzan text-green icon"></view>
<text class="text">点赞我们</text>
</view>
</view>
<view class="menu-list">
<view class="list-cell list-cell-arrow" @click="handleToEditInfo">
<view class="menu-item-box">
<view class="iconfont icon-user menu-icon"></view>
<view>编辑资料</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleHelp">
<view class="menu-item-box">
<view class="iconfont icon-help menu-icon"></view>
<view>常见问题</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleAbout">
<view class="menu-item-box">
<view class="iconfont icon-aixin menu-icon"></view>
<view>关于我们</view>
</view>
</view>
<view class="list-cell list-cell-arrow" @click="handleToSetting">
<view class="menu-item-box">
<view class="iconfont icon-setting menu-icon"></view>
<view>应用设置</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
page { page {
background-color: #f5f6f7; background-color: #f5f6f7;
} }

View File

@ -1,65 +1,48 @@
<template> <script setup lang="ts">
<view class="wrap"> import tab from "@/plugins/tab";
<view class="list-wrap"> import list from "./template.config.js";
<u-cell-group title-bg-color="rgb(243, 244, 246)" :title="getGroupTitle(item)" v-for="(item, index) in list"
:key="index"> interface ListItem {
<u-cell :titleStyle="{ fontWeight: 500 }" @click="openPage(item1.path)" :title="getFieldTitle(item1)" groupName: string;
v-for="(item1, index1) in item.list" :key="index1"> list: FieldItem[];
<template v-slot:icon> }
<image class="u-cell-icon" :src="getIcon(item1.icon)" mode="widthFix"></image>
</template> interface FieldItem {
</u-cell> title: string;
</u-cell-group> icon: string;
</view> path: string;
<u-gap height="70"></u-gap> }
<!-- <u-tabbar :list="vuex_tabbar" :mid-button="true"></u-tabbar> -->
</view> const listData = list as ListItem[];
</template> const getIcon = (path: string) => `../static/uview/demo/${path}.png`;
const openPage = (path: string) => tab.navigateTo(path)
<script> const getGroupTitle = (item: ListItem) => item.groupName;
import list from "./template.config.js"; const getFieldTitle = (item: FieldItem) => item.title;
export default { </script>
data() { <template>
return { <view class="wrap">
list: list, <view class="list-wrap">
// desc: '' <u-cell-group title-bg-color="rgb(243, 244, 246)" :title="getGroupTitle(item)" v-for="(item, index) in listData"
} :key="index">
}, <u-cell :titleStyle="{ fontWeight: 500 }" @click="openPage(item1.path)" :title="getFieldTitle(item1)"
computed: { v-for="(item1, index1) in item.list" :key="index1">
getIcon() { <template v-slot:icon>
return path => { <image class="u-cell-icon" :src="getIcon(item1.icon)" mode="widthFix"></image>
return '../static/uview/demo/' + path + '.png'; </template>
return 'https://cdn.uviewui.com/uview/example/' + path + '.png'; </u-cell>
} </u-cell-group>
}, </view>
}, <u-gap height="70"></u-gap>
methods: { </view>
openPage(path) { </template>
this.$u.route({ <style lang="scss" scoped>
url: path page {
}) background-color: rgb(240, 242, 244);
}, }
getGroupTitle(item) {
return item.groupName .u-cell-icon {
}, width: 36rpx;
getFieldTitle(item) { height: 36rpx;
return item.title margin-right: 8rpx;
} }
} </style>
}
</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>

View File

@ -1,184 +1,179 @@
<template> <template>
<view class="work-container"> <view class="work-container">
<!-- 轮播图 --> <!-- 轮播图 -->
<uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content"> <uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
<swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper"> <swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
<swiper-item v-for="(item, index) in data" :key="index"> <swiper-item v-for="(item, index) in data" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)"> <view class="swiper-item" @click="clickBannerItem(item)">
<image :src="item.image" mode="aspectFill" :draggable="false" /> <image :src="item.image" mode="aspectFill" :draggable="false" />
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
</uni-swiper-dot> </uni-swiper-dot>
<!-- 宫格组件 --> <!-- 宫格组件 -->
<uni-section title="系统管理" type="line"></uni-section> <uni-section title="系统管理" type="line"></uni-section>
<view class="grid-body"> <view class="grid-body">
<uni-grid :column="4" :showBorder="false" @change="changeGrid"> <uni-grid :column="4" :showBorder="false" @change="changeGrid">
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="person-filled" size="30"></uni-icons> <uni-icons type="person-filled" size="30"></uni-icons>
<text class="text">用户管理</text> <text class="text">用户管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="staff-filled" size="30"></uni-icons> <uni-icons type="staff-filled" size="30"></uni-icons>
<text class="text">角色管理</text> <text class="text">角色管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="color" size="30"></uni-icons> <uni-icons type="color" size="30"></uni-icons>
<text class="text">菜单管理</text> <text class="text">菜单管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="settings-filled" size="30"></uni-icons> <uni-icons type="settings-filled" size="30"></uni-icons>
<text class="text">部门管理</text> <text class="text">部门管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="heart-filled" size="30"></uni-icons> <uni-icons type="heart-filled" size="30"></uni-icons>
<text class="text">岗位管理</text> <text class="text">岗位管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="bars" size="30"></uni-icons> <uni-icons type="bars" size="30"></uni-icons>
<text class="text">字典管理</text> <text class="text">字典管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="gear-filled" size="30"></uni-icons> <uni-icons type="gear-filled" size="30"></uni-icons>
<text class="text">参数设置</text> <text class="text">参数设置</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="chat-filled" size="30"></uni-icons> <uni-icons type="chat-filled" size="30"></uni-icons>
<text class="text">通知公告</text> <text class="text">通知公告</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
<uni-grid-item> <uni-grid-item>
<view class="grid-item-box"> <view class="grid-item-box">
<uni-icons type="wallet-filled" size="30"></uni-icons> <uni-icons type="wallet-filled" size="30"></uni-icons>
<text class="text">日志管理</text> <text class="text">日志管理</text>
</view> </view>
</uni-grid-item> </uni-grid-item>
</uni-grid> </uni-grid>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import modal from "@/plugins/modal" import modal from "@/plugins/modal"
const current=ref(0); const current = ref(0);
const swiperDotIndex=ref(0); const swiperDotIndex = ref(0);
const data=ref([{ const data = ref([
image: '/static/images/banner/banner01.jpg' { image: '/static/images/banner/banner01.jpg' },
}, { image: '/static/images/banner/banner02.jpg' },
{ { image: '/static/images/banner/banner03.jpg' }
image: '/static/images/banner/banner02.jpg' ]);
},
{ function clickBannerItem(item) {
image: '/static/images/banner/banner03.jpg' console.info(item)
} };
]); function changeSwiper(e) {
current.value = e.detail.current
function clickBannerItem(item) { }
console.info(item) function changeGrid(e) {
}; modal.showToast({
function changeSwiper(e) { title: '模块建设中',
current.value = e.detail.current mask: false,
} icon: 'loading',
function changeGrid(e) { duration: 1000
modal.showToast({ });
title: '模块建设中', }
mask: false,
icon:'loading', </script>
duration: 1000
}); <style lang="scss">
} /* #ifndef APP-NVUE */
page {
</script> display: flex;
flex-direction: column;
<style lang="scss"> box-sizing: border-box;
/* #ifndef APP-NVUE */ background-color: #fff;
page { min-height: 100%;
display: flex; height: auto;
flex-direction: column; }
box-sizing: border-box;
background-color: #fff; view {
min-height: 100%; font-size: 14px;
height: auto; line-height: inherit;
} }
view { /* #endif */
font-size: 14px;
line-height: inherit; .text {
} text-align: center;
font-size: 26rpx;
/* #endif */ margin-top: 10rpx;
}
.text {
text-align: center; .grid-item-box {
font-size: 26rpx; flex: 1;
margin-top: 10rpx; /* #ifndef APP-NVUE */
} display: flex;
/* #endif */
.grid-item-box { flex-direction: column;
flex: 1; align-items: center;
/* #ifndef APP-NVUE */ justify-content: center;
display: flex; padding: 15px 0;
/* #endif */ }
flex-direction: column;
align-items: center; .uni-margin-wrap {
justify-content: center; width: 690rpx;
padding: 15px 0; width: 100%;
} ;
}
.uni-margin-wrap {
width: 690rpx; .swiper {
width: 100%; height: 300rpx;
; }
}
.swiper-box {
.swiper { height: 150px;
height: 300rpx; }
}
.swiper-item {
.swiper-box { /* #ifndef APP-NVUE */
height: 150px; display: flex;
} /* #endif */
flex-direction: column;
.swiper-item { justify-content: center;
/* #ifndef APP-NVUE */ align-items: center;
display: flex; color: #fff;
/* #endif */ height: 300rpx;
flex-direction: column; line-height: 300rpx;
justify-content: center; }
align-items: center;
color: #fff; @media screen and (min-width: 500px) {
height: 300rpx; .uni-swiper-dot-box {
line-height: 300rpx; width: 400px;
} /* #ifndef APP-NVUE */
margin: 0 auto;
@media screen and (min-width: 500px) { /* #endif */
.uni-swiper-dot-box { margin-top: 8px;
width: 400px; }
/* #ifndef APP-NVUE */
margin: 0 auto; .image {
/* #endif */ width: 100%;
margin-top: 8px; }
} }
</style>
.image {
width: 100%;
}
}
</style>

View File

@ -0,0 +1,136 @@
<template>
<view class="jingdong">
<view class="left">
<view class="sum">
<text class="num">100</text>
</view>
<view class="type">满149元可用</view>
</view>
<view class="right">
<view class="top">
<view class="title">
<text class="tag">限品类东券</text>
<text>仅可购买个人护理部分商品</text>
</view>
<view class="bottom">
<view class="date u-line-1">2020.01.01-2020.01.31</view>
<view class="immediate-use">立即使用</view>
</view>
</view>
<view class="tips">
<view class="explain">
<u-icon name="zhuanfa" class="transpond" :size="24"></u-icon>
<text>可赠送</text>
</view>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.jingdong {
margin-top: 40rpx;
width: 700rpx;
height: auto;
background-color: #ffffff;
display: flex;
.left {
padding: 0 30rpx;
background-color: rgb(95, 148, 224); //rgb(94, 152, 225);
text-align: center;
font-size: 28rpx;
color: #ffffff;
.sum {
margin-top: 50rpx;
font-weight: bold;
font-size: 32rpx;
.num {
font-size: 80rpx;
}
}
.type {
margin-bottom: 50rpx;
font-size: 24rpx;
}
}
.right {
padding: 20rpx 20rpx 0;
font-size: 28rpx;
.top {
border-bottom: 2rpx dashed $u-border-color;
.title {
margin-right: 60rpx;
line-height: 40rpx;
.tag {
padding: 4rpx 20rpx;
background-color: rgb(73, 154, 201);
border-radius: 20rpx;
color: #ffffff;
font-weight: bold;
font-size: 24rpx;
margin-right: 10rpx;
}
}
.bottom {
display: flex;
margin-top: 20rpx;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
.date {
font-size: 20rpx;
flex: 1;
}
.immediate-use {
height: auto;
padding: 0 20rpx;
font-size: 24rpx;
border-radius: 40rpx;
line-height: 40rpx;
color: rgb(117, 142, 165);
border: 2rpx solid rgb(117, 142, 165);
}
}
}
.tips {
width: 100%;
line-height: 50rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24rpx;
.transpond {
margin-right: 10rpx;
}
.explain {
display: flex;
align-items: center;
}
.particulars {
width: 30rpx;
height: 30rpx;
box-sizing: border-box;
padding-top: 8rpx;
border-radius: 50%;
background-color: $u-info-disabled;
text-align: center;
}
}
}
}
</style>

View File

@ -0,0 +1,127 @@
<template>
<view class="meituan">
<view class="content">
<view class="left">
<view class="sum">
<text class="num">8</text>
</view>
<view class="type">抵用券</view>
</view>
<view class="centre">
<view class="title">洗牙8元无门槛红包</view>
<view class="valid-date">今日到期</view>
</view>
<view class="right">
<view size="mini" class="immediate-use" :round="true">立即使用</view>
</view>
</view>
<view class="tips">
<view class="circle-left"></view>
<view class="circle-right"></view>
<view class="explain u-line-1">满8.1元可用限最新版本客户端使用</view>
<view class="rule">
<text>使用规则</text>
<u-icon name="arrow-right" color="" :size="20" @click=""></u-icon>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.meituan {
margin: 30rpx auto;
background-color: #ffffff;
width: 700rpx;
// border: 10rpx;
color: $u-warning;
font-size: 28rpx;
.content {
display: flex;
align-items: center;
padding: 80rpx 20rpx;
border: 10rpx;
background-color: #fff5f4;
.left {
.sum {
font-size: 32rpx;
.num {
font-size: 60rpx;
font-weight: bold;
}
}
}
.centre {
margin-left: 40rpx;
.title {
font-size: 32rpx;
font-weight: bold;
color: $u-main-color;
margin-bottom: 20rpx;
}
}
.right {
margin-left: 30rpx;
.immediate-use {
padding: 0 20rpx;
height: 50rpx;
border-radius: 25rpx;
line-height: 50rpx;
background-color: $u-warning !important;
color: #ffffff !important;
font-size: 24rpx;
border: none;
word-break: keep-all;
}
}
}
.tips {
padding: 0 20rpx;
border: 10rpx;
background-color: $u-info-light;
position: relative;
color: $u-tips-color;
display: flex;
justify-content: space-between;
line-height: 60rpx;
font-size: 24rpx;
.circle-left,
.circle-right {
position: absolute;
height: 36rpx;
width: 18rpx;
background-color: #f2f2f2;
}
.circle-right {
border-radius: 40rpx 0 0 40rpx;
right: 0;
top: -18rpx;
}
.circle-left {
border-radius: 0 40rpx 40rpx 0;
left: 0;
top: -18rpx;
}
.rule {
font-size: 24rpx;
display: flex;
align-items: center;
text {
margin-right: 10rpx;
flex: 1;
}
}
}
}
</style>

View File

@ -0,0 +1,140 @@
<script setup lang="ts">
import logo from '@/static/logo.png';
</script>
<template>
<view class="taobao">
<view class="title">
<view class="left">
<image class="buddha" :src="logo" mode="aspectFill"></image>
<view class="store">袜子精保护协会</view>
</view>
<view class="entrance">进店</view>
</view>
<view class="ticket">
<view class="left">
<image class="picture" :src="logo" mode="widthFix"></image>
<view class="introduce">
<view class="top">
<text class="big">3</text>
满88减3
</view>
<view class="type">店铺优惠券</view>
<view class="date u-line-1">2019.11.28-2020.1.24</view>
</view>
</view>
<view class="right">
<view class="use immediate-use" :round="true">去使用</view>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.taobao {
margin-top: 40rpx;
width: 700rpx;
background-color: white;
padding: 30rpx 20rpx 20rpx;
border-radius: 20rpx;
.title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
font-size: 30rpx;
.left {
display: flex;
align-items: center;
}
.store {
font-weight: 500;
}
.buddha {
width: 70rpx;
height: 70rpx;
border-radius: 10rpx;
margin-right: 10rpx;
}
.entrance {
color: $u-info;
border: solid 2rpx $u-info;
line-height: 48rpx;
padding: 0 30rpx;
background: none;
border-radius: 15px;
}
}
.ticket {
display: flex;
.left {
width: 70%;
padding: 30rpx 20rpx;
background-color: rgb(255, 245, 244);
border-radius: 20rpx;
border-right: dashed 2rpx rgb(224, 215, 211);
display: flex;
.picture {
width: 172rpx;
height: 172rpx;
border-radius: 20rpx;
}
.introduce {
margin-left: 10rpx;
.top {
color: $u-warning;
font-size: 28rpx;
.big {
font-size: 60rpx;
font-weight: bold;
margin-right: 10rpx;
}
}
.type {
font-size: 28rpx;
color: $u-info-dark;
}
.date {
margin-top: 10rpx;
font-size: 20rpx;
color: $u-info-dark;
}
}
}
.right {
width: 30%;
padding: 40rpx 20rpx;
background-color: rgb(255, 245, 244);
border-radius: 20rpx;
display: flex;
align-items: center;
.use {
height: auto;
padding: 0 20rpx;
font-size: 24rpx;
border-radius: 40rpx;
color: #ffffff !important;
background-color: $u-warning !important;
line-height: 40rpx;
color: rgb(117, 142, 165);
margin-left: 20rpx;
}
}
}
}
</style>

View File

@ -1,413 +1,23 @@
<script setup> <script setup>
</script> import MeituanCoupon from './components/meituan-coupon.vue';
<template> import JingdongCoupon from './components/jingdong-coupon.vue';
<view class="u-wrap"> import TaobaoCoupon from './components/taobao-coupon.vue';
<view class="meituan"> </script>
<view class="content"> <template>
<view class="left"> <view class="u-wrap">
<view class="sum"> <MeituanCoupon />
<JingdongCoupon />
<text class="num">8</text> <TaobaoCoupon />
</view> </view>
<view class="type">抵用券</view> </template>
</view>
<view class="centre"> <style lang="scss" scoped>
<view class="title">洗牙8元无门槛红包</view> page {
<view class="valid-date">今日到期</view> height: 100%;
</view> background-color: rgb(244, 244, 244);
<view class="right"> }
<view size="mini" class="immediate-use" :round="true">立即使用</view>
</view> .u-wrap {
</view> padding: 24rpx;
<view class="tips"> }
<view class="circle-left"></view> </style>
<view class="circle-right"></view>
<view class="explain u-line-1">满8.1元可用限最新版本客户端使用</view>
<view class="rule" @tap="xxx122">
<text>使用规则</text>
<u-icon name="arrow-right" color="" :size="20" @click=""></u-icon>
</view>
</view>
</view>
<view class="jingdong">
<view class="left">
<view class="sum">
<text class="num">100</text>
</view>
<view class="type">满149元可用</view>
</view>
<view class="right">
<view class="top">
<view class="title">
<text class="tag">限品类东券</text>
<text>仅可购买个人护理部分商品</text>
</view>
<view class="bottom">
<view class="date u-line-1">2020.01.01-2020.01.31</view>
<view class="immediate-use">立即使用</view>
</view>
</view>
<view class="tips">
<view class="explain">
<u-icon name="zhuanfa" class="transpond" :size="24"></u-icon>
<text>可赠送</text>
</view>
</view>
</view>
</view>
<view class="taobao">
<view class="title">
<view class="left">
<image class="buddha"
src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1975388697,1068670603&fm=26&gp=0.jpg"
mode="aspectFill"></image>
<view class="store">袜子精保护协会</view>
</view>
<view class="entrance">进店</view>
</view>
<view class="ticket">
<view class="left">
<image class="picture"
src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578059523488&di=5f592ac19c1b983005d3e85add469756&imgtype=0&src=http%3A%2F%2Fimg010.hc360.cn%2Fg7%2FM00%2F2D%2FB9%2FwKhQs1QfUo6EdeM-AAAAALwk1hM072.jpg"
mode="widthFix"></image>
<view class="introduce">
<view class="top">
<text class="big">3</text>
满88减3
</view>
<view class="type">店铺优惠券</view>
<view class="date u-line-1">2019.11.28-2020.1.24</view>
</view>
</view>
<view class="right">
<view class="use immediate-use" :round="true">去使用</view>
</view>
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
page {
height: 100%;
background-color: rgb(244, 244, 244);
}
.u-wrap {
padding: 24rpx;
}
.meituan {
margin: 30rpx auto;
background-color: #ffffff;
width: 700rpx;
// border: 10rpx;
color: $u-warning;
font-size: 28rpx;
.content {
display: flex;
align-items: center;
padding: 80rpx 20rpx;
border: 10rpx;
background-color: #fff5f4;
.left {
.sum {
font-size: 32rpx;
.num {
font-size: 60rpx;
font-weight: bold;
}
}
}
.centre {
margin-left: 40rpx;
.title {
font-size: 32rpx;
font-weight: bold;
color: $u-main-color;
margin-bottom: 20rpx;
}
}
.right {
margin-left: 30rpx;
.immediate-use {
padding: 0 20rpx;
height: 50rpx;
border-radius: 25rpx;
line-height: 50rpx;
background-color: $u-warning !important;
color: #ffffff !important;
font-size: 24rpx;
border: none;
word-break: keep-all;
}
}
}
.tips {
padding: 0 20rpx;
border: 10rpx;
background-color: $u-info-light;
position: relative;
color: $u-tips-color;
display: flex;
justify-content: space-between;
line-height: 60rpx;
font-size: 24rpx;
.circle-left,
.circle-right {
position: absolute;
height: 36rpx;
width: 18rpx;
background-color: #f2f2f2;
}
.circle-right {
border-radius: 40rpx 0 0 40rpx;
right: 0;
top: -18rpx;
}
.circle-left {
border-radius: 0 40rpx 40rpx 0;
left: 0;
top: -18rpx;
}
.rule {
font-size: 24rpx;
display: flex;
align-items: center;
text {
margin-right: 10rpx;
flex: 1;
}
}
}
}
.jingdong {
margin-top: 40rpx;
width: 700rpx;
height: auto;
background-color: #ffffff;
display: flex;
.left {
padding: 0 30rpx;
background-color: rgb(95, 148, 224); //rgb(94, 152, 225);
text-align: center;
font-size: 28rpx;
color: #ffffff;
.sum {
margin-top: 50rpx;
font-weight: bold;
font-size: 32rpx;
.num {
font-size: 80rpx;
}
}
.type {
margin-bottom: 50rpx;
font-size: 24rpx;
}
}
.right {
padding: 20rpx 20rpx 0;
font-size: 28rpx;
.top {
border-bottom: 2rpx dashed $u-border-color;
.title {
margin-right: 60rpx;
line-height: 40rpx;
.tag {
padding: 4rpx 20rpx;
background-color: rgb(73, 154, 201);
border-radius: 20rpx;
color: #ffffff;
font-weight: bold;
font-size: 24rpx;
margin-right: 10rpx;
}
}
.bottom {
display: flex;
margin-top: 20rpx;
align-items: center;
justify-content: space-between;
margin-bottom: 10rpx;
.date {
font-size: 20rpx;
flex: 1;
}
.immediate-use {
height: auto;
padding: 0 20rpx;
font-size: 24rpx;
border-radius: 40rpx;
line-height: 40rpx;
color: rgb(117, 142, 165);
border: 2rpx solid rgb(117, 142, 165);
}
}
}
.tips {
width: 100%;
line-height: 50rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24rpx;
.transpond {
margin-right: 10rpx;
}
.explain {
display: flex;
align-items: center;
}
.particulars {
width: 30rpx;
height: 30rpx;
box-sizing: border-box;
padding-top: 8rpx;
border-radius: 50%;
background-color: $u-info-disabled;
text-align: center;
}
}
}
}
.taobao {
margin-top: 40rpx;
width: 700rpx;
background-color: white;
padding: 30rpx 20rpx 20rpx;
border-radius: 20rpx;
.title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
font-size: 30rpx;
.left {
display: flex;
align-items: center;
}
.store {
font-weight: 500;
}
.buddha {
width: 70rpx;
height: 70rpx;
border-radius: 10rpx;
margin-right: 10rpx;
}
.entrance {
color: $u-info;
border: solid 2rpx $u-info;
line-height: 48rpx;
padding: 0 30rpx;
background: none;
border-radius: 15px;
}
}
.ticket {
display: flex;
.left {
width: 70%;
padding: 30rpx 20rpx;
background-color: rgb(255, 245, 244);
border-radius: 20rpx;
border-right: dashed 2rpx rgb(224, 215, 211);
display: flex;
.picture {
width: 172rpx;
height: 172rpx;
border-radius: 20rpx;
}
.introduce {
margin-left: 10rpx;
.top {
color: $u-warning;
font-size: 28rpx;
.big {
font-size: 60rpx;
font-weight: bold;
margin-right: 10rpx;
}
}
.type {
font-size: 28rpx;
color: $u-info-dark;
}
.date {
margin-top: 10rpx;
font-size: 20rpx;
color: $u-info-dark;
}
}
}
.right {
width: 30%;
padding: 40rpx 20rpx;
background-color: rgb(255, 245, 244);
border-radius: 20rpx;
display: flex;
align-items: center;
.use {
height: auto;
padding: 0 20rpx;
font-size: 24rpx;
border-radius: 40rpx;
color: #ffffff !important;
background-color: $u-warning !important;
line-height: 40rpx;
color: rgb(117, 142, 165);
margin-left: 20rpx;
}
}
}
}
</style>

View File

@ -1,106 +1,99 @@
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
const show = ref(false)
const show = ref(false) const password = ref('')
const password = ref('')
const onChange = (val) => {
onLoad(() => { if (password.value.length < 6) {
}) password.value += val
}
const onChange = (val) => {
if (password.value.length < 6) { if (password.value.length >= 6) {
password.value += val pay()
} }
}
if (password.value.length >= 6) {
pay() const onBackspace = () => {
} if (password.value.length > 0) {
} password.value = password.value.substring(0, password.value.length - 1)
}
const onBackspace = () => { }
if (password.value.length > 0) {
password.value = password.value.substring(0, password.value.length - 1) const pay = () => {
} uni.showLoading({ title: '支付中' })
} setTimeout(() => {
uni.hideLoading()
const pay = () => { show.value = false
uni.showLoading({ uni.showToast({
title: '支付中' icon: 'success',
}) title: '支付成功'
})
setTimeout(() => { }, 2000)
uni.hideLoading() }
show.value = false
uni.showToast({ const showPop = (flag = true) => {
icon: 'success', password.value = ''
title: '支付成功' show.value = flag
}) // #ifdef H5 || WEB
}, 2000) setTimeout(() => {
} const btn = document.querySelector('.u-keyboard__button-wrapper__button.u-keyboard__button-wrapper__button--gray')
if (btn) {
const showPop = (flag = true) => { console.log(btn)
password.value = '' btn.onclick = onBackspace
show.value = flag }
// #ifdef H5 || WEB }, 500)
setTimeout(() => { // #endif
const btn = document.querySelector('.u-keyboard__button-wrapper__button.u-keyboard__button-wrapper__button--gray') }
if (btn) {
console.log(btn) const finish = () => {
btn.onclick = onBackspace console.log(11111)
} }
}, 500) </script>
// #endif <template>
} <view>
<view class="u-padding-40">
const finish = () => { <u-button type="success" @click="showPop(true)">
console.log(11111) <u-icon name="red-packet"></u-icon>
} <text class="u-padding-left-10">发送1.00元红包</text>
</script> </u-button>
<template> </view>
<view> <u-keyboard default="" ref="uKeyboard" mode="number" :mask="true" :mask-close-able="false" :dot-enabled="false"
<view class="u-padding-40"> :show="show" :safe-area-inset-bottom="true" :tooltip="false" @change="onChange" @backspace="onBackspace">
<u-button type="success" @click="showPop(true)"> <view>
<u-icon name="red-packet"></u-icon> <view class="u-text-center u-padding-20 money">
<text class="u-padding-left-10">发送1.00元红包</text> <text>1.00</text>
</u-button> <text class="u-font-20 u-padding-left-10"></text>
</view> <view class="u-padding-10 close" data-flag="false" @tap="showPop(false)">
<u-keyboard default="" ref="uKeyboard" mode="number" :mask="true" :mask-close-able="false" :dot-enabled="false" <u-icon name="close" color="#333333" size="28"></u-icon>
:show="show" :safe-area-inset-bottom="true" :tooltip="false" @change="onChange" @backspace="onBackspace"> </view>
<view> </view>
<view class="u-text-center u-padding-20 money"> <view class="u-flex u-row-center">
<text>1.00</text> <u-message-input mode="box" :maxlength="6" :dot-fill="true" v-model="password"
<text class="u-font-20 u-padding-left-10"></text> :disabled-keyboard="true" @finish="finish"></u-message-input>
<view class="u-padding-10 close" data-flag="false" @tap="showPop(false)"> </view>
<u-icon name="close" color="#333333" size="28"></u-icon> <view class="u-text-center u-padding-top-10 u-padding-bottom-20 tips">支付键盘</view>
</view> </view>
</view> </u-keyboard>
<view class="u-flex u-row-center"> </view>
<u-message-input mode="box" :maxlength="6" :dot-fill="true" v-model="password" </template>
:disabled-keyboard="true" @finish="finish"></u-message-input>
</view> <style lang="scss">
<view class="u-text-center u-padding-top-10 u-padding-bottom-20 tips">支付键盘</view> .money {
</view> font-size: 80rpx;
</u-keyboard> color: $u-warning;
</view> position: relative;
</template>
.close {
<style lang="scss"> position: absolute;
.money { top: 20rpx;
font-size: 80rpx; right: 20rpx;
color: $u-warning; line-height: 28rpx;
position: relative; font-size: 28rpx;
}
.close { }
position: absolute;
top: 20rpx; .tips {
right: 20rpx; color: $u-tips-color;
line-height: 28rpx; }
font-size: 28rpx;
}
}
.tips {
color: $u-tips-color;
}
</style> </style>

View File

@ -1,90 +1,89 @@
.text-center { .text-center {
text-align: center; text-align: center;
} }
.font-13 { .font-13 {
font-size: 13px; font-size: 13px;
} }
.font-12 { .font-12 {
font-size: 12px; font-size: 12px;
} }
.font-11 { .font-11 {
font-size: 11px; font-size: 11px;
} }
.text-grey1 { .text-grey1 {
color: #888; color: #888;
} }
.text-grey2 { .text-grey2 {
color: #aaa; color: #aaa;
} }
.list-cell-arrow::before { .list-cell-arrow::before {
content: ' '; content: " ";
height: 10px; height: 10px;
width: 10px; width: 10px;
border-width: 2px 2px 0 0; border-width: 2px 2px 0 0;
border-color: #c0c0c0; border-color: #c0c0c0;
border-style: solid; border-style: solid;
-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0); -webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0); transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
position: absolute; position: absolute;
top: 50%; top: 50%;
margin-top: -6px; margin-top: -6px;
right: 30rpx; right: 30rpx;
} }
.list-cell { .list-cell {
position: relative; position: relative;
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
background-color: #fff; background-color: #fff;
color: #333; color: #333;
padding: 26rpx 30rpx; padding: 26rpx 30rpx;
} }
.list-cell:first-child { .list-cell:first-child {
border-radius: 8rpx 8rpx 0 0; border-radius: 8rpx 8rpx 0 0;
} }
.list-cell:last-child { .list-cell:last-child {
border-radius: 0 0 8rpx 8rpx; border-radius: 0 0 8rpx 8rpx;
} }
.list-cell::after { .list-cell::after {
content: ''; content: "";
position: absolute; position: absolute;
border-bottom: 1px solid #eaeef1; border-bottom: 1px solid #eaeef1;
-webkit-transform: scaleY(0.5) translateZ(0); -webkit-transform: scaleY(0.5) translateZ(0);
transform: scaleY(0.5) translateZ(0); transform: scaleY(0.5) translateZ(0);
transform-origin: 0 100%; transform-origin: 0 100%;
bottom: 0; bottom: 0;
right: 0; right: 0;
left: 0; left: 0;
pointer-events: none; pointer-events: none;
} }
.menu-list {
.menu-list { margin: 15px 15px;
margin: 15px 15px;
.menu-item-box {
.menu-item-box { width: 100%;
width: 100%; display: flex;
display: flex; align-items: center;
align-items: center;
.menu-icon {
.menu-icon { color: #007aff;
color: #007AFF; font-size: 16px;
font-size: 16px; margin-right: 5px;
margin-right: 5px; }
}
.text-right {
.text-right { margin-left: auto;
margin-left: auto; margin-right: 34rpx;
margin-right: 34rpx; color: #999;
color: #999; }
} }
} }
}

View File

@ -1,88 +1,88 @@
import { login, logout, getInfo } from "@/api/login"; import { login, logout, getInfo } from "@/api/login";
import { getToken, setToken, removeToken } from "@/utils/auth"; import { getToken, setToken, removeToken } from "@/utils/auth";
import defAva from "@/static/images/profile.jpg"; import defAva from "@/static/images/profile.jpg";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
export interface LoginForm { export interface LoginForm {
username: string; username: string;
password: string; password: string;
code: string; code: string;
uuid: string; uuid: string;
} }
const useUserStore = defineStore("user", { const useUserStore = defineStore("user", {
state: () => ({ state: () => ({
token: getToken(), token: getToken(),
name: "", name: "",
avatar: "", avatar: "",
roles: Array(), roles: Array(),
permissions: [], permissions: [],
}), }),
actions: { actions: {
// 登录 // 登录
login(userInfo: LoginForm) { login(userInfo: LoginForm) {
const username = userInfo.username.trim(); const username = userInfo.username.trim();
const password = userInfo.password; const password = userInfo.password;
const code = userInfo.code; const code = userInfo.code;
const uuid = userInfo.uuid; const uuid = userInfo.uuid;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
login(username, password, code, uuid) login(username, password, code, uuid)
.then((res: any) => { .then((res: any) => {
setToken(res.token); setToken(res.token);
this.token = res.token; this.token = res.token;
resolve(null); resolve(null);
}) })
.catch((error) => { .catch((error) => {
reject(error); reject(error);
}); });
}); });
}, },
// 获取用户信息 // 获取用户信息
getInfo() { getInfo() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getInfo() getInfo()
.then((res: any) => { .then((res: any) => {
const user = res.user; const user = res.user;
const avatar = const avatar =
user.avatar == "" || user.avatar == null user.avatar == "" || user.avatar == null
? defAva ? defAva
: import.meta.env.VITE_APP_BASE_API + user.avatar; : user.avatar;
if (res.roles && res.roles.length > 0) { if (res.roles && res.roles.length > 0) {
// 验证返回的roles是否是一个非空数组 // 验证返回的roles是否是一个非空数组
this.roles = res.roles; this.roles = res.roles;
this.permissions = res.permissions; this.permissions = res.permissions;
} else { } else {
this.roles = ["ROLE_DEFAULT"]; this.roles = ["ROLE_DEFAULT"];
} }
this.name = user.userName; this.name = user.userName;
this.avatar = avatar; this.avatar = avatar;
resolve(res); resolve(res);
}) })
.catch((error) => { .catch((error) => {
reject(error); reject(error);
}); });
}); });
}, },
// 退出系统 // 退出系统
logOut() { logOut() {
return new Promise<null>((resolve, reject) => { return new Promise<null>((resolve, reject) => {
logout() logout()
.then(() => { .then(() => {
this.token = ""; this.token = "";
this.roles = []; this.roles = [];
this.permissions = []; this.permissions = [];
this.name = ""; this.name = "";
this.avatar = ""; this.avatar = "";
removeToken(); removeToken();
resolve(null); resolve(null);
}) })
.catch((error) => { .catch((error) => {
reject(error); reject(error);
}); });
}); });
}, },
}, },
}); });
export default useUserStore; export default useUserStore;