Commit bda714ef by haojie

1

parent dceb07d8
This source diff could not be displayed because it is too large. You can view the blob instead.
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.5 3L6.5 12L15.5 21" stroke="#696F8C" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
\ No newline at end of file
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.0892 17.8016C22.1207 16.8939 22.9629 15.9589 23.5523 15.2433C24.0051 14.6935 24.2316 14.4186 24.2316 14C24.2316 13.5814 24.0051 13.3065 23.5523 12.7567C21.8955 10.7452 18.2413 7 13.9996 7C12.927 7 11.892 7.23946 10.9174 7.62981L13.7935 10.506C13.8617 10.502 13.9304 10.5 13.9996 10.5C15.9326 10.5 17.4996 12.067 17.4996 14C17.4996 14.0692 17.4976 14.1379 17.4936 14.2061L21.0892 17.8016ZM11.0936 12.0487C10.7185 12.6062 10.4996 13.2775 10.4996 14C10.4996 15.933 12.0666 17.5 13.9996 17.5C14.722 17.5 15.3934 17.2811 15.9509 16.906L18.6424 19.5975C17.2425 20.4217 15.6664 21 13.9996 21C9.75788 21 6.10363 17.2548 4.44686 15.2433C3.99401 14.6935 3.76758 14.4186 3.76758 14C3.76758 13.5814 3.99401 13.3065 4.44686 12.7567C5.26698 11.761 6.57655 10.3404 8.20455 9.15965L11.0936 12.0487Z" fill="#B9BDCA"/>
<path d="M5.83301 2.3335L24.4997 21.0002" stroke="#B9BDCA" stroke-width="2"/>
</svg>
\ No newline at end of file
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.2731 14C24.2731 13.6466 24.0798 13.4072 23.6931 12.9284C22.1093 10.9673 18.366 7 14.0003 7C9.63468 7 5.89132 10.9673 4.30753 12.9284C3.92087 13.4072 3.72754 13.6466 3.72754 14C3.72754 14.3534 3.92087 14.5928 4.30753 15.0716C5.89132 17.0327 9.63468 21 14.0003 21C18.366 21 22.1093 17.0327 23.6931 15.0716C24.0798 14.5928 24.2731 14.3534 24.2731 14ZM14.0003 17.5C15.9333 17.5 17.5003 15.933 17.5003 14C17.5003 12.067 15.9333 10.5 14.0003 10.5C12.0673 10.5 10.5003 12.067 10.5003 14C10.5003 15.933 12.0673 17.5 14.0003 17.5Z" fill="#CCD2E3"/>
</svg>
\ No newline at end of file
<svg width="8" height="8" viewBox="0 0 8 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.57262 6.8386L7.7619 3.33886C8.21066 2.84636 7.86209 2.05469 7.1946 2.05469H0.814642C0.148563 2.05469 -0.201411 2.84636 0.247346 3.33886L3.43803 6.83719C3.74285 7.17164 4.26781 7.17164 4.57262 6.8386Z" fill="#696F8C"/>
</svg>
\ No newline at end of file
...@@ -58,7 +58,7 @@ const props = withDefaults( ...@@ -58,7 +58,7 @@ const props = withDefaults(
.dja(); .dja();
} }
.ball-beat > div { .ball-beat > div {
background-color: #4999ff; background-color: #00dddd;
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 100% !important; border-radius: 100% !important;
......
<template>
<div class="custom-cards">
<img class="card-img" :src="img" alt="" />
<div class="card-body">
<div class="title">{{ title }}</div>
<div class="content">{{ content }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
// 首页card
const props = defineProps<{
img: string;
title: string;
content: string;
}>();
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-cards {
background: #2f2f2f;
border: 1px solid #302e2f;
border-radius: 15px;
display: flex;
box-sizing: border-box;
cursor: pointer;
.card-img {
width: 160px;
height: 160px;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
}
.card-body {
color: #ffffff;
padding: 0 12px;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-evenly;
.title {
font-weight: 700;
font-size: @font-size-20;
}
.content {
font-weight: 300;
font-size: @font-size-14;
// 强制换行
word-break: break-all;
}
}
}
</style>
<template>
<div class="custom-products-card">
<img :src="img" class="swiper_image" />
<div class="silde-box-footer">
<div class="title">{{ title }}</div>
<div class="content">{{ content }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
img: string;
title: string;
content: string;
}>();
// 产品页card-轮播图card共用
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-products-card {
width: 339px;
height: 240px;
display: flex;
flex-direction: column;
cursor: pointer;
.silde-box-footer {
background-color: #302e2f;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
padding: 0 12px;
box-sizing: border-box;
color: #ffffff;
border-bottom-left-radius: 15px;
border-bottom-right-radius: 15px;
.title {
font-size: @font-size-20;
font-style: normal;
font-weight: 700;
}
.content {
font-style: normal;
font-weight: 300;
font-size: @font-size-14;
}
}
.swiper_image {
height: 87px;
width: 100%;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
}
}
</style>
<template>
<div class="custom-select-box">
<TSelect
v-model="SelectValue"
:placeholder="placeholder"
:popupProps="{
overlayClassName: 'custom-select-popup',
}"
>
<t-option
v-for="item in options"
:key="item.value"
:value="item.value"
:label="item.label"
></t-option>
</TSelect>
</div>
</template>
<script lang="ts" setup>
import { Select as TSelect, Option as TOption } from 'tdesign-vue-next';
import { ref, watch } from 'vue';
const props = withDefaults(
defineProps<{
options: any[];
modelValue: number | string;
width?: string;
placeholder?: string;
}>(),
{
width: '50%',
placeholder: '请选择',
}
);
const emit = defineEmits(['update:modelValue']);
const SelectValue = ref('');
watch(
() => SelectValue.value,
(v) => {
emit('update:modelValue', v);
}
);
watch(
() => props.modelValue,
(v) => {
SelectValue.value = v;
}
);
</script>
<style lang="less">
.custom-select-popup {
border: none;
box-shadow: none;
.t-popup__content {
border: none;
box-shadow: none;
}
.t-select__list {
background: #181818;
box-shadow: none;
.t-select-option {
color: white;
--ripple-color: #00dddd;
}
.t-select-option__hover,
.t-is-selected {
color: #00dddd;
background: rgba(0, 0, 0, 0.3) !important;
}
}
}
.custom-select-box {
flex: 1;
.t-select__wrap {
width: 100%;
height: 48px;
.t-select-input {
height: 100%;
.t-input__wrap {
height: 100%;
.t-input {
height: 100%;
border-radius: 8px;
background: #181818;
border: none;
.t-input__inner {
text-align: center;
color: #ffffff;
&::placeholder {
color: #888fa1;
}
}
}
.t-is-focused {
border: 1px solid #00dddd;
box-shadow: none;
}
.t-fake-arrow {
color: #00dddd;
}
.t-fake-arrow--active {
}
}
}
}
}
</style>
<template> <template>
<div class="custom-input-global"> <div class="custom-input-global">
<div <div
class="custom-input-box" class="custom-input-box custom-before-line"
:class="{ 'custom-input-error': ruleError.status }" :class="{ 'custom-input-error': ruleError.status }"
> >
<slot name="leftIcon"> <slot name="leftIcon">
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
@focus="onInputFocus" @focus="onInputFocus"
@blur="onInputBlur" @blur="onInputBlur"
@input="numberInput(input_value)" @input="numberInput(input_value)"
:style="{ 'text-align': align }"
/> />
<slot name="rightIcon"> <slot name="rightIcon">
<span v-if="type === 'password'" class="custom-pwd-hide-button"> <span v-if="type === 'password'" class="custom-pwd-hide-button">
...@@ -68,11 +69,13 @@ const props = withDefaults( ...@@ -68,11 +69,13 @@ const props = withDefaults(
disabled?: boolean; disabled?: boolean;
needSelect?: boolean; needSelect?: boolean;
selectList?: any; selectList?: any;
align?: string;
}>(), }>(),
{ {
// 输入框类型 // 输入框类型
type: 'text', type: 'text',
placeholder: '', align: 'center',
placeholder: '请输入',
needSelect: false, needSelect: false,
selectList: [], selectList: [],
// rules: [], // rules: [],
...@@ -219,13 +222,16 @@ watch( ...@@ -219,13 +222,16 @@ watch(
<style lang="less"> <style lang="less">
@import '@/style/flex.less'; @import '@/style/flex.less';
@import '@/style/variables.less';
@import '@/style/line.less';
.custom-input-global { .custom-input-global {
height: 100%; height: 100%;
.custom-input-box { .custom-input-box {
width: 370px;
height: 48px; height: 48px;
background: var(--theme-color-15); background: #181818;
/* 背景线条 */ /* 背景线条 */
border: 1px solid var(--theme-color-19); // border: 0.5px solid #b1b5c4;
border-radius: 8px; border-radius: 8px;
transition: all 0.3s; transition: all 0.3s;
position: relative; position: relative;
...@@ -240,6 +246,11 @@ watch( ...@@ -240,6 +246,11 @@ watch(
padding-left: 12px; padding-left: 12px;
background: transparent; background: transparent;
color: var(--theme-color-4); color: var(--theme-color-4);
&::placeholder {
font-weight: 500;
font-size: @font-size-14;
color: #888fa1;
}
} }
.left-input-icon { .left-input-icon {
.da(); .da();
...@@ -278,7 +289,7 @@ watch( ...@@ -278,7 +289,7 @@ watch(
.custom-input-rule { .custom-input-rule {
color: #f05451; color: #f05451;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: @font-size-12;
line-height: 26px; line-height: 26px;
padding-left: 4px; padding-left: 4px;
min-height: 26px; min-height: 26px;
......
@import '@/style/variables.less';
.custom-t-loading { .custom-t-loading {
.t-icon-loading { .t-icon-loading {
font-size: 18px; font-size: @font-size-18;
} }
} }
<template>
<div class="custom-recommend">
<div class="recommend-title">{{ label }}</div>
<div class="recommend-content">
<template v-for="(item, index) in list" :key="index">
<CustomCard
:img="item.img"
:title="item.title"
:content="item.content"
@click="toGenerate(item)"
></CustomCard>
</template>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import CustomCard from '@/components/card.vue';
import { useRouter } from 'vue-router';
const props = defineProps<{
list: any[];
label: string;
}>();
const router = useRouter();
const toGenerate = (item: any) => {
// 判断类型跳转页面
console.log(item);
const url = router.resolve({
path: '/CopywritingGeneration',
});
window.open(url.href);
};
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-recommend {
margin-top: 30px;
padding: 0 48px;
box-sizing: border-box;
.recommend-title {
font-weight: 700;
font-size: @font-size-20;
color: #ffffff;
}
.recommend-content {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
row-gap: 30px;
margin-top: 20px;
box-sizing: border-box;
& > * {
width: 48%;
}
}
}
</style>
// 网站名称
export const Web_name = 'SILKR';
// 邮箱正则
export const emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,8}){1,2}$/;
// 邀请码
let dddcode = '79o0';
// 记住密码存入本地的key--
export const remember_password_phone = 'remember_phone';
export const remember_password_email = 'remember_email';
<template>
<div>
<t-popup
placement="left-bottom"
overlayClassName="user-popup"
destroy-on-close
trigger="click"
>
<template #content>
<div class="s-header-user-info-dropdown">
<div class="small-userinfo">
<div class="header">
<img class="avatar" :src="imgs.avatar" alt="" />
<span class="user-name">username</span>
</div>
<div class="user-options-box">
<template v-for="item in OptionsList" :key="item.value">
<div class="user-option">
<div
class="real-option"
:class="{
active: route.path == item.value,
}"
>
{{ item.label }}
</div>
</div>
</template>
</div>
<div class="line"></div>
<div class="logout-box">退出登录</div>
</div>
</div>
</template>
<div class="user-info">
<img :src="imgs.avatar" alt="" />
</div>
</t-popup>
</div>
</template>
<script setup lang="ts">
import { MessagePlugin, Popup as TPopup } from 'tdesign-vue-next';
import { useRoute, useRouter } from 'vue-router';
const imgs = {
avatar: new URL('../assets/svg/header/avatar.svg', import.meta.url).href,
};
const route = useRoute();
const router = useRouter();
// 选项列表
const OptionsList = [
{
label: '个人信息',
value: 'UserInfo',
},
{
label: '创作记录',
value: 'CreationRecord',
},
{
label: '产品订单',
value: 'ProductOrders',
},
{
label: '合作咨询',
value: 'CooperationConsulting',
},
];
// 点击不同选项
const gotoMember = (label: string) => {
if (label === 'install') {
return;
}
const resUrl = router.resolve({
path: label,
});
window.open(resUrl.href);
};
// 退出登录和去登陆
const logout = () => {
if (true) {
router.push({
path: '/login',
});
} else {
// 退出
if (true) {
MessagePlugin.success('退出成功');
}
}
};
</script>
<style lang="less">
@import '@/style/variables.less';
@import '@/style/flex.less';
.user-info {
.da();
cursor: pointer;
.up-icon {
padding-left: 12px;
}
}
.user-popup {
.t-popup__content {
padding: 0;
margin: 0;
border-radius: @main-border-radius;
background: #181818;
box-shadow: none;
border: none;
}
}
.s-header-user-info-dropdown {
width: 200px;
background: #181818;
border: 1px solid #464646;
border-radius: @main-border-radius;
.small-userinfo {
height: 100%;
.header {
width: 100%;
height: 45px;
border-bottom: 1px solid #464646;
display: flex;
align-items: center;
padding: 0 12px;
.avatar {
width: 30px;
height: 30px;
}
.user-name {
padding-left: 8px;
color: white;
font-weight: 600;
font-size: @font-size-14;
}
}
.user-options-box {
padding: 4px 0;
.user-option {
font-weight: 600;
font-size: @font-size-14;
padding: 6px;
box-sizing: border-box;
color: white;
height: 45px;
.real-option {
width: 100%;
height: 100%;
display: flex;
align-items: center;
padding-left: 12px;
cursor: pointer;
}
.active {
background: #393939;
border-radius: 8px;
}
}
}
.line {
display: flex;
justify-content: center;
height: 1px;
&::after {
content: '';
display: inline-block;
width: 125px;
border: 1px solid #464646;
}
}
.logout-box {
height: 45px;
display: flex;
justify-content: center;
align-items: center;
color: #d6d6d6;
font-weight: 600;
font-size: @font-size-14;
cursor: pointer;
}
}
}
</style>
<template> <template>
<div class="custom-layout"> <div class="custom-layout">
<Header v-if="route.meta.header"></Header> <Header v-if="route.meta.header"></Header>
<div class="custom-content"> <div class="custom-content narrow-scrollbar">
<router-view v-slot="{ Component }"> <div class="center-box">
<component :is="Component" /> <router-view v-slot="{ Component }">
</router-view> <component :is="Component" />
</router-view>
</div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import Header from "./header.vue"; import Header from './header.vue';
import { useRoute } from "vue-router"; import { useRoute } from 'vue-router';
const route = useRoute(); const route = useRoute();
</script> </script>
<style lang="less"> <style lang="less">
@import "@/style/flex.less"; @import '@/style/flex.less';
.custom-layout { .custom-layout {
height: 100%; height: 100%;
.dj(); .dj();
...@@ -27,10 +29,12 @@ const route = useRoute(); ...@@ -27,10 +29,12 @@ const route = useRoute();
flex: 1; flex: 1;
max-height: calc(100vh - 60px); max-height: calc(100vh - 60px);
overflow: auto; overflow: auto;
box-sizing: border-box; .center-box {
width: 1597px; margin: 0 auto;
max-width: 100vw; width: 1597px;
margin: 0 auto; max-width: 100vw;
box-sizing: border-box;
}
} }
} }
</style> </style>
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
{{ item.label }} {{ item.label }}
</div> </div>
</div> </div>
<!-- <div class="layout-head-right"> <div class="layout-head-right">
<t-button v-if="token" class="logout" @click="logout"> 退出 </t-button> <UserDropdown></UserDropdown>
</div> --> </div>
</div> </div>
</template> </template>
...@@ -26,11 +26,13 @@ import { useStore } from 'vuex'; ...@@ -26,11 +26,13 @@ import { useStore } from 'vuex';
import { useLogout } from '@/utils/api/userApi'; import { useLogout } from '@/utils/api/userApi';
import { MessagePlugin, Button as TButton } from 'tdesign-vue-next'; import { MessagePlugin, Button as TButton } from 'tdesign-vue-next';
import { watch } from 'vue'; import { watch } from 'vue';
import UserDropdown from './UserDropdown.vue';
const store = useStore(); const store = useStore();
const token = computed(() => store.getters['user/token']); const token = computed(() => store.getters['user/token']);
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const currentBtn = ref(route.path); const currentBtn = ref(route.path);
watch( watch(
() => route.path, () => route.path,
(v) => { (v) => {
...@@ -102,18 +104,19 @@ const changeBtn = (item: any) => { ...@@ -102,18 +104,19 @@ const changeBtn = (item: any) => {
<style lang="less"> <style lang="less">
@import '@/style/flex.less'; @import '@/style/flex.less';
@import '@/style/variables.less';
.custom-layout-head { .custom-layout-head {
height: 67px; height: 67px;
background: #181818; background: #181818;
border-bottom: 1px solid #464646; border-bottom: 1px solid #464646;
.dja(space-between); .dja(space-between);
padding: 0 12px; padding: 0 20px;
.layout-head-left { .layout-head-left {
.da(); .da();
span { span {
font-style: normal; font-style: normal;
font-weight: 800; font-weight: 800;
font-size: 40px; font-size: @font-size-40;
color: #e6e6e6; color: #e6e6e6;
line-height: 48px; line-height: 48px;
white-space: nowrap; white-space: nowrap;
...@@ -122,7 +125,7 @@ const changeBtn = (item: any) => { ...@@ -122,7 +125,7 @@ const changeBtn = (item: any) => {
margin-left: 50px; margin-left: 50px;
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: #ffffff; color: #ffffff;
transition: all 0.1s; transition: all 0.1s;
cursor: pointer; cursor: pointer;
......
<template>
<div class="custom-copywriting-generation">
<img class="tip-box" :src="imgs.tips" alt="" />
<div class="interaction-form">
<div class="basic-info">
<div class="label">*基础填写</div>
<div class="value">
<template v-for="item in AdminData.list" :key="item.name">
<template v-if="item.component_type == 'input'">
<CustomInput
v-model="item.value"
:type="item.type"
:placeholder="item.placeholder"
></CustomInput>
</template>
<template v-else-if="item.component_type == 'select'">
<CustomSelect
:options="item.options"
v-model="item.value"
:placeholder="item.placeholder"
></CustomSelect>
</template>
</template>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import CustomSelect from '@/components/custom/Select.vue';
import CustomInput from '@/components/custom/input/index.vue';
import { onBeforeMount, reactive } from 'vue';
const imgs = {
tips: new URL('../../assets/img/tips.png', import.meta.url).href,
};
// 后台配置的输入类型--input-select-textarea
// type-1是input,2是select,3是长文本输入
const AdminData = reactive({
list: [],
});
// 获取后台配置的组件
const getAdminComponent = async () => {
try {
// let res:any = await ddd();
// if(res.data){
// }
let list = [
{
type: 'text',
name: 'url',
label: '链接',
value: null,
span: 24,
placeholder: '输入链接',
// component_type: 'input',
},
// 下拉选择
{
type: 'select',
options: [
{
label: '第一个',
value: 1,
},
{
label: '第二个',
value: 2,
},
],
// 可设置默认值
value: 1,
},
];
// 修改数据
list.forEach((item: any) => {
if (item.type == 'text') {
item.component_type = 'input';
} else if (item.type == 'select') {
item.component_type = 'select';
} else if (item.type == 'textarea') {
// 多行文本输入框
item.component_type = 'textarea';
}
// 判断value的值
if (!item.value) {
item.value = '';
}
});
AdminData.list = list;
console.log(AdminData.list);
} catch (e) {
console.log(e);
}
};
onBeforeMount(async () => {
// 获取组件列表
await getAdminComponent();
});
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-copywriting-generation {
margin-top: @page-margin-top;
display: flex;
.interaction-form {
background: #2d2d2d;
border: 1px solid #565656;
border-radius: 18px;
flex: 1;
margin-left: 12px;
padding: 12px;
box-sizing: border-box;
.basic-info {
.label {
margin: 4px 0 12px 0;
color: #b1b5c4;
font-weight: 300;
font-size: @font-size-12;
}
.value {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
row-gap: 30px;
& > * {
margin: 0 12px;
}
}
}
}
}
</style>
<template>
<div class="custom-product-detail">
<ModuleCard label="亚马逊工具" :list="ProductList.list"></ModuleCard>
<Animation v-show="loading"></Animation>
</div>
</template>
<script lang="ts" setup>
import { useRoute } from 'vue-router';
import { onMounted, reactive, ref } from 'vue';
import { show_message } from '@/utils/tdesign_tool';
import ModuleCard from '@/components/modulecard.vue';
import Animation from '@/components/Animation.vue';
// 会带一个id
const route = useRoute();
const params_id = route.params.id;
const loading = ref(false);
// 产品列表
const ProductList = reactive({
list: [],
});
// 获取当前分类所有产品
const getallproduct = () => {
try {
if (!params_id) {
show_message('没有类目id');
return;
}
// let res: any = await ddd();
// console.log(res);
} catch (e) {
console.log(e);
}
};
onMounted(() => {
// 获取数据
getallproduct();
// 假数据生成
for (let i = 0; i < 20; i++) {
ProductList.list.push({
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content:
'你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好你好',
});
}
});
</script>
<style lang="less">
.custom-product-detail {
padding-bottom: 40px;
box-sizing: border-box;
}
</style>
@import '@/style/variables.less';
.custom-home-swiper { .custom-home-swiper {
width: 100%; width: 100%;
display: flex; display: flex;
...@@ -7,16 +8,10 @@ ...@@ -7,16 +8,10 @@
.swiper-slide { .swiper-slide {
display: flex; display: flex;
justify-content: center; justify-content: center;
.custom-silde-box {
width: 339px;
height: 100%;
.swiper_image {
height: 100%;
}
}
} }
} }
.prev-next { .prev-next {
cursor: pointer; cursor: pointer;
margin: 0 12px;
} }
} }
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
class="swiper-no-swiping" class="swiper-no-swiping"
:slidesPerView="4" :slidesPerView="4"
:loop="true" :loop="true"
:centeredSlides="false"
:loopAdditionalSlides="2"
:preventClicksPropagation="true" :preventClicksPropagation="true"
:loopFillGroupWithBlank="true" :loopFillGroupWithBlank="true"
:modules="modules" :modules="modules"
...@@ -23,10 +25,14 @@ ...@@ -23,10 +25,14 @@
disableOnInteraction: false, disableOnInteraction: false,
}" }"
> >
<!-- @click="goDetail(item)" -->
<SwiperSlide v-for="(item, index) in ScrollList.list" :key="index"> <SwiperSlide v-for="(item, index) in ScrollList.list" :key="index">
<div class="custom-silde-box" @click="goDetail(item)"> <CustomCardTwo
<img :src="item.img" class="swiper_image" /> @click="goDetail(item)"
</div> :img="item.img"
:title="item.title"
:content="item.content"
></CustomCardTwo>
</SwiperSlide> </SwiperSlide>
</Swiper> </Swiper>
<div class="swiper-button-next swiper-button-white prev-next"> <div class="swiper-button-next swiper-button-white prev-next">
...@@ -37,55 +43,91 @@ ...@@ -37,55 +43,91 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineComponent, onMounted, reactive, ref } from "vue"; import { defineComponent, onMounted, reactive, ref } from 'vue';
import "./index.less"; import './index.less';
import { Swiper, SwiperSlide } from "swiper/vue"; import { Swiper, SwiperSlide } from 'swiper/vue';
import { Pagination, Navigation, Autoplay } from "swiper"; import { Pagination, Navigation, Autoplay } from 'swiper';
import "swiper/css"; import 'swiper/css';
import "swiper/css/pagination"; import 'swiper/css/pagination';
import CustomCardTwo from '@/components/card2.vue';
import { useRouter } from 'vue-router';
const router = useRouter();
/** /**
* spaceBetween 每个swiper-slide的间隔距离 * spaceBetween 每个swiper-slide的间隔距离
*/ */
const imgs = { const imgs = {
prev: new URL("../../../../assets/svg/home/swiper_prev.svg", import.meta.url) prev: new URL('../../../../assets/svg/home/swiper_prev.svg', import.meta.url)
.href, .href,
next: new URL("../../../../assets/svg/home/swiper_next.svg", import.meta.url) next: new URL('../../../../assets/svg/home/swiper_next.svg', import.meta.url)
.href, .href,
}; };
const modules = ref([Navigation, Autoplay]); const modules = ref([Navigation, Autoplay]);
const ScrollList = reactive({ const ScrollList = reactive({
list: [ list: [
{ {
img: new URL("../../../../assets/img/clothes.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/clothes.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
{ {
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, img: new URL('../../../../assets/img/mote.jpeg', import.meta.url).href,
}, title: '亚马逊工具',
{ content: `
img: new URL("../../../../assets/img/mote.jpeg", import.meta.url).href, 产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......`,
}, },
], ],
}); });
const goDetail = (item: any) => { const goDetail = (item: any) => {
console.log(1); console.log(item);
const url = router.resolve({
path: 'Detail',
});
window.open(url.href);
}; };
</script> </script>
......
@import '@/style/variables.less';
.swiper-box { .swiper-box {
margin: 30px 0; margin: @page-margin-top 0 30px 0;
} }
import { defineComponent } from 'vue'; import { defineComponent, onMounted, reactive } from 'vue';
import HomeSwiper from './components/HomeSwiper/swiper.vue'; import HomeSwiper from './components/HomeSwiper/swiper.vue';
import SwiperTest from './components/HomeSwiper/swiper_test.vue';
import './index.less'; import './index.less';
import ModuleCard from '@/components/modulecard.vue';
export default defineComponent({ export default defineComponent({
setup() { setup() {
const CardList = reactive({
list: [] as any,
});
onMounted(() => {
// 创建测试列表
for (let i = 0; i < 21; i++) {
CardList.list.push({
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊产品文案生成',
content:
'1111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111',
});
}
});
return () => ( return () => (
<div> <div>
<div class="swiper-box"> <div class="swiper-box">
<HomeSwiper></HomeSwiper> <HomeSwiper></HomeSwiper>
<ModuleCard label="推荐工具" list={CardList.list}></ModuleCard>
</div> </div>
</div> </div>
); );
......
@import '@/style/variables.less';
.custom-img-to-img-content { .custom-img-to-img-content {
.keyword { .keyword {
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
......
@import '@/style/variables.less';
.custom-real-upload { .custom-real-upload {
margin-top: 30px; margin-top: 30px;
background: #ffffff; background: #ffffff;
...@@ -36,12 +37,12 @@ ...@@ -36,12 +37,12 @@
flex-direction: column; flex-direction: column;
.title { .title {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: black; color: black;
} }
.title2 { .title2 {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
.custom-chose-file { .custom-chose-file {
...@@ -69,7 +70,7 @@ ...@@ -69,7 +70,7 @@
height: 100%; height: 100%;
.uploading-title { .uploading-title {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
} }
...@@ -86,7 +87,7 @@ ...@@ -86,7 +87,7 @@
} }
.title1 { .title1 {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: #000000; color: #000000;
} }
} }
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
border: none; border: none;
--ripple-color: none !important; --ripple-color: none !important;
border-radius: 8px; border-radius: 8px;
font-size: 18px; font-size: @font-size-18;
} }
.submit { .submit {
background: #ebebeb; background: #ebebeb;
...@@ -123,7 +124,7 @@ ...@@ -123,7 +124,7 @@
} }
} }
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
@import '@/style/variables.less';
.custom-img-to-img-content { .custom-img-to-img-content {
.keyword { .keyword {
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
......
@import '@/style/variables.less';
.custom-real-upload { .custom-real-upload {
margin-top: 30px; margin-top: 30px;
background: #ffffff; background: #ffffff;
...@@ -36,12 +37,12 @@ ...@@ -36,12 +37,12 @@
flex-direction: column; flex-direction: column;
.title { .title {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: black; color: black;
} }
.title2 { .title2 {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
.custom-chose-file { .custom-chose-file {
...@@ -69,7 +70,7 @@ ...@@ -69,7 +70,7 @@
height: 100%; height: 100%;
.uploading-title { .uploading-title {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
} }
...@@ -86,7 +87,7 @@ ...@@ -86,7 +87,7 @@
} }
.title1 { .title1 {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: #000000; color: #000000;
} }
} }
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
border: none; border: none;
--ripple-color: none !important; --ripple-color: none !important;
border-radius: 8px; border-radius: 8px;
font-size: 18px; font-size: @font-size-18;
} }
.submit { .submit {
background: #ebebeb; background: #ebebeb;
...@@ -123,7 +124,7 @@ ...@@ -123,7 +124,7 @@
} }
} }
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
...@@ -67,12 +67,13 @@ const displayimg = (e) => { ...@@ -67,12 +67,13 @@ const displayimg = (e) => {
</script> </script>
<style lang="less"> <style lang="less">
@import '@/style/variables.less';
.fileUpload { .fileUpload {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
height: 32px; height: 32px;
color: white; color: white;
font-size: 16px; font-size: @font-size-16;
.custom-upload-file { .custom-upload-file {
position: absolute; position: absolute;
top: 0; top: 0;
......
@import '@/style/variables.less';
.custom-img-to-img-content { .custom-img-to-img-content {
.keyword { .keyword {
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
......
@import '@/style/variables.less';
.custom-real-upload { .custom-real-upload {
margin-top: 30px; margin-top: 30px;
background: #ffffff; background: #ffffff;
...@@ -36,12 +37,12 @@ ...@@ -36,12 +37,12 @@
flex-direction: column; flex-direction: column;
.title { .title {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: black; color: black;
} }
.title2 { .title2 {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
.custom-chose-file { .custom-chose-file {
...@@ -69,7 +70,7 @@ ...@@ -69,7 +70,7 @@
height: 100%; height: 100%;
.uploading-title { .uploading-title {
font-weight: 400; font-weight: 400;
font-size: 15px; font-size: @font-size-15;
color: #8b8b8b; color: #8b8b8b;
} }
} }
...@@ -86,7 +87,7 @@ ...@@ -86,7 +87,7 @@
} }
.title1 { .title1 {
font-weight: 600; font-weight: 600;
font-size: 18px; font-size: @font-size-18;
color: #000000; color: #000000;
} }
} }
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
border: none; border: none;
--ripple-color: none !important; --ripple-color: none !important;
border-radius: 8px; border-radius: 8px;
font-size: 18px; font-size: @font-size-18;
} }
.submit { .submit {
background: #ebebeb; background: #ebebeb;
...@@ -123,7 +124,7 @@ ...@@ -123,7 +124,7 @@
} }
} }
.label { .label {
font-size: 20px; font-size: @font-size-20;
font-weight: bold; font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
} }
...@@ -116,6 +116,7 @@ const onSubmit = async ({ validateResult, firstError }: any) => { ...@@ -116,6 +116,7 @@ const onSubmit = async ({ validateResult, firstError }: any) => {
<style lang="less"> <style lang="less">
@import '@/style/flex.less'; @import '@/style/flex.less';
@import '@/style/variables.less';
.custom-login { .custom-login {
width: 400px; width: 400px;
margin: 0 auto; margin: 0 auto;
...@@ -123,7 +124,7 @@ const onSubmit = async ({ validateResult, firstError }: any) => { ...@@ -123,7 +124,7 @@ const onSubmit = async ({ validateResult, firstError }: any) => {
flex-direction: column; flex-direction: column;
.custom-login-title { .custom-login-title {
font-weight: 500; font-weight: 500;
font-size: 50px; font-size: @font-size-50;
color: #000000; color: #000000;
text-align: center; text-align: center;
} }
......
<template>
<div class="custom-products">
<template v-for="item in CardList.list" :key="item.label">
<div class="products-label">
{{ item.label }}
</div>
<!-- 再嵌一层for -->
<div class="products-content-box">
<template v-for="it in item.data" :key="it.title">
<CustomCardTwo
:img="it.img"
:title="it.title"
:content="it.content"
></CustomCardTwo>
</template>
<template v-for="(it, index) in item.data" :key="it.title">
<i v-if="index !== item.data.length - 1"></i>
</template>
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import CustomCardTwo from '@/components/card2.vue';
import { onMounted, reactive } from 'vue';
const CardList = reactive({
// 这里将返回两层列表
list: {
commerce: {
label: '电商',
data: [
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
],
},
commerce2: {
label: '亚马逊',
data: [
{
img: new URL('../../assets/img/clothes.jpeg', import.meta.url).href,
title: '亚马逊工具',
content: `
产品主图制作、产品文案生成、模仿A+产品、五
点描述生成等......
`,
},
],
},
},
});
onMounted(() => {});
// 产品页
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-products {
.products-label {
font-weight: 700;
font-size: @font-size-26;
margin-top: @page-margin-top;
margin-bottom: 20px;
}
.products-content-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
row-gap: 30px;
i {
width: 339px;
}
}
}
</style>
...@@ -12,6 +12,33 @@ export default [ ...@@ -12,6 +12,33 @@ export default [
header: true, header: true,
}, },
}, },
// 产品页
{
path: '/Products',
name: 'Products',
component: () => import('@/pages/Products/index.vue'),
meta: {
header: true,
},
},
// 产品子集 -detail
{
path: '/Detail',
name: 'Detail',
component: () => import('@/pages/Detail/index.vue'),
meta: {
header: true,
},
},
// 文案生成-Copywriting generation
{
path: '/CopywritingGeneration',
name: 'CopywritingGeneration',
component: () => import('@/pages/CopywritingGeneration/index.vue'),
meta: {
header: true,
},
},
{ {
path: '/login', path: '/login',
name: 'login', name: 'login',
......
@import '@/style/variables.less';
.custom-disabled-button { .custom-disabled-button {
height: 48px; height: 48px;
width: 100%; width: 100%;
font-weight: 600; font-weight: 600;
font-size: 17px; font-size: @font-size-17;
color: #848e9c; color: #848e9c;
transition: all 0.3s; transition: all 0.3s;
} }
......
@import './variables.less'; @import './variables.less';
body { body {
font-size: 14px; font-size: @font-size-14;
line-height: 1.5; line-height: 1.5;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
padding: 0; padding: 0;
margin: 0; margin: 0;
user-select: none; user-select: none;
color: white;
} }
ul, ul,
......
.custom-before-line {
position: relative !important;
box-sizing: border-box;
&::before {
content: '';
width: 200%;
height: 200%;
position: absolute;
border: 0.5px solid #b1b5c4;
border-radius: 16px;
top: 0;
left: 0;
transform-origin: 0 0;
-webkit-transform-origin: 0 0;
-o-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform: scale(0.5);
-webkit-transform: scale(0.5);
-o-transform: scale(0.5);
-ms-transform: scale(0.5);
-moz-transform: scale(0.5);
pointer-events: none;
}
}
@import '@/style/variables.less';
// 页面重复的label // 页面重复的label
.custom-upload-label { .custom-upload-label {
font-weight: 700; font-weight: 700;
font-size: 20px; font-size: @font-size-20;
color: #000000; color: #000000;
} }
// 头部导航栏高度 // 每个页面的content模块的margin-top
@navbarHeight: 6vh; @page-margin-top: 30px;
// 底部导航栏高度
@FooterHeight: 8vh;
// 页面padding // border
@pagepadding:0 12px; @main-border-radius: 15px;
// 动画 // 动画
@anim-time-fn-easing: cubic-bezier(0.38, 0, 0.24, 1); @anim-time-fn-easing: cubic-bezier(0.38, 0, 0.24, 1);
...@@ -13,3 +11,17 @@ ...@@ -13,3 +11,17 @@
@anim-duration-base: 0.2s; @anim-duration-base: 0.2s;
@anim-duration-moderate: 0.24s; @anim-duration-moderate: 0.24s;
@anim-duration-slow: 0.28s; @anim-duration-slow: 0.28s;
/**
* 文字大小
*/
@font-size-12: 12px;
@font-size-14: 14px;
@font-size-15: 15px;
@font-size-16: 16px;
@font-size-17: 17px;
@font-size-18: 18px;
@font-size-20: 20px;
@font-size-26: 26px;
@font-size-40: 40px;
@font-size-50: 50px;
import { MessagePlugin } from 'tdesign-vue-next';
export const show_message = (
value: string,
type: string = 'warning',
close: boolean = true
) => {
if (close) {
MessagePlugin.closeAll();
}
if (type == 'warning') {
MessagePlugin.warning(value);
} else if (type == 'success') {
MessagePlugin.success(value);
} else if (type == 'info') {
MessagePlugin.info(value);
} else if (type == 'error') {
MessagePlugin.error(value);
}
// 类型报错-所以用上面的方法
// MessagePlugin[type](value);
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment