save
653
public/data/goods.json
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米电视6 65\" OLED 65英寸",
|
||||||
|
"cover": "g6-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g6-0.jpg",
|
||||||
|
"g6-1.jpg",
|
||||||
|
"g6-2.jpg",
|
||||||
|
"g6-3.jpg",
|
||||||
|
"g6-4.jpg"
|
||||||
|
],
|
||||||
|
"price": 6699,
|
||||||
|
"real_price": 399,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 863
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
||||||
|
"cover": "g1-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g1-0.jpg",
|
||||||
|
"g1-1.jpg",
|
||||||
|
"g1-2.jpg",
|
||||||
|
"g1-3.jpg"
|
||||||
|
],
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满4减3",
|
||||||
|
"sold": 134,
|
||||||
|
"price": 39.9,
|
||||||
|
"real_price": 9.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
||||||
|
"imgs": [
|
||||||
|
"g2-0.webp",
|
||||||
|
"g2-1.webp",
|
||||||
|
"g2-2.webp",
|
||||||
|
"g2-3.webp"
|
||||||
|
],
|
||||||
|
"cover": "g2-0.webp",
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 49.99,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "满20减5",
|
||||||
|
"sold": 3314
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
||||||
|
"cover": "g3-0.jpg",
|
||||||
|
"imgs": [
|
||||||
|
"g3-0.jpg",
|
||||||
|
"g3-1.jpg",
|
||||||
|
"g3-2.jpg",
|
||||||
|
"g3-3.jpg",
|
||||||
|
"g3-4.jpg"
|
||||||
|
],
|
||||||
|
"real_price": 9.9,
|
||||||
|
"price": 22.90,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "满10减3",
|
||||||
|
"sold": 129
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
||||||
|
"cover": "g4-0.png",
|
||||||
|
"imgs": [
|
||||||
|
"g4-0.png",
|
||||||
|
"g4-1.png",
|
||||||
|
"g4-2.png",
|
||||||
|
"g4-3.png"
|
||||||
|
],
|
||||||
|
"real_price": 199.9,
|
||||||
|
"price": 2999,
|
||||||
|
"isLowPrice": true,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 967
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "小米笔记本Pro X 14",
|
||||||
|
"imgs": [
|
||||||
|
"g5-0.jpg",
|
||||||
|
"g5-1.jpg",
|
||||||
|
"g5-2.jpg",
|
||||||
|
"g5-3.jpg",
|
||||||
|
"g5-4.jpg"
|
||||||
|
],
|
||||||
|
"cover": "g5-0.jpg",
|
||||||
|
"real_price": 1559.9,
|
||||||
|
"price": 6999,
|
||||||
|
"isLowPrice": false,
|
||||||
|
"discount": "",
|
||||||
|
"sold": 473
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 231 KiB After Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
BIN
public/images/icon/love.webp
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
@ -3,6 +3,7 @@ import request from "../utils/request";
|
|||||||
export function userinfo(params, data) {
|
export function userinfo(params, data) {
|
||||||
return request({url: '/user/userinfo', method: 'get', params, data})
|
return request({url: '/user/userinfo', method: 'get', params, data})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function userVideoList(params, data) {
|
export function userVideoList(params, data) {
|
||||||
return request({url: '/user/video_list', method: 'get', params, data})
|
return request({url: '/user/video_list', method: 'get', params, data})
|
||||||
}
|
}
|
||||||
@ -22,3 +23,7 @@ export function userCollect(params, data) {
|
|||||||
export function recommendedPost(params, data) {
|
export function recommendedPost(params, data) {
|
||||||
return request({url: '/post/recommended', method: 'get', params, data})
|
return request({url: '/post/recommended', method: 'get', params, data})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function recommendedShop(params, data) {
|
||||||
|
return request({url: '/shop/recommended', method: 'get', params, data})
|
||||||
|
}
|
||||||
@ -1,65 +0,0 @@
|
|||||||
export default {
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
"name": "小米电视6 65\" OLED 65英寸",
|
|
||||||
"cover": new URL('@/assets/img/goods/g6-0.jpg', import.meta.url).href,
|
|
||||||
imgs:[
|
|
||||||
new URL('../img/goods/g6-0.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g6-1.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g6-2.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g6-3.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g6-4.jpg', import.meta.url).href,
|
|
||||||
],
|
|
||||||
price: 6699,
|
|
||||||
isLowPrice: false,
|
|
||||||
discount: '',
|
|
||||||
sold: 863,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫",
|
|
||||||
"cover": new URL('../img/goods/g1-0.jpg', import.meta.url).href,
|
|
||||||
imgs:[
|
|
||||||
new URL('../img/goods/g1-0.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g1-1.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g1-2.jpg', import.meta.url).href,
|
|
||||||
new URL('../img/goods/g1-3.jpg', import.meta.url).href,
|
|
||||||
],
|
|
||||||
isLowPrice: true,
|
|
||||||
discount: '满4减3',
|
|
||||||
sold: 134,
|
|
||||||
price: 39.9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮",
|
|
||||||
"cover": new URL('../img/goods/g2-0.webp', import.meta.url).href,
|
|
||||||
price: 49.99,
|
|
||||||
isLowPrice: false,
|
|
||||||
discount: '满20减5',
|
|
||||||
sold: 3314,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫",
|
|
||||||
"cover": new URL('../img/goods/g3-0.jpg', import.meta.url).href,
|
|
||||||
price: 22.90,
|
|
||||||
isLowPrice: true,
|
|
||||||
discount: '满10减3',
|
|
||||||
sold: 129,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Redmi K60狠快狠强,狠旗舰!2023,第一台梦幻手机",
|
|
||||||
"cover": new URL('../img/goods/g4-0.png', import.meta.url).href,
|
|
||||||
price: 2999,
|
|
||||||
isLowPrice: true,
|
|
||||||
discount: '',
|
|
||||||
sold: 967,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "小米笔记本Pro X 14",
|
|
||||||
"cover": new URL('../img/goods/g5-0.jpg', import.meta.url).href,
|
|
||||||
price: 6999,
|
|
||||||
isLowPrice: false,
|
|
||||||
discount: '',
|
|
||||||
sold: 473,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -3,12 +3,12 @@
|
|||||||
<div class="DouyinCode" v-if="modelValue">
|
<div class="DouyinCode" v-if="modelValue">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="video-poster">
|
<div class="video-poster">
|
||||||
<img src="../assets/img/poster/1.jpg" class="poster">
|
<img :src="_checkImgUrl(item.video.cover.url_list[0])" class="poster">
|
||||||
</div>
|
</div>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="user">@名字</div>
|
<div class="user">@{{item.author.nickname}}</div>
|
||||||
<div class="title">#窃书不能算偷……窃书!……读书人的事,能算偷么?</div>
|
<div class="title">{{item.desc}}</div>
|
||||||
</div>
|
</div>
|
||||||
<img class="code" src="../assets/img/icon/components/video/douyin-code.jpg" alt="">
|
<img class="code" src="../assets/img/icon/components/video/douyin-code.jpg" alt="">
|
||||||
</div>
|
</div>
|
||||||
@ -43,9 +43,12 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import {_checkImgUrl} from "@/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DouyinCode",
|
name: "DouyinCode",
|
||||||
props: {
|
props: {
|
||||||
|
item:{},
|
||||||
modelValue: false
|
modelValue: false
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@ -55,6 +58,7 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
_checkImgUrl,
|
||||||
cancel() {
|
cancel() {
|
||||||
this.$emit('update:modelValue', false)
|
this.$emit('update:modelValue', false)
|
||||||
}
|
}
|
||||||
@ -87,16 +91,22 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
margin-bottom: 20rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
gap: 20rem;
|
||||||
padding: 10rem;
|
padding: 10rem;
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
font-size: 18rem;
|
font-size: 18rem;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
|
margin-top: 10rem;
|
||||||
font-size: 14rem;
|
font-size: 14rem;
|
||||||
color: var(--second-text-color);
|
color: var(--second-text-color);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box; //作为弹性伸缩盒子模型显示。
|
||||||
|
-webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
|
||||||
|
-webkit-line-clamp: 1; //显示的行
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.code {
|
.code {
|
||||||
@ -134,11 +144,11 @@ export default {
|
|||||||
|
|
||||||
.shares {
|
.shares {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-right: @space-width * 2;
|
margin-bottom: @space-width;
|
||||||
|
gap: 20rem;
|
||||||
|
padding-left: 20rem;
|
||||||
|
|
||||||
.share-to {
|
.share-to {
|
||||||
margin-left: 28rem;
|
|
||||||
margin-bottom: @space-width;
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: @icon-width;
|
width: @icon-width;
|
||||||
@ -159,6 +169,7 @@ export default {
|
|||||||
.cancel {
|
.cancel {
|
||||||
font-size: 16rem;
|
font-size: 16rem;
|
||||||
background: rgb(38, 38, 38);
|
background: rgb(38, 38, 38);
|
||||||
|
color: rgba(white,.8);
|
||||||
padding: 15rem;
|
padding: 15rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="shares list">
|
<div class="shares list">
|
||||||
<template v-if="mode === 'video'">
|
<template v-if="mode === 'video'">
|
||||||
<div class="option" @click.stop="$no">
|
<div class="option" @click.stop="closeShare($emit('ShareToFriend'))">
|
||||||
<img class="avatar" src="../assets/img/icon/components/video/torichang.png" alt="">
|
<img class="avatar" src="../assets/img/icon/components/video/torichang.png" alt="">
|
||||||
<span>转发</span>
|
<span>转发</span>
|
||||||
</div>
|
</div>
|
||||||
@ -51,7 +51,7 @@
|
|||||||
<img class="small" src="../assets/img/icon/components/video/warring.png" alt="">
|
<img class="small" src="../assets/img/icon/components/video/warring.png" alt="">
|
||||||
<span>举报</span>
|
<span>举报</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click.stop="$nav('/home/report',{mode:this.mode})">
|
<div class="option" @click.stop="closeShare($emit('ShareToFriend'))">
|
||||||
<Icon icon="ion:paper-plane"/>
|
<Icon icon="ion:paper-plane"/>
|
||||||
<span>私信朋友</span>
|
<span>私信朋友</span>
|
||||||
</div>
|
</div>
|
||||||
@ -73,7 +73,7 @@
|
|||||||
<span>不感兴趣</span>
|
<span>不感兴趣</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click.stop="closeShare($emit('showDouyinCode'))">
|
<div class="option" @click.stop="closeShare($emit('showDouyinCode'))">
|
||||||
<img class="small" src="../assets/img/icon/components/video/dislike.png" alt="">
|
<Icon icon="tabler:photo"/>
|
||||||
<span>生成图片</span>
|
<span>生成图片</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" @click.stop="$no">
|
<div class="option" @click.stop="$no">
|
||||||
@ -133,7 +133,7 @@ import Check from "./Check";
|
|||||||
import FromBottomDialog from "./dialog/FromBottomDialog";
|
import FromBottomDialog from "./dialog/FromBottomDialog";
|
||||||
import DouyinCode from "./DouyinCode";
|
import DouyinCode from "./DouyinCode";
|
||||||
import {useBaseStore} from "@/store/pinia";
|
import {useBaseStore} from "@/store/pinia";
|
||||||
import {$no} from "@/utils";
|
import {$no, _copy} from "@/utils";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Share",
|
name: "Share",
|
||||||
@ -144,6 +144,7 @@ export default {
|
|||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modelValue: false,
|
modelValue: false,
|
||||||
|
item: {},
|
||||||
videoId: {
|
videoId: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
@ -170,8 +171,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
$no,
|
$no,
|
||||||
@ -180,6 +180,7 @@ export default {
|
|||||||
this.$showLoading()
|
this.$showLoading()
|
||||||
await this.$sleep(500)
|
await this.$sleep(500)
|
||||||
this.$hideLoading()
|
this.$hideLoading()
|
||||||
|
_copy(this.item.share_info.share_link_desc + this.item.share_info.share_url)
|
||||||
//TODO 抖音样式改了
|
//TODO 抖音样式改了
|
||||||
this.$notice('复制成功')
|
this.$notice('复制成功')
|
||||||
},
|
},
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export default {
|
|||||||
},
|
},
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '5rem 5rem 0 0'
|
default: '15rem 15rem 0 0'
|
||||||
},
|
},
|
||||||
tag: {
|
tag: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -218,11 +218,11 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.heng-gang {
|
.heng-gang {
|
||||||
border-radius: 5rem 5rem 0 0;
|
border-radius: 15rem 15rem 0 0;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
height: 20rem;
|
height: 30rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
transform: translateY(-24rem);
|
transform: translateY(-24rem);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -20,57 +20,67 @@
|
|||||||
<p> 您的浏览器不支持 video 标签。</p>
|
<p> 您的浏览器不支持 video 标签。</p>
|
||||||
</video>
|
</video>
|
||||||
<Icon icon="fluent:play-28-filled" class="pause-icon" v-if="!isPlaying"/>
|
<Icon icon="fluent:play-28-filled" class="pause-icon" v-if="!isPlaying"/>
|
||||||
<div class="float" :style="{opacity: isUp?0:1}">
|
<div class="float">
|
||||||
<div :style="{opacity:isMove ? 0:1}" class="normal">
|
<template v-if="isLive">
|
||||||
<template v-if="!commentVisible">
|
<div class="living">点击进入直播间</div>
|
||||||
<ItemToolbar v-model:item="localItem"
|
<ItemDesc
|
||||||
:position="position"
|
:is-live="true"
|
||||||
v-bind="$attrs"
|
v-model:item="localItem"
|
||||||
/>
|
:position="position"
|
||||||
<ItemDesc
|
/>
|
||||||
v-model:item="localItem"
|
</template>
|
||||||
:position="position"
|
<template v-else>
|
||||||
/>
|
<div :style="{opacity:isMove ? 0:1}" class="normal">
|
||||||
</template>
|
<template v-if="!commentVisible">
|
||||||
<div v-if="isMy" class="comment-status">
|
<ItemToolbar v-model:item="localItem"
|
||||||
<div class="comment">
|
:position="position"
|
||||||
<div class="type-comment">
|
v-bind="$attrs"
|
||||||
<img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar">
|
/>
|
||||||
<div class="right">
|
<ItemDesc
|
||||||
<p>
|
v-model:item="localItem"
|
||||||
<span class="name">zzzzz</span>
|
:position="position"
|
||||||
<span class="time">2020-01-20</span>
|
/>
|
||||||
</p>
|
</template>
|
||||||
<p class="text">北京</p>
|
<div v-if="isMy" class="comment-status">
|
||||||
</div>
|
<div class="comment">
|
||||||
</div>
|
<div class="type-comment">
|
||||||
<transition-group name="comment-status" tag="div" class="loveds">
|
|
||||||
<div class="type-loved" :key="i" v-for="i in test">
|
|
||||||
<img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar">
|
<img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar">
|
||||||
<img src="../../assets/img/icon/love.svg" alt="" class="loved">
|
<div class="right">
|
||||||
|
<p>
|
||||||
|
<span class="name">zzzzz</span>
|
||||||
|
<span class="time">2020-01-20</span>
|
||||||
|
</p>
|
||||||
|
<p class="text">北京</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition-group>
|
<transition-group name="comment-status" tag="div" class="loveds">
|
||||||
|
<div class="type-loved" :key="i" v-for="i in test">
|
||||||
|
<img src="../../assets/img/icon/head-image.jpeg" alt="" class="avatar">
|
||||||
|
<img src="../../assets/img/icon/love.svg" alt="" class="loved">
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="progress"
|
||||||
<div class="progress"
|
:class="progressClass"
|
||||||
:class="progressClass"
|
ref="progress"
|
||||||
ref="progress"
|
@click="null"
|
||||||
@click="null"
|
@touchstart="touchstart"
|
||||||
@touchstart="touchstart"
|
@touchmove="touchmove"
|
||||||
@touchmove="touchmove"
|
@touchend="touchend"
|
||||||
@touchend="touchend"
|
>
|
||||||
>
|
<div class="time" v-if="isMove">
|
||||||
<div class="time" v-if="isMove">
|
<span class="currentTime">{{ LUtils.$duration(currentTime) }}</span>
|
||||||
<span class="currentTime">{{ LUtils.$duration(currentTime) }}</span>
|
<span class="duration"> / {{ LUtils.$duration(duration) }}</span>
|
||||||
<span class="duration"> / {{ LUtils.$duration(duration) }}</span>
|
</div>
|
||||||
|
<template v-if="duration > 15 || isMove || !isPlaying">
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="progress-line" :style="durationStyle"></div>
|
||||||
|
<div class="point"></div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="duration > 15 || isMove || !isPlaying">
|
</template>
|
||||||
<div class="bg"></div>
|
|
||||||
<div class="progress-line" :style="durationStyle"></div>
|
|
||||||
<div class="point"></div>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -125,7 +135,7 @@ export default {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isUp: {
|
isLive: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: () => {
|
default: () => {
|
||||||
return false
|
return false
|
||||||
@ -290,29 +300,34 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
click({uniqueId, index, type}) {
|
click({uniqueId, index, type}) {
|
||||||
// console.log(this.position)
|
|
||||||
if (
|
if (
|
||||||
this.position.uniqueId === uniqueId &&
|
this.position.uniqueId === uniqueId &&
|
||||||
this.position.index === index
|
this.position.index === index
|
||||||
) {
|
) {
|
||||||
if (type === EVENT_KEY.ITEM_TOGGLE) {
|
if (this.isLive) {
|
||||||
if (this.status === SlideItemPlayStatus.Play) {
|
if (type === EVENT_KEY.ITEM_TOGGLE) {
|
||||||
this.pause()
|
bus.emit(EVENT_KEY.NAV, {path: '/home/live', query: {id: this.item.id}})
|
||||||
} else {
|
}
|
||||||
this.play()
|
} else {
|
||||||
|
if (type === EVENT_KEY.ITEM_TOGGLE) {
|
||||||
|
if (this.status === SlideItemPlayStatus.Play) {
|
||||||
|
this.pause()
|
||||||
|
} else {
|
||||||
|
this.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type === EVENT_KEY.ITEM_STOP) {
|
||||||
|
this.$refs.video.currentTime = 0
|
||||||
|
this.ignoreWaiting = true
|
||||||
|
this.pause()
|
||||||
|
setTimeout(() => this.ignoreWaiting = false, 300)
|
||||||
|
}
|
||||||
|
if (type === EVENT_KEY.ITEM_PLAY) {
|
||||||
|
this.$refs.video.currentTime = 0
|
||||||
|
this.ignoreWaiting = true
|
||||||
|
this.play()
|
||||||
|
setTimeout(() => this.ignoreWaiting = false, 300)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (type === EVENT_KEY.ITEM_STOP) {
|
|
||||||
this.$refs.video.currentTime = 0
|
|
||||||
this.ignoreWaiting = true
|
|
||||||
this.pause()
|
|
||||||
setTimeout(() => this.ignoreWaiting = false, 300)
|
|
||||||
}
|
|
||||||
if (type === EVENT_KEY.ITEM_PLAY) {
|
|
||||||
this.$refs.video.currentTime = 0
|
|
||||||
this.ignoreWaiting = true
|
|
||||||
this.play()
|
|
||||||
setTimeout(() => this.ignoreWaiting = false, 300)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -713,4 +728,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.living {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
font-size: 18rem;
|
||||||
|
border-radius: 50rem;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
padding: 15rem 20rem;
|
||||||
|
line-height: 1;
|
||||||
|
color: white;
|
||||||
|
top: 70%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@ -22,6 +22,12 @@ const props = defineProps({
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isLive: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@ -43,6 +49,7 @@ const state = reactive({
|
|||||||
<span>{{ props.item.address }}</span>
|
<span>{{ props.item.address }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="live" v-if="props.isLive">直播中</div>
|
||||||
<div class="name mb1r f18 fb" @click.stop="$emit('goUserInfo')">@{{ props.item.author.nickname }}</div>
|
<div class="name mb1r f18 fb" @click.stop="$emit('goUserInfo')">@{{ props.item.author.nickname }}</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{ props.item.desc }}
|
{{ props.item.desc }}
|
||||||
@ -113,6 +120,16 @@ const state = reactive({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.live{
|
||||||
|
border-radius: 3rem;
|
||||||
|
margin-bottom: 10rem;
|
||||||
|
padding: 3rem 6rem;
|
||||||
|
font-size: 11rem;
|
||||||
|
display: inline-flex;
|
||||||
|
background: var(--primary-btn-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.music {
|
.music {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -203,15 +203,16 @@ function getInsEl(item, index, play = false) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return parent
|
return parent
|
||||||
|
} else {
|
||||||
|
const app = createApp({
|
||||||
|
render() {
|
||||||
|
return <SlideItem data-index={index}>{slideVNode}</SlideItem>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const ins = app.mount(parent)
|
||||||
|
appInsMap.set(index, app)
|
||||||
|
return ins.$el
|
||||||
}
|
}
|
||||||
const app = createApp({
|
|
||||||
render() {
|
|
||||||
return <SlideItem data-index={index}>{slideVNode}</SlideItem>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const ins = app.mount(parent)
|
|
||||||
appInsMap.set(index, app)
|
|
||||||
return ins.$el
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchStart(e) {
|
function touchStart(e) {
|
||||||
|
|||||||
@ -78,7 +78,7 @@ async function fetchData() {
|
|||||||
export async function startMock() {
|
export async function startMock() {
|
||||||
mock.onGet(/video\/recommended/).reply(async (config) => {
|
mock.onGet(/video\/recommended/).reply(async (config) => {
|
||||||
let page = getPage2(config.params)
|
let page = getPage2(config.params)
|
||||||
console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length),page)
|
console.log('allRecommendVideos', cloneDeep(allRecommendVideos.length), page)
|
||||||
return [200, {
|
return [200, {
|
||||||
data: {
|
data: {
|
||||||
total: 844,
|
total: 844,
|
||||||
@ -143,7 +143,7 @@ export async function startMock() {
|
|||||||
if (!userVideos.length) {
|
if (!userVideos.length) {
|
||||||
// let r = await fetch(BASE_URL + '/data/user-71158770.json')
|
// let r = await fetch(BASE_URL + '/data/user-71158770.json')
|
||||||
// let r = await fetch(BASE_URL + '/data/user-8357999.json')
|
// let r = await fetch(BASE_URL + '/data/user-8357999.json')
|
||||||
let r = await fetch(BASE_URL + '/data/user-12345xiaolaohu.json')
|
let r = await fetch(BASE_URL + '/data/user_video_list/user-12345xiaolaohu.json')
|
||||||
let list = await r.json()
|
let list = await r.json()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
let userList = cloneDeep(baseStore.users)
|
let userList = cloneDeep(baseStore.users)
|
||||||
@ -243,5 +243,18 @@ export async function startMock() {
|
|||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mock.onGet(/shop\/recommended/).reply(async (config) => {
|
||||||
|
let page = getPage2(config.params)
|
||||||
|
|
||||||
|
let r2 = await fetch(BASE_URL + '/data/goods.json')
|
||||||
|
let v = await r2.json()
|
||||||
|
return [200, {
|
||||||
|
data: {
|
||||||
|
total: v.length,
|
||||||
|
list: v.slice(page.offset, page.limit)
|
||||||
|
}, code: 200
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
setTimeout(fetchData, 1000)
|
setTimeout(fetchData, 1000)
|
||||||
}
|
}
|
||||||
@ -1,16 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="LivePage" ref="page">
|
<div class="LivePage" ref="page">
|
||||||
<div class="live-wrapper">
|
<div class="live-wrapper">
|
||||||
<img src="../../assets/img/poster/1.jpg" alt="">
|
<video
|
||||||
|
src="https://www.douyin.com/aweme/v1/play/?video_id=v0d00fg10000cj1lq4jc77u0ng6s1gt0&line=0&file_id=bed51c00899b458cbc5d8280147c22a1&sign=7749aec7bd62a3760065f60e40fc1867&is_play_url=1&source=PackSourceEnum_PUBLISH"
|
||||||
|
poster="/images/jwWCPZVTIA4IKM-8WipLF.png"
|
||||||
|
preload=""
|
||||||
|
loop=""
|
||||||
|
muted
|
||||||
|
x5-video-player-type="h5-page"
|
||||||
|
x5-video-player-fullscreen="false"
|
||||||
|
webkit-playsinline="true"
|
||||||
|
x5-playsinline="true"
|
||||||
|
playsinline="true"
|
||||||
|
fullscreen="false"
|
||||||
|
autoplay="">
|
||||||
|
<p> 您的浏览器不支持 video 标签。</p>
|
||||||
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<div class="float">
|
<div class="float">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="liver">
|
<div class="liver">
|
||||||
<img class="avatar" src="../../assets/img/icon/avatar/10.png" alt="">
|
<img class="avatar" :src="_checkImgUrl(userinfo.avatar_168x168.url_list[0])" alt="">
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<div class="desc-wrapper">
|
<div class="desc-wrapper">
|
||||||
<div class="name">大司马大司马大司马</div>
|
<div class="name">{{ userinfo.nickname }}</div>
|
||||||
<div class="count">2万本场点赞</div>
|
<div class="count">2万本场点赞</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="follow-btn">关注</div>
|
<div class="follow-btn">关注</div>
|
||||||
@ -58,8 +72,8 @@
|
|||||||
<span>30</span>
|
<span>30</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="name">嘻嘻哈哈</span>
|
<span class="name">{{ i.name}}</span>
|
||||||
<span class="text">{{ i }}</span>
|
<span class="text">{{ i.text }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -85,8 +99,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<base-button @click="sendComment">点击</base-button>
|
<base-button @click="sendComment">点击</base-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -94,6 +106,10 @@
|
|||||||
import BaseButton from "../../components/BaseButton";
|
import BaseButton from "../../components/BaseButton";
|
||||||
import Dom from "../../utils/dom";
|
import Dom from "../../utils/dom";
|
||||||
import {nextTick} from "vue";
|
import {nextTick} from "vue";
|
||||||
|
import {mapState} from "pinia";
|
||||||
|
import {useBaseStore} from "@/store/pinia";
|
||||||
|
import {_checkImgUrl, random} from "@/utils";
|
||||||
|
import Mock from "mockjs";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "LivePage",
|
name: "LivePage",
|
||||||
@ -101,23 +117,25 @@ export default {
|
|||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
timer1: -1,
|
||||||
|
timer2: -1,
|
||||||
|
timer3: -1,
|
||||||
isFollowed: false,
|
isFollowed: false,
|
||||||
list: [
|
list: [],
|
||||||
'asdfasdf',
|
|
||||||
'asdfasdf',
|
|
||||||
'asdfasdf',
|
|
||||||
],
|
|
||||||
barrage: [],
|
barrage: [],
|
||||||
barrageTemplate: () => {
|
barrageTemplate: () => {
|
||||||
|
let name = Mock.mock('@cname')
|
||||||
|
let a = Mock.mock('@csentence')
|
||||||
return `
|
return `
|
||||||
<div class="barrage">
|
<div class="barrage">
|
||||||
<div class="type">管理</div>
|
<div class="type">${name}</div>
|
||||||
<div class="text">感谢老铁送的火箭</div>
|
<div class="text">${a}</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
userJoinedTemplate: () => {
|
userJoinedTemplate: () => {
|
||||||
let src = new URL('../../assets/img/icon/home/level.webp')
|
let src = '/images/icon/love.webp'
|
||||||
|
let name = Mock.mock('@cname')
|
||||||
return `
|
return `
|
||||||
<div class="user-joined">
|
<div class="user-joined">
|
||||||
<div class="level">
|
<div class="level">
|
||||||
@ -126,23 +144,36 @@ export default {
|
|||||||
<span>30</span>
|
<span>30</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="name">嘻嘻哈哈</span>
|
<span class="name">${name}</span>
|
||||||
<span class="text">加入了直播间</span>
|
<span class="text">加入了直播间</span>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
sendGiftTemplate: () => {
|
sendGiftTemplate: () => {
|
||||||
let avatar = new URL('../../assets/img/icon/avatar/3.png')
|
let avatarList = [
|
||||||
let gift = new URL('../../assets/img/icon/home/love.webp')
|
'/images/EPsQ7u4sNnrHC-ix-a9yQ.png',
|
||||||
|
'/images/Xex2IhY-Zm338cNlcGuNW.png',
|
||||||
|
'/images/gddHyRZrdk0Em3RRgVa9g.png',
|
||||||
|
'/images/LJ-8p2jF3HydBD5j28PgQ.png',
|
||||||
|
'/images/KwJ9N7yFjYylfwYeThWjx.png',
|
||||||
|
'/images/EKkC06GI4yXC2mNHMrm46.png',
|
||||||
|
'/images/rlkpmpGPdhYZRJl3J4Xl7.png',
|
||||||
|
'/images/Ge4mMWQoICdpyTyixk3Sf.png',
|
||||||
|
]
|
||||||
|
let avatar = avatarList[random(0, avatarList.length - 1)]
|
||||||
|
let gift = '/images/icon/love.webp'
|
||||||
|
let name = Mock.mock('@cname')
|
||||||
|
let name2 = Mock.mock('@cname')
|
||||||
|
let num = Mock.mock('@integer(60,400)')
|
||||||
return `
|
return `
|
||||||
<div class="send-gift">
|
<div class="send-gift">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img src="${avatar}" alt="" class="avatar">
|
<img src="${avatar}" alt="" class="avatar">
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<div class="name">哈哈哈哈哈哈哈哈哈</div>
|
<div class="name">${name}</div>
|
||||||
<div class="sendto">
|
<div class="sendto">
|
||||||
<span class="send">送</span>
|
<span class="send">送</span>
|
||||||
<span class="to">嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻</span>
|
<span class="to">${name2}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gift-wrapper">
|
<div class="gift-wrapper">
|
||||||
@ -150,7 +181,7 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
x339
|
x${num}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@ -158,25 +189,33 @@ export default {
|
|||||||
page: null,
|
page: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {
|
||||||
|
...mapState(useBaseStore, ['friends', 'userinfo']),
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.page = this.$refs.page
|
this.page = this.$refs.page
|
||||||
// setInterval(async () => {
|
this.timer1 = setInterval(async () => {
|
||||||
// this.sendGift()
|
this.sendGift()
|
||||||
// await this.$sleep(300)
|
await this.$sleep(300)
|
||||||
// this.sendGift()
|
this.sendGift()
|
||||||
// this.joinUser()
|
this.joinUser()
|
||||||
// }, 3000)
|
}, 1000)
|
||||||
// setInterval(async () => {
|
this.timer2 = setInterval(async () => {
|
||||||
// this.sendBarrage()
|
this.sendBarrage()
|
||||||
// }, 5100)
|
}, 1500)
|
||||||
// setInterval(async () => {
|
this.timer3 = setInterval(async () => {
|
||||||
// this.sendComment()
|
this.sendComment()
|
||||||
// }, 500)
|
}, 700)
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
clearInterval(this.timer1)
|
||||||
|
clearInterval(this.timer2)
|
||||||
|
clearInterval(this.timer3)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
_checkImgUrl,
|
||||||
sendGift() {
|
sendGift() {
|
||||||
let page = new Dom(this.page)
|
let page = new Dom(this.page)
|
||||||
let sendGift = new Dom().create(this.sendGiftTemplate())
|
let sendGift = new Dom().create(this.sendGiftTemplate())
|
||||||
@ -188,6 +227,10 @@ export default {
|
|||||||
if (oldSendGift.els.length !== 0) {
|
if (oldSendGift.els.length !== 0) {
|
||||||
top = sendGift.removePx(oldSendGift.css('top')) - 70
|
top = sendGift.removePx(oldSendGift.css('top')) - 70
|
||||||
}
|
}
|
||||||
|
if (top < 100) {
|
||||||
|
top = document.body.clientHeight * .6
|
||||||
|
}
|
||||||
|
console.log('top', top)
|
||||||
sendGift.css('top', top)
|
sendGift.css('top', top)
|
||||||
page.append(sendGift)
|
page.append(sendGift)
|
||||||
},
|
},
|
||||||
@ -210,11 +253,17 @@ export default {
|
|||||||
if (oldBarrages.els.length !== 0) {
|
if (oldBarrages.els.length !== 0) {
|
||||||
top = barrage.removePx(oldBarrages.css('top')) + 20
|
top = barrage.removePx(oldBarrages.css('top')) + 20
|
||||||
}
|
}
|
||||||
|
if (top > document.body.clientHeight * .5) {
|
||||||
|
top = document.body.clientHeight * .35
|
||||||
|
}
|
||||||
barrage.css('top', top)
|
barrage.css('top', top)
|
||||||
page.append(barrage)
|
page.append(barrage)
|
||||||
},
|
},
|
||||||
sendComment() {
|
sendComment() {
|
||||||
this.list.push('评论评论评论评论评论评论评论评论评论评论' + this.list.length)
|
this.list.push({
|
||||||
|
name: Mock.mock('@cname'),
|
||||||
|
text: Mock.mock('@csentence')
|
||||||
|
})
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let comments = this.$refs['comments']
|
let comments = this.$refs['comments']
|
||||||
comments.scrollTo({top: comments.scrollHeight - comments.clientHeight, behavior: 'smooth'})
|
comments.scrollTo({top: comments.scrollHeight - comments.clientHeight, behavior: 'smooth'})
|
||||||
@ -272,6 +321,8 @@ export default {
|
|||||||
.avatar {
|
.avatar {
|
||||||
margin-right: 5rem;
|
margin-right: 5rem;
|
||||||
width: 40rem;
|
width: 40rem;
|
||||||
|
height: 40rem;
|
||||||
|
object-fit: cover;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,6 +468,14 @@ export default {
|
|||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: calc(var(--vh, 1vh) * 100);
|
height: calc(var(--vh, 1vh) * 100);
|
||||||
background: black;
|
background: black;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
video {
|
||||||
|
width: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
|
|||||||
@ -146,6 +146,7 @@
|
|||||||
ref="share"
|
ref="share"
|
||||||
page-id="home-index"
|
page-id="home-index"
|
||||||
@dislike="dislike"
|
@dislike="dislike"
|
||||||
|
:item="state.currentItem"
|
||||||
:videoId="state.recommendList[state.itemIndex]?.id"
|
:videoId="state.recommendList[state.itemIndex]?.id"
|
||||||
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
||||||
@play-feedback="state.showPlayFeedback = true"
|
@play-feedback="state.showPlayFeedback = true"
|
||||||
@ -156,7 +157,9 @@
|
|||||||
|
|
||||||
<PlayFeedback v-model="state.showPlayFeedback"/>
|
<PlayFeedback v-model="state.showPlayFeedback"/>
|
||||||
|
|
||||||
<DouyinCode v-model="state.showDouyinCode"/>
|
<DouyinCode
|
||||||
|
:item="state.currentItem"
|
||||||
|
v-model="state.showDouyinCode"/>
|
||||||
|
|
||||||
<ShareTo v-model:type="state.shareType"
|
<ShareTo v-model:type="state.shareType"
|
||||||
:videoId="state.recommendList[state.itemIndex]?.id"
|
:videoId="state.recommendList[state.itemIndex]?.id"
|
||||||
@ -195,7 +198,7 @@ import SlideItem from '@/components/slide/SlideItem.vue'
|
|||||||
import Comment from "../../components/Comment.vue";
|
import Comment from "../../components/Comment.vue";
|
||||||
import Share from "../../components/Share.vue";
|
import Share from "../../components/Share.vue";
|
||||||
import IndicatorHome from "./components/IndicatorHome.vue";
|
import IndicatorHome from "./components/IndicatorHome.vue";
|
||||||
import {onMounted, onUnmounted, reactive} from "vue";
|
import {onActivated, onDeactivated, onMounted, onUnmounted, reactive} from "vue";
|
||||||
import bus, {EVENT_KEY} from "../../utils/bus";
|
import bus, {EVENT_KEY} from "../../utils/bus";
|
||||||
import {useNav} from "@/utils/hooks/useNav";
|
import {useNav} from "@/utils/hooks/useNav";
|
||||||
import PlayFeedback from "@/pages/home/components/PlayFeedback.vue";
|
import PlayFeedback from "@/pages/home/components/PlayFeedback.vue";
|
||||||
@ -221,6 +224,7 @@ const nav = useNav()
|
|||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
active: true,
|
||||||
baseIndex: 1,
|
baseIndex: 1,
|
||||||
navIndex: 4,
|
navIndex: 4,
|
||||||
test: '',
|
test: '',
|
||||||
@ -253,6 +257,7 @@ function delayShowDialog(cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCurrentItem(item) {
|
function setCurrentItem(item) {
|
||||||
|
if (!state.active) return
|
||||||
// console.log('sss',item,state.baseIndex)
|
// console.log('sss',item,state.baseIndex)
|
||||||
if (state.baseIndex !== 1) return
|
if (state.baseIndex !== 1) return
|
||||||
if (state.currentItem.author.uid !== item.author.uid) {
|
if (state.currentItem.author.uid !== item.author.uid) {
|
||||||
@ -266,21 +271,34 @@ function setCurrentItem(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
bus.on(EVENT_KEY.ENTER_FULLSCREEN, (e) => state.fullScreen = true)
|
bus.on(EVENT_KEY.ENTER_FULLSCREEN, (e) => {
|
||||||
bus.on(EVENT_KEY.EXIT_FULLSCREEN, (e) => state.fullScreen = false)
|
if (!state.active) return
|
||||||
|
state.fullScreen = true
|
||||||
|
})
|
||||||
|
bus.on(EVENT_KEY.EXIT_FULLSCREEN, (e) => {
|
||||||
|
if (!state.active) return
|
||||||
|
state.fullScreen = false
|
||||||
|
})
|
||||||
bus.on(EVENT_KEY.OPEN_COMMENTS, (e) => {
|
bus.on(EVENT_KEY.OPEN_COMMENTS, (e) => {
|
||||||
|
if (!state.active) return
|
||||||
bus.emit(EVENT_KEY.ENTER_FULLSCREEN)
|
bus.emit(EVENT_KEY.ENTER_FULLSCREEN)
|
||||||
state.commentVisible = true
|
state.commentVisible = true
|
||||||
})
|
})
|
||||||
bus.on(EVENT_KEY.CLOSE_COMMENTS, (e) => {
|
bus.on(EVENT_KEY.CLOSE_COMMENTS, (e) => {
|
||||||
|
if (!state.active) return
|
||||||
bus.emit(EVENT_KEY.EXIT_FULLSCREEN)
|
bus.emit(EVENT_KEY.EXIT_FULLSCREEN)
|
||||||
state.commentVisible = false
|
state.commentVisible = false
|
||||||
})
|
})
|
||||||
bus.on(EVENT_KEY.SHOW_SHARE, (e) => {
|
bus.on(EVENT_KEY.SHOW_SHARE, (e) => {
|
||||||
|
if (!state.active) return
|
||||||
state.isSharing = true
|
state.isSharing = true
|
||||||
})
|
})
|
||||||
bus.on(EVENT_KEY.NAV, ({path, query}) => nav(path, query))
|
bus.on(EVENT_KEY.NAV, ({path, query}) => {
|
||||||
|
if (!state.active) return
|
||||||
|
nav(path, query)
|
||||||
|
})
|
||||||
bus.on(EVENT_KEY.GO_USERINFO, () => {
|
bus.on(EVENT_KEY.GO_USERINFO, () => {
|
||||||
|
if (!state.active) return
|
||||||
state.baseIndex = 2
|
state.baseIndex = 2
|
||||||
})
|
})
|
||||||
bus.on(EVENT_KEY.CURRENT_ITEM, setCurrentItem)
|
bus.on(EVENT_KEY.CURRENT_ITEM, setCurrentItem)
|
||||||
@ -290,6 +308,15 @@ onUnmounted(() => {
|
|||||||
bus.offAll()
|
bus.offAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
state.active = true
|
||||||
|
})
|
||||||
|
|
||||||
|
onDeactivated(() => {
|
||||||
|
state.active = false
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
function closeComments() {
|
function closeComments() {
|
||||||
bus.emit(EVENT_KEY.CLOSE_COMMENTS)
|
bus.emit(EVENT_KEY.CLOSE_COMMENTS)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,228 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
|
|
||||||
import {onMounted, onUnmounted, reactive, watch} from "vue";
|
|
||||||
import {_checkImgUrl, _duration, _formatNumber} from "@/utils";
|
|
||||||
import {recommendedVideo} from "@/api/videos";
|
|
||||||
import {useBaseStore} from "@/store/pinia";
|
|
||||||
|
|
||||||
const baseStore = useBaseStore()
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
active: Boolean
|
|
||||||
})
|
|
||||||
|
|
||||||
const p = {
|
|
||||||
onShowComments() {
|
|
||||||
console.log('onShowComments')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const state = reactive({
|
|
||||||
index: 0,
|
|
||||||
list: [],
|
|
||||||
totalSize: 0,
|
|
||||||
pageSize: 10,
|
|
||||||
pageNo: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
function loadMore() {
|
|
||||||
if (!baseStore.loading) {
|
|
||||||
state.pageNo++
|
|
||||||
getData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData(refresh = false) {
|
|
||||||
if (baseStore.loading) return
|
|
||||||
baseStore.loading = true
|
|
||||||
let res = await recommendedVideo({pageNo: refresh ? 0 : state.pageNo, pageSize: state.pageSize})
|
|
||||||
console.log('getSlide4Data-', 'refresh', refresh, res)
|
|
||||||
baseStore.loading = false
|
|
||||||
if (res.code === 200) {
|
|
||||||
state.totalSize = res.data.total
|
|
||||||
if (refresh) {
|
|
||||||
state.list = []
|
|
||||||
}
|
|
||||||
state.list = state.list.concat(res.data.list)
|
|
||||||
} else {
|
|
||||||
state.pageNo--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(() => props.active, n => {
|
|
||||||
if (!state.list.length && n) {
|
|
||||||
baseStore.loading = false
|
|
||||||
getData()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
})
|
|
||||||
onUnmounted(() => {
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="page">
|
|
||||||
<div class="item"
|
|
||||||
:class="[
|
|
||||||
i % 5 === 0 && 'big',
|
|
||||||
i % 5 === 0 ? '' : (i % 2 === 1 && 'l'),
|
|
||||||
i % 5 === 0 ? '' : (i % 2 === 0 && 'r'),
|
|
||||||
]"
|
|
||||||
v-for="(item,i) in state.list">
|
|
||||||
<video
|
|
||||||
controls
|
|
||||||
:poster="_checkImgUrl(item.video.cover.url_list[0])"
|
|
||||||
:src="item.video.play_addr.url_list[0]"
|
|
||||||
></video>
|
|
||||||
<img v-lazy="_checkImgUrl(item.video.cover.url_list[0])" alt="" class="poster">
|
|
||||||
<div class="duration">{{ _duration(item.duration / 1000) }}</div>
|
|
||||||
<div class="title">
|
|
||||||
{{ item.desc }}
|
|
||||||
</div>
|
|
||||||
<div class="bottom">
|
|
||||||
<div class="l">
|
|
||||||
<img v-lazy="_checkImgUrl(item.author.avatar_168x168.url_list[0])" alt="" class="avatar">
|
|
||||||
<div class="name">{{ item.author.nickname }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="r">
|
|
||||||
<Icon icon="icon-park-outline:like"/>
|
|
||||||
<div class="num">{{ _formatNumber(item.statistics.digg_count) }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="less">
|
|
||||||
.page {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
row-gap: 15rem;
|
|
||||||
height: calc(var(--vh, 1vh) * 100 - var(--common-header-height) - var(--footer-height));
|
|
||||||
margin-top: var(--common-header-height);
|
|
||||||
overflow: auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
margin: 0 10rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8rem;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.poster {
|
|
||||||
border-radius: 12rem;
|
|
||||||
width: 100%;
|
|
||||||
height: 140rem;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
video {
|
|
||||||
display: none;
|
|
||||||
height: 220rem;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
height: 36rem;
|
|
||||||
color: white;
|
|
||||||
font-size: 14rem;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box; //作为弹性伸缩盒子模型显示。
|
|
||||||
-webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
|
|
||||||
-webkit-line-clamp: 2; //显示的行
|
|
||||||
}
|
|
||||||
|
|
||||||
.f {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.duration {
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 80rem;
|
|
||||||
right: 10rem;
|
|
||||||
font-size: 13rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
color: gray;
|
|
||||||
.f;
|
|
||||||
font-size: 13rem;
|
|
||||||
|
|
||||||
.l {
|
|
||||||
.f;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box; //作为弹性伸缩盒子模型显示。
|
|
||||||
-webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
|
|
||||||
-webkit-line-clamp: 1; //显示的行
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
@w: 20rem;
|
|
||||||
width: @w;
|
|
||||||
height: @w;
|
|
||||||
object-fit: cover;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.r {
|
|
||||||
word-break: keep-all;
|
|
||||||
.f;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
font-size: 16rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.big {
|
|
||||||
grid-column-start: 1;
|
|
||||||
grid-column-end: 3;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.duration {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.poster {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
video {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
height: unset;
|
|
||||||
-webkit-line-clamp: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title, .bottom {
|
|
||||||
padding: 0 10rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.l {
|
|
||||||
margin-right: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.r {
|
|
||||||
margin-left: 5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -4,17 +4,18 @@
|
|||||||
:class="state.subTypeIsTop?'top':''"
|
:class="state.subTypeIsTop?'top':''"
|
||||||
ref="subTypeRef">
|
ref="subTypeRef">
|
||||||
<div class="card" @touchmove.capture="stop">
|
<div class="card" @touchmove.capture="stop">
|
||||||
<div class="nav-item" v-for="i in 2">
|
<div class="nav-item" v-for="i in store.users">
|
||||||
<img src="@/assets/img/icon/msg-icon9.webp" alt="">
|
<img :src="_checkImgUrl(i.avatar_168x168.url_list[0])" alt="">
|
||||||
<span>美食美食美食美食美食美食美食</span>
|
<span>{{ i.nickname }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-type-notice"
|
<div class="sub-type-notice"
|
||||||
v-if="state.subType===-1 && !state.subTypeVisible"
|
v-if="state.subType===-1 && !state.subTypeVisible"
|
||||||
@click="showSubType">1个直播
|
@click.stop="showSubType">{{store.users.length}}个直播
|
||||||
</div>
|
</div>
|
||||||
<SlideList
|
<SlideList
|
||||||
|
:cbs="{isLive:true}"
|
||||||
:active="props.active"
|
:active="props.active"
|
||||||
:style="{background: 'black',marginTop:state.subTypeVisible?state.subTypeHeight:0}"
|
:style="{background: 'black',marginTop:state.subTypeVisible?state.subTypeHeight:0}"
|
||||||
:api="recommendedVideo"
|
:api="recommendedVideo"
|
||||||
@ -27,10 +28,12 @@
|
|||||||
import SlideItem from '@/components/slide/SlideItem.vue'
|
import SlideItem from '@/components/slide/SlideItem.vue'
|
||||||
import {onMounted, onUnmounted, reactive, ref} from "vue";
|
import {onMounted, onUnmounted, reactive, ref} from "vue";
|
||||||
import bus, {EVENT_KEY} from "@/utils/bus";
|
import bus, {EVENT_KEY} from "@/utils/bus";
|
||||||
import Utils from "@/utils";
|
import Utils, {_checkImgUrl} from "@/utils";
|
||||||
import SlideList from './SlideList.vue';
|
import SlideList from './SlideList.vue';
|
||||||
import {recommendedVideo} from "@/api/videos";
|
import {recommendedVideo} from "@/api/videos";
|
||||||
|
import {useBaseStore} from "@/store/pinia";
|
||||||
|
|
||||||
|
const store = useBaseStore()
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
active: {
|
active: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -104,6 +107,8 @@ onUnmounted(() => {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
gap: 10rem;
|
||||||
|
padding-left: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-item {
|
.nav-item {
|
||||||
@ -126,7 +131,7 @@ onUnmounted(() => {
|
|||||||
img {
|
img {
|
||||||
width: @width;
|
width: @width;
|
||||||
height: @width;
|
height: @width;
|
||||||
margin-bottom: 5rem;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,6 +62,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 消息-->
|
||||||
|
<div class="message" @click="$nav('/message/chat')">
|
||||||
|
<div class="avatar on-line">
|
||||||
|
<img src="../../assets/img/icon/avatar/2.png" alt="" class="head-image">
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="left">
|
||||||
|
<div class="name">
|
||||||
|
<span>{{ userinfo.nickname }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
哈哈哈哈哈哈
|
||||||
|
<div class="point"></div>
|
||||||
|
10-10
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<!-- <div class="not-read"></div>-->
|
||||||
|
<!-- <img class="camera" src="../../assets/img/icon/close-white.png" alt="">-->
|
||||||
|
<!-- <img class="arrow" src="../../assets/img/icon/close-white.png" alt="">-->
|
||||||
|
<div class="badge">12</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 抖音小助手-->
|
<!-- 抖音小助手-->
|
||||||
<div class="message" @click="$nav('/message/douyin-helper')">
|
<div class="message" @click="$nav('/message/douyin-helper')">
|
||||||
<div class="avatar">
|
<div class="avatar">
|
||||||
@ -195,30 +219,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 消息-->
|
|
||||||
<div class="message" @click="$nav('/message/chat')">
|
|
||||||
<div class="avatar on-line">
|
|
||||||
<img src="../../assets/img/icon/avatar/2.png" alt="" class="head-image">
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="left">
|
|
||||||
<div class="name">
|
|
||||||
<span>{{ userinfo.nickname }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="detail">
|
|
||||||
哈哈哈哈哈哈
|
|
||||||
<div class="point"></div>
|
|
||||||
10-10
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<!-- <div class="not-read"></div>-->
|
|
||||||
<!-- <img class="camera" src="../../assets/img/icon/close-white.png" alt="">-->
|
|
||||||
<!-- <img class="arrow" src="../../assets/img/icon/close-white.png" alt="">-->
|
|
||||||
<div class="badge">12</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<NoMore/>
|
<NoMore/>
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,7 @@ export default {
|
|||||||
.avatar {
|
.avatar {
|
||||||
margin-top: 55rem;
|
margin-top: 55rem;
|
||||||
width: 55rem;
|
width: 55rem;
|
||||||
|
height: 55rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-bottom: 20rem;
|
margin-bottom: 20rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -219,36 +219,7 @@ export default {
|
|||||||
avatar: '../../assets/img/icon/head-image.jpg'
|
avatar: '../../assets/img/icon/head-image.jpg'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: MESSAGE_TYPE.RED_PACKET,
|
|
||||||
state: AUDIO_STATE.NORMAL,
|
|
||||||
mode: RED_PACKET_MODE.MULTIPLE,
|
|
||||||
data: {
|
|
||||||
money: 5.11,
|
|
||||||
title: '大吉大利',
|
|
||||||
state: '未领取'
|
|
||||||
},
|
|
||||||
time: '2021-01-02 21:21',
|
|
||||||
user: {
|
|
||||||
id: '2739632844317827',
|
|
||||||
avatar: '../../assets/img/icon/head-image.jpg'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: MESSAGE_TYPE.RED_PACKET,
|
|
||||||
state: AUDIO_STATE.NORMAL,
|
|
||||||
mode: RED_PACKET_MODE.SINGLE,
|
|
||||||
data: {
|
|
||||||
money: 5.11,
|
|
||||||
title: '大吉大利',
|
|
||||||
state: '已过期'
|
|
||||||
},
|
|
||||||
time: '2021-01-02 21:21',
|
|
||||||
user: {
|
|
||||||
id: 1,
|
|
||||||
avatar: '../../assets/img/icon/head-image.jpg'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
type: MESSAGE_TYPE.MEME,
|
type: MESSAGE_TYPE.MEME,
|
||||||
state: AUDIO_STATE.NORMAL,
|
state: AUDIO_STATE.NORMAL,
|
||||||
@ -441,6 +412,36 @@ export default {
|
|||||||
avatar: '../../../assets/img/icon/head-image.jpg'
|
avatar: '../../../assets/img/icon/head-image.jpg'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: MESSAGE_TYPE.RED_PACKET,
|
||||||
|
state: AUDIO_STATE.NORMAL,
|
||||||
|
mode: RED_PACKET_MODE.MULTIPLE,
|
||||||
|
data: {
|
||||||
|
money: 5.11,
|
||||||
|
title: '大吉大利',
|
||||||
|
state: '未领取'
|
||||||
|
},
|
||||||
|
time: '2021-01-02 21:21',
|
||||||
|
user: {
|
||||||
|
id: '2739632844317827',
|
||||||
|
avatar: '../../assets/img/icon/head-image.jpg'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: MESSAGE_TYPE.RED_PACKET,
|
||||||
|
state: AUDIO_STATE.NORMAL,
|
||||||
|
mode: RED_PACKET_MODE.SINGLE,
|
||||||
|
data: {
|
||||||
|
money: 5.11,
|
||||||
|
title: '大吉大利',
|
||||||
|
state: '已过期'
|
||||||
|
},
|
||||||
|
time: '2021-01-02 21:21',
|
||||||
|
user: {
|
||||||
|
id: 1,
|
||||||
|
avatar: '../../assets/img/icon/head-image.jpg'
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
typing: false,
|
typing: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -466,15 +467,19 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
$('img').on('load', this.scrollBottom)
|
||||||
this.scrollBottom()
|
this.scrollBottom()
|
||||||
},
|
},
|
||||||
|
unmounted() {
|
||||||
|
$('img').off('load', this.scrollBottom)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
_checkImgUrl,
|
_checkImgUrl,
|
||||||
scrollBottom() {
|
scrollBottom() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let wrapper = this.$refs.msgWrapper
|
let wrapper = this.$refs.msgWrapper
|
||||||
console.log('wrapper.clientHeight', wrapper.clientHeight)
|
// console.log('wrapper.clientHeight', wrapper.clientHeight)
|
||||||
console.log('wrapper.scrollHeight', wrapper.scrollHeight)
|
// console.log('wrapper.scrollHeight', wrapper.scrollHeight)
|
||||||
wrapper.scrollTo({top: wrapper.scrollHeight - wrapper.clientHeight})
|
wrapper.scrollTo({top: wrapper.scrollHeight - wrapper.clientHeight})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -804,6 +809,7 @@ export default {
|
|||||||
.avatar {
|
.avatar {
|
||||||
margin-top: 60rem;
|
margin-top: 60rem;
|
||||||
width: 55rem;
|
width: 55rem;
|
||||||
|
height: 55rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-bottom: 20rem;
|
margin-bottom: 20rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<SlideVerticalInfinite
|
<SlideVerticalInfinite
|
||||||
v-if="false"
|
|
||||||
ref="listRef"
|
ref="listRef"
|
||||||
v-love="state.uniqueId"
|
v-love="state.uniqueId"
|
||||||
:id="state.uniqueId"
|
:id="state.uniqueId"
|
||||||
@ -31,7 +30,7 @@
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="comment">
|
<div class="comment">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<img :src="_checkImgUrl(store.userinfo.avatar_168x168.url_list[0])" class="avatar" alt=""/>
|
<img :src="_checkImgUrl(baseStore.userinfo.avatar_168x168.url_list[0])" class="avatar" alt=""/>
|
||||||
<span>善语结善缘,恶言伤人心</span>
|
<span>善语结善缘,恶言伤人心</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
@ -41,22 +40,92 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Comment page-id="video-detail"
|
||||||
|
:video-id="state.currentItem.aweme_id"
|
||||||
|
v-model="state.commentVisible"
|
||||||
|
@close="closeComments"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Share v-model="state.isSharing"
|
||||||
|
ref="share"
|
||||||
|
page-id="video-detail"
|
||||||
|
@dislike="dislike"
|
||||||
|
:item="state.currentItem"
|
||||||
|
:videoId="state.recommendList[state.itemIndex]?.id"
|
||||||
|
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
||||||
|
@play-feedback="state.showPlayFeedback = true"
|
||||||
|
@shareToFriend="delayShowDialog(e => state.shareToFriend = true)"
|
||||||
|
@showDouyinCode="state.showDouyinCode = true"
|
||||||
|
@download="state.shareType = 9"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlayFeedback v-model="state.showPlayFeedback"/>
|
||||||
|
|
||||||
|
<DouyinCode
|
||||||
|
:item="state.currentItem"
|
||||||
|
v-model="state.showDouyinCode"/>
|
||||||
|
|
||||||
|
<ShareTo v-model:type="state.shareType"
|
||||||
|
:videoId="state.recommendList[state.itemIndex]?.id"
|
||||||
|
:canDownload="state.recommendList[state.itemIndex]?.canDownload"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FollowSetting
|
||||||
|
v-model:currentItem="state.currentItem"
|
||||||
|
@showChangeNote="delayShowDialog( e => state.showChangeNote = true)"
|
||||||
|
@showBlockDialog="delayShowDialog(e => state.showBlockDialog = true)"
|
||||||
|
@showShare="delayShowDialog( e => state.isSharing = true)"
|
||||||
|
v-model="state.showFollowSetting"/>
|
||||||
|
|
||||||
|
<FollowSetting2
|
||||||
|
v-model:currentItem="state.currentItem"
|
||||||
|
@cancelFollow="$refs.uploader.cancelFollow()"
|
||||||
|
v-model="state.showFollowSetting2"/>
|
||||||
|
|
||||||
|
<BlockDialog v-model="state.showBlockDialog"/>
|
||||||
|
|
||||||
|
<ConfirmDialog
|
||||||
|
title="设置备注名"
|
||||||
|
ok-text="确认"
|
||||||
|
v-model:visible="state.showChangeNote"
|
||||||
|
>
|
||||||
|
<Search mode="light" v-model="state.test" :isShowSearchIcon="false"/>
|
||||||
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
<ShareToFriend v-model="state.shareToFriend"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="jsx">
|
||||||
import {onMounted, reactive} from "vue";
|
import Comment from "../../components/Comment.vue";
|
||||||
|
import Share from "../../components/Share.vue";
|
||||||
|
import {onMounted, onUnmounted, reactive} from "vue";
|
||||||
|
import bus, {EVENT_KEY} from "../../utils/bus";
|
||||||
|
import {useNav} from "@/utils/hooks/useNav";
|
||||||
|
import PlayFeedback from "@/pages/home/components/PlayFeedback.vue";
|
||||||
|
import ShareTo from "@/pages/home/components/ShareTo.vue";
|
||||||
|
import DouyinCode from "../../components/DouyinCode.vue";
|
||||||
|
import FollowSetting from "@/pages/home/components/FollowSetting.vue";
|
||||||
|
import BlockDialog from "../message/components/BlockDialog.vue";
|
||||||
|
import Search from "../../components/Search.vue";
|
||||||
|
import ConfirmDialog from "../../components/dialog/ConfirmDialog.vue";
|
||||||
|
import FollowSetting2 from "@/pages/home/components/FollowSetting2.vue";
|
||||||
|
import ShareToFriend from "@/pages/home/components/ShareToFriend.vue";
|
||||||
|
import {DefaultUser} from "@/utils/const_var";
|
||||||
|
import {_checkImgUrl} from "@/utils";
|
||||||
import {useBaseStore} from "@/store/pinia";
|
import {useBaseStore} from "@/store/pinia";
|
||||||
import SlideVerticalInfinite from "@/components/slide/SlideVerticalInfinite.vue";
|
import SlideVerticalInfinite from "@/components/slide/SlideVerticalInfinite.vue";
|
||||||
import {useSlideListItemRender} from "@/utils/hooks/useSlideListItemRender";
|
import {useSlideListItemRender} from "@/utils/hooks/useSlideListItemRender";
|
||||||
import {_checkImgUrl} from "@/utils";
|
import {useRouter} from "vue-router";
|
||||||
import {useNav} from "@/utils/hooks/useNav";
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'VideoDetail'
|
name: 'VideoDetail'
|
||||||
})
|
})
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const store = useBaseStore()
|
const router = useRouter()
|
||||||
|
|
||||||
|
const baseStore = useBaseStore()
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
dialog: {
|
dialog: {
|
||||||
shareToFriend: false,
|
shareToFriend: false,
|
||||||
@ -65,7 +134,33 @@ const data = reactive({
|
|||||||
},
|
},
|
||||||
isMy: false
|
isMy: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
baseIndex: 1,
|
||||||
|
navIndex: 4,
|
||||||
|
test: '',
|
||||||
|
recommendList: [],
|
||||||
|
isSharing: false,
|
||||||
|
canMove: true,
|
||||||
|
shareType: -1,
|
||||||
|
showPlayFeedback: false,
|
||||||
|
showShareDuoshan: false,
|
||||||
|
showShareDialog: false,
|
||||||
|
showShare2WeChatZone: false,
|
||||||
|
showDouyinCode: false,
|
||||||
|
showFollowSetting: false,
|
||||||
|
showFollowSetting2: false,
|
||||||
|
showBlockDialog: false,
|
||||||
|
showChangeNote: false,
|
||||||
|
shareToFriend: false,
|
||||||
|
|
||||||
|
commentVisible: false,
|
||||||
|
fullScreen: false,
|
||||||
|
currentItem: {
|
||||||
|
author: DefaultUser,
|
||||||
|
isRequest: false,
|
||||||
|
aweme_list: [],
|
||||||
|
},
|
||||||
index: 0,
|
index: 0,
|
||||||
list: [],
|
list: [],
|
||||||
uniqueId: 'uniqueId_2',
|
uniqueId: 'uniqueId_2',
|
||||||
@ -73,18 +168,72 @@ const state = reactive({
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
pageNo: 0,
|
pageNo: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const render = useSlideListItemRender()
|
const render = useSlideListItemRender()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// console.log('s', store.routeData)
|
// console.log('s', store.routeData)
|
||||||
state.index = store.routeData.index
|
state.index = baseStore.routeData.index
|
||||||
state.list = store.routeData.list
|
state.list = baseStore.routeData.list
|
||||||
// console.log('sss', state.list[state.index])
|
// console.log('sss', state.list[state.index])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function delayShowDialog(cb) {
|
||||||
|
setTimeout(cb, 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCurrentItem(item) {
|
||||||
|
// console.log('sss',item,state.baseIndex)
|
||||||
|
if (state.baseIndex !== 1) return
|
||||||
|
if (state.currentItem.author.uid !== item.author.uid) {
|
||||||
|
state.currentItem = {
|
||||||
|
...item,
|
||||||
|
isRequest: false,
|
||||||
|
aweme_list: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log('item', item)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
bus.on(EVENT_KEY.ENTER_FULLSCREEN, (e) => state.fullScreen = true)
|
||||||
|
bus.on(EVENT_KEY.EXIT_FULLSCREEN, (e) => state.fullScreen = false)
|
||||||
|
bus.on(EVENT_KEY.OPEN_COMMENTS, (e) => {
|
||||||
|
bus.emit(EVENT_KEY.ENTER_FULLSCREEN)
|
||||||
|
state.commentVisible = true
|
||||||
|
})
|
||||||
|
bus.on(EVENT_KEY.CLOSE_COMMENTS, (e) => {
|
||||||
|
bus.emit(EVENT_KEY.EXIT_FULLSCREEN)
|
||||||
|
state.commentVisible = false
|
||||||
|
})
|
||||||
|
bus.on(EVENT_KEY.SHOW_SHARE, (e) => {
|
||||||
|
state.isSharing = true
|
||||||
|
})
|
||||||
|
bus.on(EVENT_KEY.NAV, ({path, query}) => nav(path, query))
|
||||||
|
bus.on(EVENT_KEY.GO_USERINFO, () => {
|
||||||
|
router.back()
|
||||||
|
})
|
||||||
|
bus.on(EVENT_KEY.CURRENT_ITEM, setCurrentItem)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
bus.offAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
function closeComments() {
|
||||||
|
bus.emit(EVENT_KEY.CLOSE_COMMENTS)
|
||||||
|
}
|
||||||
|
|
||||||
|
function dislike() {
|
||||||
|
// listRef.value.dislike(state.list[1])
|
||||||
|
// state.list[state.index] = state.list[1]
|
||||||
|
// Utils.$notice('操作成功,将减少此类视频的推荐')
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import "../../assets/less/index";
|
|
||||||
|
|
||||||
#video-detail {
|
#video-detail {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -199,4 +348,5 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
201
src/pages/other/VideoDetail2.vue
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<div id="video-detail">
|
||||||
|
<div class="search-wrapper">
|
||||||
|
<Icon class="back" icon="icon-park-outline:left" @click="$back"/>
|
||||||
|
<div class="search" @click="nav('/home/search')">
|
||||||
|
<div class="left">
|
||||||
|
<Icon class="icon" icon="ion:search"/>
|
||||||
|
<span>搜你想看的</span>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<span class="gang">|</span>
|
||||||
|
<span class="txt">搜索</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<SlideVerticalInfinite
|
||||||
|
ref="listRef"
|
||||||
|
v-love="state.uniqueId"
|
||||||
|
:id="state.uniqueId"
|
||||||
|
:uniqueId="state.uniqueId"
|
||||||
|
name="main"
|
||||||
|
:active="true"
|
||||||
|
:loading="false"
|
||||||
|
v-model:index="state.index"
|
||||||
|
:render="render"
|
||||||
|
:list="state.list"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="comment">
|
||||||
|
<div class="left">
|
||||||
|
<img :src="_checkImgUrl(store.userinfo.avatar_168x168.url_list[0])" class="avatar" alt=""/>
|
||||||
|
<span>善语结善缘,恶言伤人心</span>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<Icon icon="tabler:photo"/>
|
||||||
|
<Icon icon="ion:at-sharp"/>
|
||||||
|
<Icon icon="fa-regular:laugh"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {onMounted, reactive} from "vue";
|
||||||
|
import {useBaseStore} from "@/store/pinia";
|
||||||
|
import SlideVerticalInfinite from "@/components/slide/SlideVerticalInfinite.vue";
|
||||||
|
import {useSlideListItemRender} from "@/utils/hooks/useSlideListItemRender";
|
||||||
|
import {_checkImgUrl} from "@/utils";
|
||||||
|
import {useNav} from "@/utils/hooks/useNav";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'VideoDetail'
|
||||||
|
})
|
||||||
|
const nav = useNav()
|
||||||
|
const store = useBaseStore()
|
||||||
|
const data = reactive({
|
||||||
|
dialog: {
|
||||||
|
shareToFriend: false,
|
||||||
|
permissionDialog: false,
|
||||||
|
test: false,
|
||||||
|
},
|
||||||
|
isMy: false
|
||||||
|
})
|
||||||
|
const state = reactive({
|
||||||
|
index: 0,
|
||||||
|
list: [],
|
||||||
|
uniqueId: 'uniqueId_2',
|
||||||
|
totalSize: 0,
|
||||||
|
pageSize: 10,
|
||||||
|
pageNo: 0,
|
||||||
|
})
|
||||||
|
const render = useSlideListItemRender()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// console.log('s', store.routeData)
|
||||||
|
state.index = store.routeData.index
|
||||||
|
state.list = store.routeData.list
|
||||||
|
// console.log('sss', state.list[state.index])
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
@import "../../assets/less/index";
|
||||||
|
|
||||||
|
#video-detail {
|
||||||
|
position: fixed;
|
||||||
|
font-size: 14rem;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: black;
|
||||||
|
|
||||||
|
.search-wrapper {
|
||||||
|
z-index: 9;
|
||||||
|
position: fixed;
|
||||||
|
top: 8rem;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
padding: 0 15rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15rem;
|
||||||
|
|
||||||
|
.back {
|
||||||
|
color: white;
|
||||||
|
font-size: 30rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
color: var(--second-btn-color);
|
||||||
|
display: flex;
|
||||||
|
background: rgba(171, 169, 169, 0.4);
|
||||||
|
border-radius: 8rem;
|
||||||
|
flex: 1;
|
||||||
|
padding: 8rem;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
font-size: 15rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: gainsboro;
|
||||||
|
gap: 5rem;
|
||||||
|
line-height: 1;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 14rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rem;
|
||||||
|
font-size: 16rem;
|
||||||
|
|
||||||
|
.gang {
|
||||||
|
color: dimgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
height: calc(var(--vh, 1vh) * 100 - var(--footer-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
height: var(--footer-height);
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
color: var(--second-text-color);
|
||||||
|
z-index: 9;
|
||||||
|
width: 95%;
|
||||||
|
height: 75%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background: rgb(37, 37, 37);
|
||||||
|
border-radius: 50rem;
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
height: 70%;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.left;
|
||||||
|
gap: 15rem;
|
||||||
|
font-size: 24rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<div class="slide-imgs">
|
<div class="slide-imgs">
|
||||||
<SlideHorizontal v-model:index="state.index">
|
<SlideHorizontal v-model:index="state.index">
|
||||||
<SlideItem v-for="item in state.detail.imgs">
|
<SlideItem v-for="item in state.detail.imgs">
|
||||||
<img :src="item" alt="">
|
<img v-lazy="_checkImgUrl('goods/'+item)" alt=""/>
|
||||||
</SlideItem>
|
</SlideItem>
|
||||||
</SlideHorizontal>
|
</SlideHorizontal>
|
||||||
<div class="index">{{ state.index + 1 }}/{{ state.detail.imgs.length }}</div>
|
<div class="index">{{ state.index + 1 }}/{{ state.detail.imgs.length }}</div>
|
||||||
@ -66,20 +66,20 @@
|
|||||||
<div class="price-wrap">
|
<div class="price-wrap">
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<span class="symbol">¥</span>
|
<span class="symbol">¥</span>
|
||||||
<span class="int">8</span>
|
<span class="int">{{ state.detail.price }}</span>
|
||||||
<span class="decimal">.8</span>
|
<!-- <span class="decimal">.8</span>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="discount">
|
<div class="discount">
|
||||||
<span class="text">热销款券后</span>
|
<span class="text">热销款券后</span>
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<span class="symbol">¥</span>
|
<span class="symbol">¥</span>
|
||||||
<span class="int">5</span>
|
<span class="int">{{ state.detail.real_price }}</span>
|
||||||
<span class="decimal">.9</span>
|
<!-- <span class="decimal">.9</span>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="name">{{ state.detail.name }}</div>
|
<div class="name">{{ state.detail.name }}</div>
|
||||||
<div class="num">已售20/100</div>
|
<div class="num">已售{{ state.detail.sold }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card desc-wrapper">
|
<div class="card desc-wrapper">
|
||||||
@ -145,9 +145,9 @@
|
|||||||
<div class="tag">推荐 <span class="gray">18</span></div>
|
<div class="tag">推荐 <span class="gray">18</span></div>
|
||||||
<div class="tag">商用服务好 <span class="gray">15</span></div>
|
<div class="tag">商用服务好 <span class="gray">15</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="comment" v-for="i in 2">
|
<div class="comment">
|
||||||
<header>
|
<header>
|
||||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
<img :src="_checkImgUrl('2S9bbgb-Sf2kIdSTxoeTw.png')" alt="" class="avatar">
|
||||||
<span class="gray">花***栽</span>
|
<span class="gray">花***栽</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="w">
|
<div class="w">
|
||||||
@ -159,14 +159,31 @@
|
|||||||
china款/超值【买る双+送2双】共5双
|
china款/超值【买る双+送2双】共5双
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
<img :src="_checkImgUrl('NYEfuYS-LVZ620UYgQNAM.png')" alt="" class="avatar">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="comment">
|
||||||
|
<header>
|
||||||
|
<img :src="_checkImgUrl('9Tx6cZkUOoHqPkbETUZ5Y.png')" alt="" class="avatar">
|
||||||
|
<span class="gray">花***栽</span>
|
||||||
|
</header>
|
||||||
|
<div class="w">
|
||||||
|
<div class="left">
|
||||||
|
<div class="d">
|
||||||
|
东西不错质量也很好 性价比很高 良心商家就冲这图必须给好评
|
||||||
|
</div>
|
||||||
|
<div class="c2">
|
||||||
|
china款/超值【买る双+送2双】共5双
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img :src="_checkImgUrl('2b2rpive_RVzDrYgo-F9K.png')" alt="" class="avatar">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card shop">
|
<div class="card shop">
|
||||||
<header>
|
<header>
|
||||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
<img :src="_checkImgUrl('LJ-8p2jF3HydBD5j28PgQ.png')" alt="" class="avatar">
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="l">
|
<div class="l">
|
||||||
<div class="name">店铺名</div>
|
<div class="name">店铺名</div>
|
||||||
@ -207,9 +224,36 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<div class="item" v-for="i in 4">
|
<div class="item">
|
||||||
<img src="https://cdn.seovx.com/?mom=302" alt="" class="avatar">
|
<img :src="_checkImgUrl('/goods/g6-0.jpg')" alt="" class="avatar">
|
||||||
<div class="name">【热销中】袜子男潮流百搭中筒袜子袜子男潮流百搭中筒袜子</div>
|
<div class="name">小米电视6 65" OLED 65英寸</div>
|
||||||
|
<div class="price">
|
||||||
|
<span class="symbol">¥</span>
|
||||||
|
<span class="int">8</span>
|
||||||
|
<span class="decimal">.8</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img :src="_checkImgUrl('/goods/g1-0.jpg')" alt="" class="avatar">
|
||||||
|
<div class="name">红白撞色条纹软糯针织上衣女2022年秋季新款甜美减龄短款毛衣开衫</div>
|
||||||
|
<div class="price">
|
||||||
|
<span class="symbol">¥</span>
|
||||||
|
<span class="int">8</span>
|
||||||
|
<span class="decimal">.8</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img :src="_checkImgUrl('/goods/g2-0.webp')" alt="" class="avatar">
|
||||||
|
<div class="name">森马t恤男2023男士纯棉上衣白色情侣装凉感短袖打底衫纯色体恤潮</div>
|
||||||
|
<div class="price">
|
||||||
|
<span class="symbol">¥</span>
|
||||||
|
<span class="int">8</span>
|
||||||
|
<span class="decimal">.8</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img :src="_checkImgUrl('/goods/g3-0.jpg')" alt="" class="avatar">
|
||||||
|
<div class="name">ins潮牌长袖t恤男宽松纯色内搭上衣潮牌百搭秋冬季潮流帅气打底衫</div>
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<span class="symbol">¥</span>
|
<span class="symbol">¥</span>
|
||||||
<span class="int">8</span>
|
<span class="int">8</span>
|
||||||
@ -221,7 +265,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="img-list" v-if="true">
|
<div class="img-list">
|
||||||
<header>
|
<header>
|
||||||
<div class="l"></div>
|
<div class="l"></div>
|
||||||
<span class="gray">商品详情</span>
|
<span class="gray">商品详情</span>
|
||||||
@ -229,7 +273,7 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="imgs">
|
<div class="imgs">
|
||||||
<img v-lazy="`https://cdn.seovx.com/?mom=302&d=${i}`" alt="" class="avatar" v-for="i in 5">
|
<img v-lazy="_checkImgUrl('goods/'+i)" alt="" class="avatar" v-for="i in state.detail.imgs">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -254,34 +298,39 @@
|
|||||||
你可以还会喜欢
|
你可以还会喜欢
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div v-masonry class="goods-list"
|
<ScrollList
|
||||||
:class="{fixed:state.fixed}"
|
class="Scroll"
|
||||||
transition-duration="0s"
|
:api="recommendedShop"
|
||||||
item-selector=".goods">
|
>
|
||||||
<div v-masonry-tile class="goods"
|
<template v-slot="{list}">
|
||||||
@click="nav('/shop/detail')"
|
<WaterfallList :list="list">
|
||||||
v-for="(item, index) in state.list">
|
<template v-slot="{item}">
|
||||||
<div class="item">
|
<div class="goods"
|
||||||
<img class="poster" v-lazy="Utils.$imgPreview(item.cover)"/>
|
@click="nav('/shop/detail',{},item)">
|
||||||
<div class="bottom">
|
<div class="item">
|
||||||
<div class="desc">
|
<img class="poster" v-lazy="_checkImgUrl('goods/'+item.cover)"/>
|
||||||
{{ item.name }}
|
<div class="bottom">
|
||||||
</div>
|
<div class="desc">
|
||||||
<div class="discounts" v-if="item.discount">{{ item.discount }}</div>
|
{{ item.name }}
|
||||||
<div class="info">
|
</div>
|
||||||
<div class="price">
|
<div class="discounts" v-if="item.discount">{{ item.discount }}</div>
|
||||||
¥
|
<div class="info">
|
||||||
<div class="big">{{ item.price }}</div>
|
<div class="price">
|
||||||
|
¥
|
||||||
|
<div class="big">{{ item.price }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="num">已售{{ item.sold }}件</div>
|
||||||
|
</div>
|
||||||
|
<div class="low" v-if="item.isLowPrice">
|
||||||
|
近30天低价
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="num">已售{{ item.sold }}件</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="low" v-if="item.isLowPrice">
|
</template>
|
||||||
近30天低价
|
</WaterfallList>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</ScrollList>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -312,19 +361,21 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
|
import SlideHorizontal from "@/components/slide/SlideHorizontal.vue";
|
||||||
import SlideItem from "@/components/slide/SlideItem.vue";
|
import SlideItem from "@/components/slide/SlideItem.vue";
|
||||||
import {reactive, ref} from "vue";
|
import {onMounted, onUnmounted, reactive, ref} from "vue";
|
||||||
import goods from "@/assets/data/goods";
|
|
||||||
import {useNav} from "@/utils/hooks/useNav";
|
import {useNav} from "@/utils/hooks/useNav";
|
||||||
import Utils from "@/utils";
|
import {_checkImgUrl} from "@/utils";
|
||||||
|
import {useBaseStore} from "@/store/pinia";
|
||||||
|
import {recommendedShop} from "@/api/user";
|
||||||
|
import WaterfallList from "@/components/WaterfallList.vue";
|
||||||
|
import ScrollList from "@/components/ScrollList.vue";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: 'GoodsDetail'
|
||||||
|
})
|
||||||
|
|
||||||
let activeIndexs = ref([])
|
let activeIndexs = ref([])
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const props = defineProps({
|
const store = useBaseStore()
|
||||||
id: {
|
|
||||||
type: String,
|
|
||||||
default: () => ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let page = ref()
|
let page = ref()
|
||||||
let header = ref()
|
let header = ref()
|
||||||
let headerShadow = ref()
|
let headerShadow = ref()
|
||||||
@ -341,9 +392,10 @@ function scroll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
detail: goods.list[1],
|
detail: {
|
||||||
|
imgs: []
|
||||||
|
},
|
||||||
index: 0,
|
index: 0,
|
||||||
list: goods.list,
|
|
||||||
listEl: null,
|
listEl: null,
|
||||||
fixed: false
|
fixed: false
|
||||||
})
|
})
|
||||||
@ -356,6 +408,15 @@ function toggle(i) {
|
|||||||
activeIndexs.value.push(i)
|
activeIndexs.value.push(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('r', store.routeData.imgs)
|
||||||
|
state.detail = store.routeData
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
console.log('onUnmounted')
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@ -946,7 +1007,6 @@ function toggle(i) {
|
|||||||
|
|
||||||
& > header {
|
& > header {
|
||||||
padding: 15rem;
|
padding: 15rem;
|
||||||
padding-bottom: 5rem;
|
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
font-size: 15rem;
|
font-size: 15rem;
|
||||||
}
|
}
|
||||||
@ -959,14 +1019,13 @@ function toggle(i) {
|
|||||||
|
|
||||||
@p: 5rem;
|
@p: 5rem;
|
||||||
|
|
||||||
.goods-list {
|
.Scroll {
|
||||||
padding-bottom: 20rem;
|
padding: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods {
|
.goods {
|
||||||
width: 50%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 5rem;
|
margin-bottom: 10rem;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
border-radius: 8rem;
|
border-radius: 8rem;
|
||||||
|
|||||||
@ -13,106 +13,105 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Scroll class="Scroll"
|
<ScrollList
|
||||||
fixedHeight="100"
|
class="Scroll"
|
||||||
@fixed="e=>state.fixed = e"
|
:api="recommendedShop"
|
||||||
@pulldown="loadData">
|
>
|
||||||
<div class="wrapper">
|
<template v-slot="{list}">
|
||||||
<div class="card">
|
<div class="top-card">
|
||||||
<div class="options">
|
<div class="card">
|
||||||
<div class="option" @click="$no">
|
<div class="options">
|
||||||
<Icon icon="lets-icons:order-light"/>
|
<div class="option" @click="$no">
|
||||||
<div>我的订单</div>
|
<Icon icon="lets-icons:order-light"/>
|
||||||
</div>
|
<div>我的订单</div>
|
||||||
<div class="option" @click="$no">
|
</div>
|
||||||
<Icon icon="material-symbols-light:charging-station-outline"/>
|
<div class="option" @click="$no">
|
||||||
<div>手机充值</div>
|
<Icon icon="material-symbols-light:charging-station-outline"/>
|
||||||
</div>
|
<div>手机充值</div>
|
||||||
<div class="option" @click="$no">
|
</div>
|
||||||
<Icon icon="lucide:message-square-quote"/>
|
<div class="option" @click="$no">
|
||||||
<div>购物消息</div>
|
<Icon icon="system-uicons:message" />
|
||||||
</div>
|
<div>购物消息</div>
|
||||||
<div class="option" @click="$no">
|
</div>
|
||||||
<Icon icon="fluent:location-16-regular"/>
|
<div class="option" @click="$no">
|
||||||
<div>小时达</div>
|
<Icon icon="fluent:location-16-regular"/>
|
||||||
</div>
|
<div>小时达</div>
|
||||||
<div class="option" @click="$no">
|
</div>
|
||||||
<Icon icon="ri:refund-2-fill"/>
|
<div class="option" @click="$no">
|
||||||
<div>退款/售后</div>
|
<Icon icon="dashicons:money-alt" />
|
||||||
</div>
|
<div>退款/售后</div>
|
||||||
<div class="option" @click="$no">
|
</div>
|
||||||
<Icon icon="icon-park-outline:clothes-turtleneck"/>
|
<div class="option" @click="$no">
|
||||||
<div>潮流服饰</div>
|
<Icon icon="icon-park-outline:clothes-turtleneck"/>
|
||||||
|
<div>潮流服饰</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card" style="margin-bottom: 5rem;">
|
||||||
<div class="card" style="margin-bottom: 5rem;">
|
<div class="baiyibutie">
|
||||||
<div class="baiyibutie">
|
<div class="item">
|
||||||
<div class="item">
|
<img src="@/assets/img/icon/shop/baiyibutie.png" alt="">
|
||||||
<img src="@/assets/img/icon/shop/baiyibutie.png" alt="">
|
<span>38节补贴</span>
|
||||||
<span>38节补贴</span>
|
</div>
|
||||||
</div>
|
<div class="item">
|
||||||
<div class="item">
|
<img src="@/assets/img/icon/shop/1.webp" alt="">
|
||||||
<img src="@/assets/img/icon/shop/1.webp" alt="">
|
<span class="price">
|
||||||
<span class="price">
|
|
||||||
<span class="m">¥</span>
|
<span class="m">¥</span>
|
||||||
<span>470</span>
|
<span>470</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<img src="@/assets/img/icon/shop/2.webp" alt="">
|
<img src="@/assets/img/icon/shop/2.webp" alt="">
|
||||||
<span class="price">
|
<span class="price">
|
||||||
<span class="m">¥</span>
|
<span class="m">¥</span>
|
||||||
<span>699</span>
|
<span>699</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<img src="@/assets/img/icon/shop/3.png" alt="">
|
<img src="@/assets/img/icon/shop/3.png" alt="">
|
||||||
<span class="price">
|
<span class="price">
|
||||||
<span class="m">¥</span>
|
<span class="m">¥</span>
|
||||||
<span>8.8</span>
|
<span>8.8</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<img src="@/assets/img/icon/shop/4.jpg" alt="">
|
<img src="@/assets/img/icon/shop/4.jpg" alt="">
|
||||||
<span class="price">
|
<span class="price">
|
||||||
<span class="m">¥</span>
|
<span class="m">¥</span>
|
||||||
<span>2.99</span>
|
<span>2.99</span>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<WaterfallList :list="list">
|
||||||
|
<template v-slot="{item}">
|
||||||
<div v-masonry class="goods-list"
|
<div class="goods"
|
||||||
:class="{fixed:state.fixed}"
|
@click="nav('/shop/detail',{},item)">
|
||||||
transition-duration="0s"
|
<div class="item">
|
||||||
item-selector=".goods">
|
<img class="poster" v-lazy="_checkImgUrl('goods/'+item.cover)"/>
|
||||||
<div v-masonry-tile class="goods"
|
<div class="bottom">
|
||||||
@click="nav('/shop/detail')"
|
<div class="desc">
|
||||||
v-for="(item, index) in state.list">
|
{{ item.name }}
|
||||||
<div class="item">
|
</div>
|
||||||
<img class="poster" :src="Utils.$imgPreview(item.cover)"/>
|
<div class="discounts" v-if="item.discount">{{ item.discount }}</div>
|
||||||
<div class="bottom">
|
<div class="info">
|
||||||
<div class="desc">
|
<div class="price">
|
||||||
{{ item.name }}
|
¥
|
||||||
</div>
|
<div class="big">{{ item.price }}</div>
|
||||||
<div class="discounts" v-if="item.discount">{{ item.discount }}</div>
|
</div>
|
||||||
<div class="info">
|
<div class="num">已售{{ item.sold }}件</div>
|
||||||
<div class="price">
|
</div>
|
||||||
¥
|
<div class="low" v-if="item.isLowPrice">
|
||||||
<div class="big">{{ item.price }}</div>
|
近30天低价
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="num">已售{{ item.sold }}件</div>
|
|
||||||
</div>
|
|
||||||
<div class="low" v-if="item.isLowPrice">
|
|
||||||
近30天低价
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</WaterfallList>
|
||||||
</div>
|
</template>
|
||||||
</Scroll>
|
</ScrollList>
|
||||||
<Footer v-bind:init-tab="2"
|
<Footer v-bind:init-tab="2"
|
||||||
:is-white="true"
|
:is-white="true"
|
||||||
style="position: fixed;left: 0;"/>
|
style="position: fixed;left: 0;"/>
|
||||||
@ -124,9 +123,10 @@
|
|||||||
|
|
||||||
import {onMounted, reactive} from "vue";
|
import {onMounted, reactive} from "vue";
|
||||||
import {useNav} from "@/utils/hooks/useNav";
|
import {useNav} from "@/utils/hooks/useNav";
|
||||||
import Utils, {$no} from "@/utils";
|
import {$no, _checkImgUrl} from "@/utils";
|
||||||
import Scroll from "@/components/Scroll.vue";
|
import ScrollList from "@/components/ScrollList.vue";
|
||||||
import goods from "@/assets/data/goods";
|
import {recommendedShop} from "@/api/user";
|
||||||
|
import WaterfallList from "@/components/WaterfallList.vue";
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Shop'
|
name: 'Shop'
|
||||||
@ -134,15 +134,10 @@ defineOptions({
|
|||||||
|
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
list: goods.list,
|
|
||||||
listEl: null,
|
listEl: null,
|
||||||
fixed: false
|
fixed: false
|
||||||
})
|
})
|
||||||
|
|
||||||
function loadData() {
|
|
||||||
console.log('loadData')
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -155,13 +150,11 @@ onMounted(() => {
|
|||||||
#Shop {
|
#Shop {
|
||||||
font-size: 14rem;
|
font-size: 14rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: @fColor;
|
background: #f8f8f8;
|
||||||
background: #f1f1f1;
|
padding: 10rem;
|
||||||
padding: 10rem 5rem;
|
|
||||||
color: black;
|
color: black;
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
padding: 0 5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
@ -174,12 +167,13 @@ onMounted(() => {
|
|||||||
margin-bottom: 10rem;
|
margin-bottom: 10rem;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
font-size: 22rem;
|
color: gray;
|
||||||
|
font-size: 20rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
border: 1rem solid rgb(140, 48, 74);
|
border: 2rem solid red;
|
||||||
border-radius: 8rem;
|
border-radius: 12rem;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0 10rem;
|
padding: 0 10rem;
|
||||||
padding-right: 3rem;
|
padding-right: 3rem;
|
||||||
@ -200,7 +194,7 @@ onMounted(() => {
|
|||||||
background: rgb(242, 62, 92);
|
background: rgb(242, 62, 92);
|
||||||
padding: 0 10rem;
|
padding: 0 10rem;
|
||||||
height: 85%;
|
height: 85%;
|
||||||
border-radius: 6rem;
|
border-radius: 10rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -284,16 +278,15 @@ onMounted(() => {
|
|||||||
background: @fColor;
|
background: @fColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@p: 5rem;
|
.top-card {
|
||||||
|
margin-bottom: 10rem;
|
||||||
.goods-list {
|
|
||||||
padding-bottom: 20rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@p: 5rem;
|
||||||
|
|
||||||
.goods {
|
.goods {
|
||||||
width: 50%;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 5rem;
|
margin-bottom: 10rem;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
border-radius: 8rem;
|
border-radius: 8rem;
|
||||||
|
|||||||