瀏覽代碼

1

dev_YWQ
congzc 1 年之前
父節點
當前提交
52fce46429
共有 8 個文件被更改,包括 935 次插入151 次删除
  1. +1
    -151
      README.md
  2. +16
    -0
      src/apis/myStore.js
  3. +25
    -0
      src/lang/package/en.ts
  4. +24
    -0
      src/lang/package/zh-cn.ts
  5. +16
    -0
      src/layout/index.vue
  6. +34
    -0
      src/router/index.ts
  7. +21
    -0
      src/views/myAPI/index.vue
  8. +798
    -0
      src/views/myStore/index.vue

+ 1
- 151
README.md 查看文件

@@ -1,154 +1,4 @@
<p align="center">
<img src="https://img.shields.io/badge/Vue-3.2.45-brightgreen.svg" />
<img src="https://img.shields.io/badge/Vite-4.3.1-green.svg" />
<img src="https://img.shields.io/badge/Element Plus-2.3.1-blue.svg" />
<img src="https://img.shields.io/badge/license-MIT-green.svg" />
<a href="https://gitee.com/youlaiorg" target="_blank">
<img src="https://img.shields.io/badge/Author-有来开源组织-orange.svg" />
</a>
</p>
<p align="center">
<a target="_blank" href="https://www.cnblogs.com/haoxianrui/p/17331952.html">vue3-element-admin官方文档</a> | <a
target="_blank" href="http://vue3.youlai.tech">在线预览</a>
</p>

## 项目介绍

[vue3-element-admin](https://gitee.com/youlaiorg/vue3-element-admin) 是基于
[vue-element-admin](https://gitee.com/panjiachen/vue-element-admin) 升级的 `Vue3` 版本后台管理框架,使用
Vue3、Vite4、TypeScript、Pinia、Element Plus 当前主流技术栈开发。

## 项目特色

- 基于 `vue-element-admin` 升级的 `Vue3` 版本,主流技术栈,无过度自定义封装,极易上手,减少学习成本;
- 配套 `Java` 后台接口,非 `Mock`
数据,[在线接口文档](https://www.apifox.cn/apidoc/shared-195e783f-4d85-4235-a038-eec696de4ea5/api-65851240);
- 从 `0` 到 `1` 的项目文档支持,[官方文档](https://www.cnblogs.com/haoxianrui/p/16090029.html)。
- 系统功能:用户、角色、菜单、字典管和部门管理等;
- 基础设施:动态路由,按钮权限,常用组件封装。

## 技术栈

| 技术栈 | 描述 | 官网 |
| --- | --- | --- |
| Vue3 | 渐进式 JavaScript 框架 | https://v3.cn.vuejs.org/ |
| TypeScript | JavaScript 的一个超集 | https://www.tslang.cn/ |
| Vite | 前端开发与构建工具 | https://cn.vitejs.dev/ |
| Element Plus | 基于 Vue 3,面向设计师和开发者的组件库 | https://element-plus.gitee.io/zh-CN/ |
| Pinia | 新一代状态管理工具 | https://pinia.vuejs.org/ |
| Vue Router | Vue.js 的官方路由 | https://router.vuejs.org/zh/ |

## 项目预览

**在线预览地址**: [http://vue3.youlai.tech/](http://vue3.youlai.tech/)

**控制台 & 接口文档**

| ![暗黑模式](https://s2.loli.net/2023/03/13/QvjY4zf3VCGteNF.png) |
| --------------------------------------------------------------- |
| ![接口文档](https://s2.loli.net/2023/03/13/bH4J3O6WRgCUpwt.png) |

**权限管理系统**

| ![用户管理](https://s2.loli.net/2023/03/13/L9xgT5sSMVZukQj.png) |
![image-20230313003008012](https://s2.loli.net/2023/03/13/nQg6HmrtFUkPDYv.png) |
| --- | --- |
| ![image-20230313003028425](https://s2.loli.net/2023/03/13/C4fDRJeTuUO7gPI.png) |
![字典管理](https://s2.loli.net/2023/03/13/BzqjHpa64wfeWhE.png) |

## 项目地址

| | Gitee | Github |
| --- | --- | --- |
| vue3-element-admin | [vue3-element-admin](https://gitee.com/youlaiorg/vue3-element-admin) |
[vue3-element-admin](https://github.com/youlaitech/vue3-element-admin) |
| 后端 | [youlai-boot](https://gitee.com/youlaiorg/youlai-boot) | [youlai-boot](https://github.com/hxrui/youlai-boot.git)
|

## 环境要求

- Node 环境

版本:16+

- 开发工具

VSCode

- 必装插件

- Vue Language Features (Volar)
- TypeScript Vue Plugin (Volar)

## 项目启动

```bash
# 安装 pnpm
npm install pnpm -g

# 安装依赖
pnpm install

# 项目运行
pnpm run dev

# 项目打包
pnpm run build:prod

```

## 项目部署

- 上传文件

将打包生成在 `dist` 目录下的文件拷贝至 `/usr/share/nginx/html` 目录

- nginx.cofig 配置

```
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

# 代理转发 prod-api 标识至 vapi.youlai.tech
location /prod-api/ {
proxy_pass http://vapi.youlai.tech/;
}
}

```

## 接口文档

- 接口调用地址:[vapi.youlai.tech](http://vapi.youlai.tech)
- 接口文档地址:[vue3-element-admin
在线接口文档](https://www.apifox.cn/apidoc/shared-195e783f-4d85-4235-a038-eec696de4ea5/api-65851240)

## 本地接口

> 默认使用线上接口,你可以通过以下步骤完成本地接口环境搭建:

1. 获取基于 `Java 、SpringBoot` 开发的后端 [youlai-boot](https://gitee.com/youlaiorg/youlai-boot.git) 源码 ;
2. 根据后端工程说明文档 [README.md](https://gitee.com/youlaiorg/youlai-boot#%E9%A1%B9%E7%9B%AE%E8%BF%90%E8%A1%8C) 完成本地启动;
3. 替换 [vite.config.ts](vite.config.ts) 的代理目标地址 [vapi.youlai.tech](vapi.youlai.tech) 为本地的
[localhost:8989](localhost:8989) 。

## 关于我们

> 欢迎加我的微信,备注 `前端`、`后端`、`全栈` 进对应技术交流群

| 微信交流群 | 我的微信 |
| --- | --- |
| ![](https://s2.loli.net/2023/05/06/NwhFvKqZ4zjfO5i.png)| ![](https://s2.loli.net/2022/04/06/yRx8uzj4emA5QVr.jpg) |

![](https://s2.loli.net/2022/11/19/OGjum9wr8f6idLX.png)


<!-- 照片说话 慧影 -->
git commit -m "feat: "
git commit --no-verify -m "提交时的注释" 跳过检验
git merge origin/dev_

+ 16
- 0
src/apis/myStore.js 查看文件

@@ -0,0 +1,16 @@
import request from "@/utils/request.js";


/**
* @description 获取价格表
* @params
* @returns
*/
export function packageInfoApi() {
return request({
url: `/api/user/getPackageInfo`,
method: 'get'
})
}



+ 25
- 0
src/lang/package/en.ts 查看文件

@@ -81,6 +81,7 @@ export default {
searchMusic:'Search music',
copywriting:'Copywriting',
BackgroundImage:'Background Image',
comingSoon:'COMING SOON',
material:'Material',
subtitles:'Subtitles',
sex:"Sex",
@@ -166,7 +167,31 @@ export default {
selectPlan: "SELECT PLAN",
WeChatPay: "WeChatPay",
Alipay: "Alipay",
score:'Credits',
day:'day',
second:'seconds',
yes:'yes',
no:'no',
InviteGetscore:'Invite users to get score',
createVideoPrice:'Create video prices',
AIGeneratesPhotoPrices:'AI generates photo unit prices',
UnitChargeDuration:'Unit charge duration',
Language:'Language',
sound:'Sound',
IndividualVideoDuration:'Individual video duration',
Watermark:'Watermark',
AIGeneratedPortrait:'AI generated portrait',
PhotoSinging:'Photo singing',
AIGeneratedText:'The number of times AI generated text',
VideoResolution:'Video resolution',
DigitalPersonTemplate:'Digital person template',
talkUs:"Talk With Us",
},
API:{
title:'API Access',
},


signSucceed: {
title: "Confirm your email",
succeed: "Sign Succeed !",


+ 24
- 0
src/lang/package/zh-cn.ts 查看文件

@@ -81,6 +81,7 @@ export default {
chooseMusic:'选择音乐',
searchMusic:'搜索音乐',
copywriting:'文案',
comingSoon:'敬请期待',
BackgroundImage:'背景',
material:'素材',
subtitles:'字幕',
@@ -167,7 +168,30 @@ export default {
selectPlan: "方案选择",
WeChatPay: "微信支付",
Alipay: "支付宝支付",
score:'积分',
day:'天',
second:'秒',
yes:'是',
no:'否',
InviteGetscore:'邀请用户得到的积分',
createVideoPrice:'创建视频单价',
AIGeneratesPhotoPrices:'AI生成照片单价',
UnitChargeDuration:'单价收费时长',
Language:'语言',
sound:'声音',
IndividualVideoDuration:'单个视频时长',
Watermark:'水印',
AIGeneratedPortrait:'AI生成人像',
PhotoSinging:'照片唱歌',
AIGeneratedText:'AI生成脚本次数',
VideoResolution:'视频分辨率',
DigitalPersonTemplate:'数字人模版',
talkUs:"联系我们",
},
API:{
title:'API 接口',
},

signSucceed: {
title: "确认邮箱",
succeed: "注册成功",


+ 16
- 0
src/layout/index.vue 查看文件

@@ -23,6 +23,22 @@
</div>
{{ $t("myCreating.title") }}
</div>
<div
class="myRouter-item"
@click="router.push('/myStore')"
style="margin-top: 350px"
>
<div class="icon">
<el-icon><i-ep-Goods /></el-icon>
</div>
{{ $t("shop.title") }}
</div>
<div class="myRouter-item" @click="router.push('/myAPI')">
<div class="icon">
<el-icon><i-ep-DocumentAdd /></el-icon>
</div>
{{ $t("API.title") }}
</div>
</div>
</div>
<!-- 右边显示部分 -->


+ 34
- 0
src/router/index.ts 查看文件

@@ -55,6 +55,40 @@ export const constantRoutes: RouteRecordRaw[] = [
},
},
],
}, {
path: "/",
component: Layout,
redirect: "/myStore",
children: [
{
path: "myStore",
component: () => import("@/views/myStore/index.vue"),
name: "myStore",
meta: {
title: "myStore",
icon: "homepage",
affix: true,
name: "myStore.title",
},
},
],
}, {
path: "/",
component: Layout,
redirect: "/myAPI",
children: [
{
path: "myAPI",
component: () => import("@/views/myAPI/index.vue"),
name: "myAPI",
meta: {
title: "myAPI",
icon: "homepage",
affix: true,
name: "API.title",
},
},
],
},
{
path: "/",


+ 21
- 0
src/views/myAPI/index.vue 查看文件

@@ -0,0 +1,21 @@
<template>
<div class="page">
<h1>使用DOKUWIKI部署,免费,开源,无需数据库即可维护wiki内容</h1>
<a href="https://www.dokuwiki.org/dokuwiki" target="_blank"
><h2>https://www.dokuwiki.org/dokuwiki</h2></a
>
</div>
</template>
<script setup>
// import { ref } from 'vue'
</script>
<style lang="scss" scoped>
.page {
padding: 30px;
width: 100%;
overflow: hidden;
overflow-y: scroll;
background-color: #fff;
min-height: calc(100vh - 80px);
}
</style>

+ 798
- 0
src/views/myStore/index.vue 查看文件

@@ -0,0 +1,798 @@
<template>
<div class="page">
<div class="commoditylIst" ref="scrollContainerRef" @wheel="handleWheel">
<div class="item" v-for="item in packageList" :key="item.typeDesc">
<!-- 遮罩层 -->
<div class="mask" v-if="item.type != 1">
<el-icon><i-ep-Lock /></el-icon>
</div>
<div @click="clickPayDialog(item)" v-if="item.typeDesc">
<div class="line" :style="`background-color:${item.color} ;`"></div>
<div class="info">
<!-- 商品信息 -->
<div class="content">
<div class="titleBox">
<div class="title">
{{ lanChange == "zh-cn" ? item.typeDesc : item.englishName }}
</div>
</div>
<div class="money">
<span class="price">{{
lanChange == "zh-cn" ? item.rmb + "¥" : item.dollar + "$"
}}</span
>/{{ item.validityDuration }}{{ $t("shop.day") }}
</div>
<div class="time">
<span>{{ item.credit }}</span
>{{ $t("shop.score") }}
</div>
<div
v-if="item.type != 1"
class="button"
:style="`background-color:${item.color} ;`"
>
{{ $t("createVideo.comingSoon") }}
</div>
<div
v-else
class="button"
:style="`background-color:${item.color} ;`"
>
{{ $t("shop.selectPlan") }}
</div>
</div>
<!-- 商品权益 -->
<div class="authority">
<div class="authority-item">
{{ $t("shop.InviteGetscore") }}:

<span>
<i>{{ item.inviteUserCredit }}</i
>{{ $t("shop.score") }}</span
>
</div>
<div class="authority-item">
{{ $t("shop.createVideoPrice") }}:<span
><i>{{ item.videoPrice }}</i
>{{ $t("shop.score") }}</span
>
</div>
<div class="authority-item">
{{ $t("shop.AIGeneratesPhotoPrices") }}:<span
><i>{{ item.photoPrice }}</i
>{{ $t("shop.score") }}</span
>
</div>
<div class="authority-item">
{{ $t("shop.UnitChargeDuration") }}:<span
><i>{{ item.chargeTime }}</i
>{{ $t("shop.second") }}</span
>
</div>

<div class="authority-item">
{{ $t("shop.Language") }}:<span
><i>{{ item.userPackageDetails[0].languageDesc }}</i></span
>
</div>
<div class="authority-item">
{{ $t("shop.sound") }}:<span
><i>{{ item.userPackageDetails[0].soundDesc }}</i></span
>
</div>
<div class="authority-item">
{{ $t("shop.IndividualVideoDuration") }}:<span
><i>{{ item.userPackageDetails[0].videoTime }}</i
>{{ $t("shop.second") }}</span
>
</div>
<div class="authority-item">
{{ $t("shop.Watermark") }}:<span>{{
item.userPackageDetails[0].aiPortrait == 0
? $t("shop.yes")
: $t("shop.no")
}}</span>
</div>
<div class="authority-item">
{{ $t("shop.AIGeneratedPortrait") }}:<span>{{
item.userPackageDetails[0].aiPortrait == 0
? $t("shop.no")
: $t("shop.yes")
}}</span>
</div>
<div class="authority-item">
{{ $t("shop.PhotoSinging") }}:<span>{{
item.userPackageDetails[0].photoSing == 0
? $t("shop.no")
: $t("shop.yes")
}}</span>
</div>
<div class="authority-item">
{{ $t("shop.AIGeneratedText") }}:<span
><i>{{ item.userPackageDetails[0].aiCreateTime }}</i></span
>
</div>
<div class="authority-item">
{{ $t("shop.VideoResolution") }}:<span>{{
item.userPackageDetails[0].resolutionRatioDesc
}}</span>
</div>
<!-- <div class="authority-item">
{{ $t("shop.DigitalPersonTemplate") }}:{{
item.userPackageDetails[0].humanTemplateDesc
}}
</div> -->
<!-- <div
class="authority-item"
v-for="items in item.authority"
:key="items"
>
<span>✔</span>{{ items }}
</div> -->
</div>
</div>
</div>
</div>
<!-- 企业版 -->
<div class="item">
<!-- 遮罩层 -->
<div class="mask" v-if="false">
<el-icon><i-ep-Lock /></el-icon>
</div>
<div class="line" :style="`background-color:#000 ;`"></div>
<div class="info">
<div class="content" style="border-bottom: none">
<div class="titleBox">
<div class="title">
{{ $t("shop.Ent") }}
</div>
</div>
<!-- 描述 -->
<div class="description">
<div>
{{ lanChange == "zh-cn" ? "所有权限" : "All Pro Benefits" }}
</div>
<div>
{{
lanChange == "zh-cn" ? "克隆数组双元" : "Clone DigItal Double"
}}
</div>
<div>
{{
lanChange == "zh-cn" ? "专属定制头像" : "Customized Avatar"
}}
</div>
<div>
{{
lanChange == "zh-cn"
? "专属定制声纹"
: "Customized Voiceprint"
}}
</div>
</div>
<div v-if="true" class="button" :style="`background-color:#000 ;`">
{{ $t("shop.talkUs") }}
</div>
<div v-else class="button" :style="`background-color:#000 ;`">
{{ $t("shop.talkUs") }}
</div>
</div>
</div>
</div>
</div>
<!-- 对话框 -->
<el-dialog v-if="false" v-model="showPayDialog" width="60%" center>
<div class="payDialog">
<div class="left">
<div class="title">{{ $t(presentItme.value.title) }}</div>
<div class="price">
<span>{{ presentItme.value.price }}</span>
元/{{ presentItme.value.priceTime }}
</div>
<div
class="authority"
v-for="item in presentItme.value.authority"
:key="item"
>
{{ item }}
</div>
</div>
<div class="right">
<div
style="background-color: #07c160; cursor: pointer"
@click="showOrderCode(1)"
>
{{ $t("shop.WeChatPay") }}
</div>
<div
style="background-color: #1378fe; cursor: pointer"
@click="showOrderCode(2)"
>
{{ $t("shop.Alipay") }}
</div>
<div
style="background-color: #0070ba; cursor: pointer"
@click="showOrderCode(3)"
>
Paypal
</div>
</div>
</div>
<!-- 二维码弹出框 -->
<el-dialog
v-model="orderCodeDialogShow"
width="30%"
append-to-body
destroy-on-close
>
<div class="orderCodeDialog">
<div class="codeImg">
<my-Loading-Icon v-if="!orderCodeUrl"></my-Loading-Icon>
<img v-if="orderCodeUrl" src="../../assets/img/false1.png" alt="" />
</div>
<div class="tips">扫描二维码进行付款</div>
<div class="btnBox">
<div>刷新二维码</div>
</div>
</div>
</el-dialog>
</el-dialog>
</div>
</template>

<script setup>
//#region 导入
import { getCurrentInstance, ref, onMounted } from "vue";
// import { packageInfoApi } from "@/apis/myStore";
import { useI18n } from "vue-i18n";

import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const { locale } = useI18n();
const lanChange = ref(locale);

const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录
//#endregion ------------------------------------

//#region 各个套餐的逻辑
const packageList = ref([
{
id: 1,
type: 1,
typeDesc: "基础版",
englishName: "Trial",
dollar: "0.00",
rmb: "0.00",
credit: 100,
validityDuration: 30,
inviteUserCredit: 10,
videoPrice: 10,
photoPrice: 10,
talkPrice: 20,
chargeTime: 60,
createDate: 1686814258000,
updateDate: 1686814258000,
isDel: 0,
color: "#f3af00",
userPackageDetails: [
{
id: 1,
detailType: 1,
detailTypeDesc: "照片说话",
packageId: 1,
watermark: 1,
watermarkDesc: "是",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 60,
aiPortrait: 0,
aiPortraitDesc: "否",
photoSing: 0,
photoSingDesc: "否",
aiCreateTime: 0,
resolutionRatio: 1,
resolutionRatioDesc: "720p",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
{
id: 4,
detailType: 2,
detailTypeDesc: "口播",
packageId: 1,
watermark: 1,
watermarkDesc: "是",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 60,
aiCreateTime: 0,
resolutionRatio: 1,
resolutionRatioDesc: "720p",
humanTemplate: 1,
humanTemplateDesc: "免费",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
],
},
{
id: 2,
type: 2,
typeDesc: "专业版",
englishName: "Pro",
dollar: "7.99",
rmb: "49.99",
credit: 200,
validityDuration: 30,
inviteUserCredit: 10,
videoPrice: 6,
photoPrice: 6,
talkPrice: 16,
chargeTime: 60,
createDate: 1686814258000,
updateDate: 1686814258000,
isDel: 0,
color: "#c971ff",
userPackageDetails: [
{
id: 2,
detailType: 1,
detailTypeDesc: "照片说话",
packageId: 2,
watermark: 0,
watermarkDesc: "否",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 300,
aiPortrait: 1,
aiPortraitDesc: "是",
photoSing: 1,
photoSingDesc: "是",
aiCreateTime: 30,
resolutionRatio: 2,
resolutionRatioDesc: "1080p",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
{
id: 5,
detailType: 2,
detailTypeDesc: "口播",
packageId: 2,
watermark: 0,
watermarkDesc: "否",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 300,
aiCreateTime: 100,
resolutionRatio: 2,
resolutionRatioDesc: "1080p",
humanTemplate: 2,
humanTemplateDesc: "VIP",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
],
},
{
id: 3,
type: 3,
typeDesc: "加强版",
englishName: "Advanced",
dollar: "39.99",
rmb: "279.99",
credit: 1200,
validityDuration: 30,
inviteUserCredit: 10,
videoPrice: 5,
photoPrice: 5,
talkPrice: 15,
chargeTime: 60,
createDate: 1686814258000,
updateDate: 1686814258000,
isDel: 0,
color: "#7b61ff",
userPackageDetails: [
{
id: 3,
detailType: 1,
detailTypeDesc: "照片说话",
packageId: 3,
watermark: 0,
watermarkDesc: "否",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 300,
aiPortrait: 1,
aiPortraitDesc: "是",
photoSing: 1,
photoSingDesc: "是",
aiCreateTime: 200,
resolutionRatio: 2,
resolutionRatioDesc: "1080p",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
{
id: 6,
detailType: 2,
detailTypeDesc: "口播",
packageId: 3,
watermark: 0,
watermarkDesc: "否",
language: 1,
languageDesc: "50+",
sound: 1,
soundDesc: "400+",
videoTime: 300,
aiCreateTime: 200,
resolutionRatio: 2,
resolutionRatioDesc: "1080p",
humanTemplate: 2,
humanTemplateDesc: "VIP",
createDate: 1686882177000,
updateDate: 1686882177000,
isDel: 0,
},
],
},
]);

async function getPackageList() {
const res = await packageInfoApi();
packageList.value = res.data;
}
const showPayDialog = ref(false); //套餐信息dialog显示隐藏
const presentItme = reactive({}); //点击的套餐项
function clickPayDialog(item) {
presentItme.value = item;
showPayDialog.value = true;
}
function showOrderCode(type) {
orderCodeDialogShow.value = true;
}
//#endregion ------------------------------------

//#region 点击套餐内的支付
const orderCodeDialogShow = ref(false);
const orderCodeUrl = ref(null);
//#endregion ------------------------------------

//#region $t在script中的使用
// const {
// appContext: {
// config: { globalProperties },
// },
// } = getCurrentInstance();

// const string = "createVideo.typeScript";
// const t = globalProperties.$t(string);
//#endregion ------------------------------------

//#region 页面滚动
const scrollContainerRef = ref(null);
function handleWheel(event) {
const scrollContainer = scrollContainerRef.value; // 获取滚动容器的引用
const scrollAmount = 150; // 每次滚动的距离

// 检查滚动方向
if (event.deltaY > 0) {
// 向右滚动
scrollContainer.scrollLeft += scrollAmount;
} else {
// 向左滚动
scrollContainer.scrollLeft -= scrollAmount;
}
event.preventDefault(); // 防止页面上下滚动
}
//#endregion ------------------------------------

//#region 页面初始化
onMounted(async () => {
// getPackageList();
});
//#endregion ------------------------------------

//#region

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

//#region

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

<style lang="scss" scoped>
.page {
// min-width: calc(100vw - 210px);
height: calc(100vh - 80px);
width: 1690px;
padding: 0px 20px 0 20px;
background-color: #fff;
border-radius: 25px 0 0;
padding: 20px;
user-select: none;
overflow: hidden;
}
// 方案列表
.commoditylIst {
display: flex;
justify-content: flex-start;
overflow-x: scroll;
padding: 30px 20px 20px 10px;
max-width: 100%;
// height: 75%;
// overflow: hidden;
// overflow-x: scroll;
// scrollbar-width: none; /* 隐藏滚动条(Chrome、Firefox) */
// -ms-overflow-style: none; /* 隐藏滚动条(IE、Edge) */
// &::-webkit-scrollbar {
// display: none; /* 隐藏滚动条(Safari、Chrome) */
// }
.item {
position: relative;
width: 480px;
// height: 680px;
margin-left: 45px;
background-color: #fffefd;
flex-shrink: 0; /* 防止缩小宽度 */
border: 1px solid #c0bfbd;
border-radius: 20px;
overflow: hidden;
transition: all 0.2s;
cursor: pointer;
&:hover {
.mask {
display: block;
}
}
// 遮罩层
.mask {
position: absolute;
top: 0;
left: 0;
display: none;
width: 100%;
height: 100%;
line-height: 780px;
font-size: 120px;
font-weight: 900;
text-align: center;
background-color: rgba(0, 0, 0, 0.2);
cursor: pointer;
}
.line {
height: 20px;
background-color: pink;
cursor: pointer;
}
.info {
padding: 20px;
cursor: pointer;
.content {
// height: 220px;
padding: 20px;
border-bottom: 1px solid #c0bfbd;
cursor: pointer;
.titleBox {
display: flex;
justify-content: space-between;
}
.title {
font-size: 30px;
font-weight: 700;
width: 100%;
margin-bottom: 10px;
cursor: pointer;
text-align: center;
.el-icon {
line-height: 30px;
width: 40px;
height: 40px;
font-size: 40px;
color: #000;
text-align: center;
vertical-align: sub;
cursor: pointer;
}
}
.money {
margin-bottom: 10px;
font-size: 20px;
color: #7c7c7a;
cursor: pointer;
text-align: end;
.price {
font-size: 30px;
font-weight: 700;
color: #242625;
cursor: pointer;
}
}
.time {
text-align: end;
margin-bottom: 10px;
font-size: 20px;
color: #7c7c7a;
cursor: pointer;
margin-bottom: 20px;
span {
font-weight: 700;
color: #242625;
cursor: pointer;
margin-right: 5px;
}
}

.button {
width: 100%;
height: 40px;
font-size: 16px;
border-radius: 10px;
text-align: center;
line-height: 40px;
color: #fff;
font-weight: 700;
background-color: yellow;
cursor: pointer;
}
.description {
margin-top: 50px;
margin-bottom: 30px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
font-size: 18px;
color: #7c7c7a;
> div {
margin-bottom: 20px;
}
}
}
.authority {
margin-top: 10px;
&-item {
display: flex;
justify-content: space-between;
cursor: pointer;
font-weight: 400;
font-size: 18px;
padding: 5px 10px;
color: #7c7c7a;

span {
cursor: pointer;
color: #7c7c7a;
margin-right: 30px;
}
i {
font-size: 20px;
font-style: normal;
margin-right: 5px;
background-image: -webkit-linear-gradient(
left,
#4b61dc,
#15d1b8 25%,
#4b61dc 50%,
#15d1b8 75%,
#4b61dc
) !important;
-webkit-text-fill-color: transparent !important;
-webkit-background-clip: text !important;
background-clip: text !important;
-webkit-background-size: 200% 100% !important;
background-size: 200% 100% !important;
}
}
}
}
&:hover {
cursor: pointer;
transform: translateY(-20px);
box-shadow: #00000026 2px 2px 2px 2px;
}
}
}
// 支付弹窗
.payDialog {
display: flex;
position: relative;
min-height: 500px;
.left {
width: 35%;
border-right: 1px solid #7c7c7a;
.title {
color: #242625;
font-weight: 700;
font-size: 30px;
text-align: center;
}
.price {
span {
font-size: 30px;
font-weight: 700;
color: #242625;
}
}
.authority {
padding: 10px 20px;
}
}
.right {
width: 65%;
position: absolute;
top: 20%;
right: 0%;
padding-left: 20%;
> div {
width: 200px;
height: 40px;
// border: 1px solid #242625;
border-radius: 10px;
text-align: center;
line-height: 40px;
margin: 30px;
color: #fff;
}
}
}
// 二维码弹窗
.orderCodeDialog {
width: 100%;
.codeImg {
display: flex;
margin: auto;
justify-content: space-evenly;
align-items: center;
width: 300px;
height: 300px;
border: 1px solid #ccc;
border-radius: 15px;
overflow: hidden;
padding: 10px;
img {
width: 100%;
height: 100%;
}
}
.tips {
padding-top: 10px;
text-align: center;
}
.btnBox {
padding: 15px 40px;
display: flex;
justify-content: space-evenly;
> div {
padding: 10px 20px;
color: #000;
background-color: #fff;
border: #000 solid 1px;
border-radius: 10px;
transition: all 0.3s;
cursor: pointer;
&:hover {
color: #fff;
background-color: #000;
}
}
}
}
</style>

Loading…
取消
儲存