Merge remote-tracking branch 'origin/develop' into dev_vite

This commit is contained in:
X1627315083
2025-06-19 09:38:42 +08:00
24 changed files with 8310 additions and 9513 deletions

View File

@@ -886,6 +886,12 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
overflow: hidden;
box-sizing: border-box;
}
.ant-select-dropdown .ant-select-item {
font-size: 1.6rem;
line-height: 2.4rem;
padding: 0.8rem 1.8rem;
min-height: 3.2rem;
}
.generalModel {
-moz-user-select: none;
-webkit-user-select: none;

View File

@@ -970,6 +970,15 @@ tr > .ant-picker-cell-in-view.ant-picker-cell-range-hover-start:last-child::afte
overflow: hidden;
box-sizing: border-box;
}
.ant-select-item{
font-size: 1.6rem;
line-height: 2.4rem;
padding: .8rem 1.8rem;
min-height: 3.2rem;
.ant-select-item-option-content{
}
}
}
.generalModel{//自带关闭的页面

View File

@@ -485,6 +485,7 @@ export default defineComponent({
float: left;
user-select:none;
-webkit-user-drag: none;
object-fit: cover;
}
.modal_imgItem{
position: absolute;

View File

@@ -101,7 +101,7 @@ export default defineComponent({
eventLangData = eventDataCn
}
eventLangData.eventsItem.forEach((item:any)=>{
if(item.id == router.currentRoute.value.query.id){
if(item.id == router.currentRoute.value.query.eventId){
filter.eventsDetail = item;
}
})

View File

@@ -728,11 +728,6 @@ export default defineComponent({
if(rv.filter((item:any)=>item.status == 'Invalid').length ==dataNum){
message.info(this.t('Generate.effectPoor'));
}else{
nextTick().then(()=>{
if(this.driver__.driver){
driverObj__.moveNext()
}
})
}
this.store.dispatch('getCredits')

View File

@@ -687,7 +687,7 @@ export default defineComponent({
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
z-index: 99;
.operate_icon{
font-size: 1.8rem;
color: #fff;

View File

@@ -8,13 +8,13 @@
<!-- v-show="loginType == 'username'" -->
<div>
<div class="login_form_content" :state="emailStap">
<div v-show="emailStap === 1">
<div class="login_form_title marign_top30">Enterprise</div>
<div class="login_form_title marign_top30">
Enterprise
</div>
<div class="generalModel_state">
<div
class="generalModel_state_item"
style="width: 100%; margin: 0"
>
<div class="generalModel_state_item" style="width: 100%; margin: 0;">
<a-select
placeholder="Select a school"
v-model:value="selectEnterprise"
@@ -36,7 +36,9 @@
</a-select>
</div>
</div>
<div class="login_form_title marign_top30">Email</div>
<div class="login_form_title marign_top30">
Email
</div>
<input
class="login_form_input"
placeholder="Enter your email address"
@@ -61,16 +63,21 @@
</div>
</div>
<!-- 邮箱登录 start -->
<div
v-show="emailStap === 2"
class="login_form_email"
:class="{ active: emailStap === 2 }"
>
<div v-show="emailStap === 2" class="email_last_step">
<div
v-show="emailStap === 2"
class="email_last_step"
>
<div class="email_last_step_block">
<span class="email_last_step_content"
>Verify with one-time verification code</span
>Verify with one-time verification
code</span
>
<i
class="fi fi-br-cross email_last_step_block_icon"
@@ -79,23 +86,34 @@
</div>
<div class="email_last_step_bottom">
<div class="email_last_step_des">
<div class="sent_email_content">Sent to {{ email }}</div>
<div class="sent_email_content">
Sent to {{ email }}
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="emailNextStepFun()"
<span v-show="time"
>{{ time }}s</span
>
<span
v-show="!time"
@click="emailNextStepFun()"
>Resend</span
>
</div>
</div>
<VerificationCodeInput
:ct="emailCode"
@sendCaptcha="submitEmailLogin($event)"
@sendCaptcha="
submitEmailLogin($event)
"
></VerificationCodeInput>
<div class="email_last_step_des">
<div class="sent_email_content email_tip_content">
Please check the junk box if you haven't received
verification code
<div
class="sent_email_content email_tip_content"
>
Please check the junk box if you
haven't received verification
code
</div>
</div>
</div>
@@ -105,8 +123,15 @@
<div class="login_form_title marign_top30">
<label :class="{ active: emailStap == 2 }">
<input :state="emailStap" type="checkbox" v-model="checked" />
<span>I agree to all Term, Privacy Policy and Fees</span>
<input
:state="emailStap"
type="checkbox"
v-model="checked"
/>
<span
>I agree to all Term, Privacy Policy and
Fees</span
>
</label>
</div>
<!-- <div class="thirdPartyLogin marign_top30">
@@ -140,6 +165,7 @@
</div>
<!-- 邮箱登录 end -->
</div>
<!-- 忘记密码 start -->
@@ -149,7 +175,9 @@
@click="forgetPasswordLastStepFun()"
>
<i class="fi fi-br-arrow-left"></i>
<span class="forget_password_content_title">Retrieve password</span>
<span class="forget_password_content_title"
>Retrieve password</span
>
</div>
<div v-show="frogetPasswordStep === 1">
<div class="forget_passored_form_content">
@@ -177,7 +205,9 @@
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="forgetPasswordNextStepFun()"
<span
v-show="!time"
@click="forgetPasswordNextStepFun()"
>Resend</span
>
</div>
@@ -227,47 +257,42 @@ import phoneLogin from "@/component/LoginPage/phoneLogin.vue";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { setLang } from "@/tool/guide";
import md5 from "md5";
const md5 = require("md5");
export default defineComponent({
components: {
VerificationCodeInput,
googleLogin,
weiXinLogin,
phoneLogin,
VerificationCodeInput,googleLogin,weiXinLogin,phoneLogin
},
setup() {
let timer: any = 0;
const { locale } = useI18n();
const store = useStore();
let loadingShow = ref(false);
let loadingShow = ref(false)
const data = reactive({
selectEnterprise: "",
selectEnterprise:'',
schoolList:[] as any,
});
const schoolListChange = (e: any) => {};
})
const schoolListChange = (e:any)=>{
}
const filterOption = (e:any)=>{
let params = {
name:e,
type: "Enterprise",
};
Https.axiosPost(
Https.httpUrls.organizationNameSearch,
{},
{ params: params }
).then((rv: any) => {
type:'Enterprise'
}
Https.axiosPost(Https.httpUrls.organizationNameSearch,{},{params:params}).then((rv:any)=>{
data.schoolList = rv.map((item:any)=>{
return {
label:item,
value:item,
};
});
});
};
}
})
})
}
const handleFocus= ()=>{
if(data.schoolList.length == 0){
filterOption("");
filterOption('')
}
}
};
return {
...toRefs(data),
store,
@@ -275,8 +300,7 @@ export default defineComponent({
locale,
loadingShow,
schoolListChange,
filterOption,
handleFocus,
filterOption,handleFocus
};
},
data() {
@@ -288,8 +312,8 @@ export default defineComponent({
emailCode: ["", "", "", "", "", ""], //邮箱验证码
emailNextStep: true,
username: "",
password: localStorage.getItem("loginPassword") || "",
email: localStorage.getItem("loginEmail") || "", //邮箱登录邮箱
password: localStorage.getItem("loginPassword") || '',
email: localStorage.getItem("loginEmail") || '', //邮箱登录邮箱
frogetPasswordStep: 1, //忘记密码的步骤
forgetPasswordEmail: "",
forgetEmailCode: ["", "", "", "", "", ""], //忘记密码的邮箱验证码
@@ -334,14 +358,16 @@ export default defineComponent({
email: this.email,
operationType: "LOGIN",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.emailStap = 2;
this.time = 60;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
}
});
}
);
},
//邮箱登录的上一步
@@ -364,12 +390,15 @@ export default defineComponent({
email: this.forgetPasswordEmail,
operationType: "FORGET_PWD",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.frogetPasswordStep = 2;
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.createTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.createTimer();
}
});
}
);
},
//忘记密码的上一步
forgetPasswordLastStepFun() {
@@ -378,7 +407,8 @@ export default defineComponent({
} else {
this.frogetPasswordStep = this.frogetPasswordStep - 1;
this.forgetPasswordEmail = "";
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.clearTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.clearTimer();
}
},
@@ -391,13 +421,15 @@ export default defineComponent({
password: "",
verifyEmail: true,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
this.forgetEmailValue = emailVerifyCode;
this.frogetPasswordStep = 3;
this.clearTimer();
}
});
}
);
},
//改变勾选是否是机器人
@@ -412,7 +444,9 @@ export default defineComponent({
return;
} else {
if (!this.password) {
message.info("Please enter your account number or password");
message.info(
"Please enter your account number or password"
);
return;
}
//输入邮箱
@@ -431,12 +465,14 @@ export default defineComponent({
}
//判断是否同意隐私政策
if (!this.checked) {
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
return;
}
let data = {
password: md5(this.password + "abc"),
userName: "a",
userName: 'a',
// userName: this.username,
organizationName:this.selectEnterprise,
email: this.email,
@@ -448,7 +484,7 @@ export default defineComponent({
Https.axiosPost(Https.httpUrls.enterpriseLogin, data)
.then((rv: any) => {
if (rv) {
this.clearTimer();
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
@@ -459,7 +495,8 @@ export default defineComponent({
localStorage.setItem("loginPassword", this.password);
}
})
.catch((res) => {});
.catch((res) => {
});
setTimeout(() => {
this.loginTime = true;
}, 2000);
@@ -479,39 +516,39 @@ export default defineComponent({
emailVerifyCode: emailVerifyCode,
loginType: "EMAIL",
userId: this.userId,
organizationName: this.selectEnterprise,
organizationName:this.selectEnterprise
};
Https.axiosPost(Https.httpUrls.accountLogin, data)
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
isCheckAgreement(){
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
},
//微信登录
wechatLogin(value:any) {
let data = {
code : value.code,
type: 2,
};
this.loadingShow = true;
type:2
}
this.loadingShow = true
Https.axiosGet(Https.httpUrls.parseWeChatCode, {params:data})
.then((rv: any) => {
this.loadingShow = false;
this.setSuccessLogin(rv);
this.loadingShow = false
this.setSuccessLogin(rv)
})
.catch((res) => {
this.loadingShow = false;
});
.catch((res) => {this.loadingShow = false});
},
//谷歌登录
googelLogin(value:any) {
let data = { credential: value, type: 2 };
let data = {credential : value,type:2}
Https.axiosGet(Https.httpUrls.parseGoogleCredential, {params:data})
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
@@ -534,8 +571,8 @@ export default defineComponent({
let userid:any = {
ueserId:rv.userId,
systemUser:rv.systemUser,
};
if (rv.email) userid.email = rv.email;
}
if(rv.email)userid.email = rv.email
this.store.commit("upUserDetail", userid);
if (window.innerWidth < 768) {
@@ -546,9 +583,13 @@ export default defineComponent({
} else {
this.turnToHomePage("/home");
}
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
sessionStorage.setItem(
"isTimeOne",
JSON.stringify(false)
); //是否需要公告 提示 弹窗
let randomNum: any =
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
Math.floor(Math.random() * 9000000000000000) +
1000000000000000;
sessionStorage.setItem("sessionId", randomNum);
sessionStorage.setItem("record", JSON.stringify([]));
}
@@ -561,12 +602,14 @@ export default defineComponent({
password: md5(this.newPassword + "abc"),
verifyEmail: false,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
message.success("Changing the password successfully");
this.changeIsLogin(1);
}
});
}
);
},
//创建定时器
@@ -612,9 +655,9 @@ export default defineComponent({
// },
},
mounted() {
const data = this.$route.query;
if (data?.state == "weiXin") {
this.wechatLogin(data);
const data = this.$route.query
if(data?.state == 'weiXin'){
this.wechatLogin(data)
}
},
});
@@ -735,7 +778,7 @@ export default defineComponent({
font-size: 1.4rem;
box-sizing: border-box;
outline: none;
transition: all 0.3s;
transition: all .3s;
&:hover{
border: 0.1rem solid #000;
}
@@ -789,9 +832,9 @@ export default defineComponent({
font-weight: 500;
color: #ffffff;
cursor: pointer;
transition: all 0.3s;
transition: all .3s;
&:hover{
background: #3c3c3c;
background: #3C3C3C;
}
&[state="2"] {
cursor: not-allowed;

View File

@@ -4,6 +4,7 @@
<!-- 账号密码和邮箱登录 start-->
<div class="login_content" v-if="isLogin === 1">
<div class="login_content_left">
<!-- v-show="loginType == 'username'" -->
<div>
<div class="login_form_content" :state="emailStap">
@@ -14,7 +15,9 @@
v-model="username"
/> -->
<div v-show="emailStap === 1">
<div class="login_form_title marign_top30">Email</div>
<div class="login_form_title marign_top30">
Email
</div>
<input
class="login_form_input"
placeholder="Enter your email address"
@@ -39,16 +42,21 @@
</div>
</div>
<!-- 邮箱登录 start -->
<div
v-show="emailStap === 2"
class="login_form_email"
:class="{ active: emailStap === 2 }"
>
<div v-show="emailStap === 2" class="email_last_step">
<div
v-show="emailStap === 2"
class="email_last_step"
>
<div class="email_last_step_block">
<span class="email_last_step_content"
>Verify with one-time verification code</span
>Verify with one-time verification
code</span
>
<i
class="fi fi-br-cross email_last_step_block_icon"
@@ -57,23 +65,34 @@
</div>
<div class="email_last_step_bottom">
<div class="email_last_step_des">
<div class="sent_email_content">Sent to {{ email }}</div>
<div class="sent_email_content">
Sent to {{ email }}
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="emailNextStepFun()"
<span v-show="time"
>{{ time }}s</span
>
<span
v-show="!time"
@click="emailNextStepFun()"
>Resend</span
>
</div>
</div>
<VerificationCodeInput
:ct="emailCode"
@sendCaptcha="submitEmailLogin($event)"
@sendCaptcha="
submitEmailLogin($event)
"
></VerificationCodeInput>
<div class="email_last_step_des">
<div class="sent_email_content email_tip_content">
Please check the junk box if you haven't received
verification code
<div
class="sent_email_content email_tip_content"
>
Please check the junk box if you
haven't received verification
code
</div>
</div>
</div>
@@ -83,25 +102,24 @@
<div class="login_form_title marign_top30">
<label :class="{ active: emailStap == 2 }">
<input :state="emailStap" type="checkbox" v-model="checked" />
<span>I agree to all Term, Privacy Policy and Fees</span>
<input
:state="emailStap"
type="checkbox"
v-model="checked"
/>
<span
>I agree to all Term, Privacy Policy and
Fees</span
>
</label>
</div>
<div class="thirdPartyLogin marign_top30">
<div class="label">
<div
class="mask"
v-show="!checked"
@click="isCheckAgreement"
></div>
<div class="mask" v-show="!checked" @click="isCheckAgreement"></div>
<googleLogin @googelLogin="googelLogin"></googleLogin>
</div>
<div class="label">
<div
class="mask"
v-show="!checked"
@click="isCheckAgreement"
></div>
<div class="mask" v-show="!checked" @click="isCheckAgreement"></div>
<weiXinLogin></weiXinLogin>
</div>
<!-- <phoneLogin></phoneLogin> -->
@@ -115,7 +133,10 @@
</div>
<div class="login_text">
<div class="forget_password_text" @click="changeIsLogin(2)">
<div
class="forget_password_text"
@click="changeIsLogin(2)"
>
Forgot your password
</div>
</div>
@@ -135,7 +156,9 @@
<!-- <span class="icon iconfont fi-br-arrow-left"></span
> -->
<i class="fi fi-br-arrow-left"></i>
<span class="forget_password_content_title">Retrieve password</span>
<span class="forget_password_content_title"
>Retrieve password</span
>
</div>
<div v-show="frogetPasswordStep === 1">
<div class="forget_passored_form_content">
@@ -163,7 +186,9 @@
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="forgetPasswordNextStepFun()"
<span
v-show="!time"
@click="forgetPasswordNextStepFun()"
>Resend</span
>
</div>
@@ -195,6 +220,8 @@
<!-- 忘记密码 end -->
</div>
<!-- <div class="login_footer">
<div class="login_footer_item">
<div class="login_footer_item_text">
@@ -244,19 +271,16 @@ import phoneLogin from "@/component/LoginPage/phoneLogin.vue";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { setLang } from "@/tool/guide";
import md5 from "md5";
const md5 = require("md5");
export default defineComponent({
components: {
VerificationCodeInput,
googleLogin,
weiXinLogin,
phoneLogin,
VerificationCodeInput,googleLogin,weiXinLogin,phoneLogin
},
setup() {
let timer: any = 0;
const { locale } = useI18n();
const store = useStore();
let loadingShow = ref(false);
let loadingShow = ref(false)
return {
store,
timer,
@@ -273,8 +297,8 @@ export default defineComponent({
emailCode: ["", "", "", "", "", ""], //邮箱验证码
emailNextStep: true,
username: "",
password: localStorage.getItem("loginPassword") || "",
email: localStorage.getItem("loginEmail") || "", //邮箱登录邮箱
password: localStorage.getItem("loginPassword") || '',
email: localStorage.getItem("loginEmail") || '', //邮箱登录邮箱
frogetPasswordStep: 1, //忘记密码的步骤
forgetPasswordEmail: "",
forgetEmailCode: ["", "", "", "", "", ""], //忘记密码的邮箱验证码
@@ -319,14 +343,16 @@ export default defineComponent({
email: this.email,
operationType: "LOGIN",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.emailStap = 2;
this.time = 60;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
}
});
}
);
},
//邮箱登录的上一步
@@ -349,12 +375,15 @@ export default defineComponent({
email: this.forgetPasswordEmail,
operationType: "FORGET_PWD",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.frogetPasswordStep = 2;
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.createTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.createTimer();
}
});
}
);
},
//忘记密码的上一步
forgetPasswordLastStepFun() {
@@ -363,7 +392,8 @@ export default defineComponent({
} else {
this.frogetPasswordStep = this.frogetPasswordStep - 1;
this.forgetPasswordEmail = "";
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.clearTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.clearTimer();
}
},
@@ -376,13 +406,15 @@ export default defineComponent({
password: "",
verifyEmail: true,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
this.forgetEmailValue = emailVerifyCode;
this.frogetPasswordStep = 3;
this.clearTimer();
}
});
}
);
},
//改变勾选是否是机器人
@@ -397,7 +429,9 @@ export default defineComponent({
return;
} else {
if (!this.password) {
message.info("Please enter your account number or password");
message.info(
"Please enter your account number or password"
);
return;
}
//输入邮箱
@@ -412,12 +446,14 @@ export default defineComponent({
}
//判断是否同意隐私政策
if (!this.checked) {
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
return;
}
let data = {
password: md5(this.password + "abc"),
userName: "a",
userName: 'a',
// userName: this.username,
email: this.email,
operationType: "LOGIN",
@@ -433,7 +469,7 @@ export default defineComponent({
// this.loginType = 'email'
// }
if (rv) {
this.clearTimer();
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
@@ -446,7 +482,8 @@ export default defineComponent({
localStorage.setItem("loginPassword", this.password);
}
})
.catch((res) => {});
.catch((res) => {
});
setTimeout(() => {
this.loginTime = true;
}, 2000);
@@ -469,35 +506,35 @@ export default defineComponent({
};
Https.axiosPost(Https.httpUrls.accountLogin, data)
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
isCheckAgreement(){
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
},
//微信登录
wechatLogin(value:any) {
let data = {
code : value.code,
type: 2,
};
this.loadingShow = true;
type:2
}
this.loadingShow = true
Https.axiosGet(Https.httpUrls.parseWeChatCode, {params:data})
.then((rv: any) => {
this.loadingShow = false;
this.setSuccessLogin(rv);
this.loadingShow = false
this.setSuccessLogin(rv)
})
.catch((res) => {
this.loadingShow = false;
});
.catch((res) => {this.loadingShow = false});
},
//谷歌登录
googelLogin(value:any) {
let data = { credential: value, type: 2 };
let data = {credential : value,type:2}
Https.axiosGet(Https.httpUrls.parseGoogleCredential, {params:data})
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
@@ -520,8 +557,8 @@ export default defineComponent({
let userid:any = {
ueserId:rv.userId,
systemUser:rv.systemUser,
};
if (rv.email) userid.email = rv.email;
}
if(rv.email)userid.email = rv.email
this.store.commit("upUserDetail", userid);
if (window.innerWidth < 768) {
@@ -532,9 +569,13 @@ export default defineComponent({
} else {
this.turnToHomePage("/home");
}
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
sessionStorage.setItem(
"isTimeOne",
JSON.stringify(false)
); //是否需要公告 提示 弹窗
let randomNum: any =
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
Math.floor(Math.random() * 9000000000000000) +
1000000000000000;
sessionStorage.setItem("sessionId", randomNum);
sessionStorage.setItem("record", JSON.stringify([]));
}
@@ -547,12 +588,14 @@ export default defineComponent({
password: md5(this.newPassword + "abc"),
verifyEmail: false,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
message.success("Changing the password successfully");
this.changeIsLogin(1);
}
});
}
);
},
//创建定时器
@@ -598,9 +641,9 @@ export default defineComponent({
// },
},
mounted() {
const data = this.$route.query;
if (data?.state == "weiXin") {
this.wechatLogin(data);
const data = this.$route.query
if(data?.state == 'weiXin'){
this.wechatLogin(data)
}
},
});
@@ -706,7 +749,7 @@ export default defineComponent({
font-size: 1.4rem;
box-sizing: border-box;
outline: none;
transition: all 0.3s;
transition: all .3s;
&:hover{
border: 0.1rem solid #000;
}
@@ -760,9 +803,9 @@ export default defineComponent({
font-weight: 500;
color: #ffffff;
cursor: pointer;
transition: all 0.3s;
transition: all .3s;
&:hover{
background: #3c3c3c;
background: #3C3C3C;
}
&[state="2"] {
cursor: not-allowed;

View File

@@ -8,13 +8,13 @@
<!-- v-show="loginType == 'username'" -->
<div>
<div class="login_form_content" :state="emailStap">
<div v-show="emailStap === 1">
<div class="login_form_title marign_top30">School</div>
<div class="login_form_title marign_top30">
School
</div>
<div class="generalModel_state">
<div
class="generalModel_state_item"
style="width: 100%; margin: 0"
>
<div class="generalModel_state_item" style="width: 100%; margin: 0;">
<a-select
placeholder="Select a school"
v-model:value="selectSchool"
@@ -36,7 +36,9 @@
</a-select>
</div>
</div>
<div class="login_form_title marign_top30">Email</div>
<div class="login_form_title marign_top30">
Email
</div>
<input
class="login_form_input"
placeholder="Enter your email address"
@@ -61,16 +63,21 @@
</div>
</div>
<!-- 邮箱登录 start -->
<div
v-show="emailStap === 2"
class="login_form_email"
:class="{ active: emailStap === 2 }"
>
<div v-show="emailStap === 2" class="email_last_step">
<div
v-show="emailStap === 2"
class="email_last_step"
>
<div class="email_last_step_block">
<span class="email_last_step_content"
>Verify with one-time verification code</span
>Verify with one-time verification
code</span
>
<i
class="fi fi-br-cross email_last_step_block_icon"
@@ -79,23 +86,34 @@
</div>
<div class="email_last_step_bottom">
<div class="email_last_step_des">
<div class="sent_email_content">Sent to {{ email }}</div>
<div class="sent_email_content">
Sent to {{ email }}
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="emailNextStepFun()"
<span v-show="time"
>{{ time }}s</span
>
<span
v-show="!time"
@click="emailNextStepFun()"
>Resend</span
>
</div>
</div>
<VerificationCodeInput
:ct="emailCode"
@sendCaptcha="submitEmailLogin($event)"
@sendCaptcha="
submitEmailLogin($event)
"
></VerificationCodeInput>
<div class="email_last_step_des">
<div class="sent_email_content email_tip_content">
Please check the junk box if you haven't received
verification code
<div
class="sent_email_content email_tip_content"
>
Please check the junk box if you
haven't received verification
code
</div>
</div>
</div>
@@ -105,8 +123,15 @@
<div class="login_form_title marign_top30">
<label :class="{ active: emailStap == 2 }">
<input :state="emailStap" type="checkbox" v-model="checked" />
<span>I agree to all Term, Privacy Policy and Fees</span>
<input
:state="emailStap"
type="checkbox"
v-model="checked"
/>
<span
>I agree to all Term, Privacy Policy and
Fees</span
>
</label>
</div>
<!-- <div class="thirdPartyLogin marign_top30">
@@ -149,7 +174,9 @@
@click="forgetPasswordLastStepFun()"
>
<i class="fi fi-br-arrow-left"></i>
<span class="forget_password_content_title">Retrieve password</span>
<span class="forget_password_content_title"
>Retrieve password</span
>
</div>
<div v-show="frogetPasswordStep === 1">
<div class="forget_passored_form_content">
@@ -177,7 +204,9 @@
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="forgetPasswordNextStepFun()"
<span
v-show="!time"
@click="forgetPasswordNextStepFun()"
>Resend</span
>
</div>
@@ -227,47 +256,42 @@ import phoneLogin from "@/component/LoginPage/phoneLogin.vue";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { setLang } from "@/tool/guide";
import md5 from "md5";
const md5 = require("md5");
export default defineComponent({
components: {
VerificationCodeInput,
googleLogin,
weiXinLogin,
phoneLogin,
VerificationCodeInput,googleLogin,weiXinLogin,phoneLogin
},
setup() {
let timer: any = 0;
const { locale } = useI18n();
const store = useStore();
let loadingShow = ref(false);
let loadingShow = ref(false)
const data = reactive({
selectSchool: "",
selectSchool:'',
schoolList:[] as any,
});
const schoolListChange = (e: any) => {};
})
const schoolListChange = (e:any)=>{
}
const filterOption = (e:any)=>{
let params = {
name:e,
type: "School",
};
Https.axiosPost(
Https.httpUrls.organizationNameSearch,
{},
{ params: params }
).then((rv: any) => {
type:'School'
}
Https.axiosPost(Https.httpUrls.organizationNameSearch,{},{params:params}).then((rv:any)=>{
data.schoolList = rv.map((item:any)=>{
return {
label:item,
value:item,
};
});
});
};
}
})
})
}
const handleFocus= ()=>{
if(data.schoolList.length == 0){
filterOption("");
filterOption('')
}
}
};
return {
...toRefs(data),
store,
@@ -275,8 +299,7 @@ export default defineComponent({
locale,
loadingShow,
schoolListChange,
filterOption,
handleFocus,
filterOption,handleFocus
};
},
data() {
@@ -288,8 +311,8 @@ export default defineComponent({
emailCode: ["", "", "", "", "", ""], //邮箱验证码
emailNextStep: true,
username: "",
password: localStorage.getItem("loginPassword") || "",
email: localStorage.getItem("loginEmail") || "", //邮箱登录邮箱
password: localStorage.getItem("loginPassword") || '',
email: localStorage.getItem("loginEmail") || '', //邮箱登录邮箱
frogetPasswordStep: 1, //忘记密码的步骤
forgetPasswordEmail: "",
forgetEmailCode: ["", "", "", "", "", ""], //忘记密码的邮箱验证码
@@ -334,14 +357,16 @@ export default defineComponent({
email: this.email,
operationType: "LOGIN",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.emailStap = 2;
this.time = 60;
this.emailCode = ["", "", "", "", "", ""];
this.createTimer();
}
});
}
);
},
//邮箱登录的上一步
@@ -364,12 +389,15 @@ export default defineComponent({
email: this.forgetPasswordEmail,
operationType: "FORGET_PWD",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.frogetPasswordStep = 2;
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.createTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.createTimer();
}
});
}
);
},
//忘记密码的上一步
forgetPasswordLastStepFun() {
@@ -378,7 +406,8 @@ export default defineComponent({
} else {
this.frogetPasswordStep = this.frogetPasswordStep - 1;
this.forgetPasswordEmail = "";
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.clearTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.clearTimer();
}
},
@@ -391,13 +420,15 @@ export default defineComponent({
password: "",
verifyEmail: true,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
this.forgetEmailValue = emailVerifyCode;
this.frogetPasswordStep = 3;
this.clearTimer();
}
});
}
);
},
//改变勾选是否是机器人
@@ -412,7 +443,9 @@ export default defineComponent({
return;
} else {
if (!this.password) {
message.info("Please enter your account number or password");
message.info(
"Please enter your account number or password"
);
return;
}
//输入邮箱
@@ -431,12 +464,14 @@ export default defineComponent({
}
//判断是否同意隐私政策
if (!this.checked) {
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
return;
}
let data = {
password: md5(this.password + "abc"),
userName: "a",
userName: 'a',
// userName: this.username,
organizationName:this.selectSchool,
email: this.email,
@@ -449,7 +484,7 @@ export default defineComponent({
Https.axiosPost(Https.httpUrls.schoolLogin, data)
.then((rv: any) => {
if (rv) {
this.clearTimer();
this.clearTimer()
this.time = 60;
this.emailStap = 2;
this.emailCode = ["", "", "", "", "", ""];
@@ -482,39 +517,39 @@ export default defineComponent({
emailVerifyCode: emailVerifyCode,
loginType: "EMAIL",
userId: this.userId,
organizationName: this.selectSchool,
organizationName:this.selectSchool
};
Https.axiosPost(Https.httpUrls.accountLogin, data)
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
isCheckAgreement(){
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
},
//微信登录
wechatLogin(value:any) {
let data = {
code : value.code,
type: 2,
};
this.loadingShow = true;
type:2
}
this.loadingShow = true
Https.axiosGet(Https.httpUrls.parseWeChatCode, {params:data})
.then((rv: any) => {
this.loadingShow = false;
this.setSuccessLogin(rv);
this.loadingShow = false
this.setSuccessLogin(rv)
})
.catch((res) => {
this.loadingShow = false;
});
.catch((res) => {this.loadingShow = false});
},
//谷歌登录
googelLogin(value:any) {
let data = { credential: value, type: 2 };
let data = {credential : value,type:2}
Https.axiosGet(Https.httpUrls.parseGoogleCredential, {params:data})
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
@@ -537,8 +572,8 @@ export default defineComponent({
let userid:any = {
ueserId:rv.userId,
systemUser:rv.systemUser,
};
if (rv.email) userid.email = rv.email;
}
if(rv.email)userid.email = rv.email
this.store.commit("upUserDetail", userid);
if (window.innerWidth < 768) {
@@ -549,9 +584,13 @@ export default defineComponent({
} else {
this.turnToHomePage("/home");
}
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
sessionStorage.setItem(
"isTimeOne",
JSON.stringify(false)
); //是否需要公告 提示 弹窗
let randomNum: any =
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
Math.floor(Math.random() * 9000000000000000) +
1000000000000000;
sessionStorage.setItem("sessionId", randomNum);
sessionStorage.setItem("record", JSON.stringify([]));
}
@@ -564,12 +603,14 @@ export default defineComponent({
password: md5(this.newPassword + "abc"),
verifyEmail: false,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
message.success("Changing the password successfully");
this.changeIsLogin(1);
}
});
}
);
},
//创建定时器
@@ -615,9 +656,9 @@ export default defineComponent({
// },
},
mounted() {
const data = this.$route.query;
if (data?.state == "weiXin") {
this.wechatLogin(data);
const data = this.$route.query
if(data?.state == 'weiXin'){
this.wechatLogin(data)
}
},
});
@@ -738,7 +779,7 @@ export default defineComponent({
font-size: 1.4rem;
box-sizing: border-box;
outline: none;
transition: all 0.3s;
transition: all .3s;
&:hover{
border: 0.1rem solid #000;
}
@@ -792,9 +833,9 @@ export default defineComponent({
font-weight: 500;
color: #ffffff;
cursor: pointer;
transition: all 0.3s;
transition: all .3s;
&:hover{
background: #3c3c3c;
background: #3C3C3C;
}
&[state="2"] {
cursor: not-allowed;

View File

@@ -1,10 +1,6 @@
<template>
<div class="Falls">
<div
class="falls_item"
v-fadeIn="isScroll"
v-for="item in list"
:key="item.id"
<div class="falls_item" v-fadeIn="isScroll" v-for="item in list" :key="item.id"
:style="{
width: item.style.width + 'px',
height: item.style.height + 'px',
@@ -21,9 +17,7 @@
height: item.style.imgHeihgt + 'px',
}"
/>
<div v-if="item.original == 1" class="falls_item_user_Original">
{{ $t("newScaleImage.Original") }}
</div>
<div v-if="item.original == 1" class="falls_item_user_Original">{{$t('newScaleImage.Original')}}</div>
</div>
<!-- 文字 -->
@@ -48,11 +42,7 @@
<span>{{item.viewNums}}</span>
</div> -->
<label @click="portfolioLike(item)">
<i
v-if="true"
class="fi fi-sr-thumbs-up"
style="color: rgba(158, 158, 167)"
></i>
<i v-if="true" class="fi fi-sr-thumbs-up" style="color:rgba(158, 158, 167);"></i>
<i v-else class="fi fi-rr-social-network"></i>
<span>{{item.likeNum}}</span>
</label>
@@ -72,17 +62,7 @@
</template>
<script>
import {
defineComponent,
h,
toRefs,
ref,
reactive,
onMounted,
nextTick,
provide,
computed,
} from "vue";
import { defineComponent,h ,toRefs,ref,reactive,onMounted,onBeforeDestroy,nextTick,provide,computed} from 'vue'
import { gsap, TweenMax } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
export default defineComponent({
@@ -98,19 +78,19 @@ export default defineComponent({
itemWidth:{
type:Number,
default:300,
},
}
},
setup(){
let list = ref([]);
let wait_list = ref([]);
let width = ref(300);
let num_x = ref(1);
let gap_x = ref(0);
let gap_y = ref(0);
let poss = ref([]);
let loading = ref(false);
let computedHeight = 0;
let imgDom = ref();
let list = ref([])
let wait_list = ref([])
let width = ref(300)
let num_x = ref(1)
let gap_x = ref(0)
let gap_y = ref(0)
let poss = ref([])
let loading = ref(false)
let computedHeight = 0
let imgDom = ref()
return{
list,
wait_list,
@@ -122,24 +102,24 @@ export default defineComponent({
loading,
computedHeight,
imgDom,
};
}
},
directives:{
fadeIn:{
mounted (el,binding) {
let dom;
let dom
if(binding.value){
dom = document.querySelector(".works_page .page_content");
dom = document.querySelector('.works_page .page_content')
}else{
dom = document.querySelector(".homeRecommend_content_body");
dom = document.querySelector('.homeRecommend_content_body')
}
gsap.registerPlugin(ScrollTrigger);
let tl1 = gsap.timeline();
tl1.from(el, 1, { y: "30px", opacity: 0 });
tl1.from(el,1, {y:'30px',opacity:0},)
ScrollTrigger.create({
trigger: el, // 触发器元素
start: "top 90%", // 滚动触发器的起始滚动位置
end: "100% 80%", // 滚动触发器的结束滚动位置
end: '100% 80%', // 滚动触发器的结束滚动位置
// markers: true, // 开启标注功能
scrub: true,
animation:tl1,
@@ -154,46 +134,41 @@ export default defineComponent({
// }
// }
});
},
}
},
},
mounted () {
this.resize();
this.resize()
window.addEventListener("resize", this.resize);
let domFalls = document.querySelector(".Falls");
let domFalls = document.querySelector('.Falls')
let domCss = getComputedStyle(domFalls);
const paddingBottom =
domCss.getPropertyValue("--paddingBottom").split("px")[0] * 1;
const textMarginTop =
domCss.getPropertyValue("--textMarginTop").split("px")[0] * 1;
const textHeight =
domCss.getPropertyValue("--textHeight").split("px")[0] * 1;
const contentHeight =
domCss.getPropertyValue("--contentHeight").split("px")[0] * 1;
const paddingBottom = domCss.getPropertyValue('--paddingBottom').split('px')[0]*1;
const textMarginTop = domCss.getPropertyValue('--textMarginTop').split('px')[0]*1;
const textHeight = domCss.getPropertyValue('--textHeight').split('px')[0]*1;
const contentHeight = domCss.getPropertyValue('--contentHeight').split('px')[0]*1;
if(this.$props.isText){
this.computedHeight =
paddingBottom + textMarginTop + textHeight + contentHeight;
this.computedHeight = paddingBottom + textMarginTop + textHeight + contentHeight;
}
},
beforeDestroy () {
this.wait_list = [];
this.wait_list = []
window.removeEventListener("resize", this.resize);
},
// 挂载方法
methods: {
clearData(){
this.wait_list = [];
this.width = this.itemWidth;
this.num_x = 1;
this.gap_x = 0;
this.gap_y = 0;
this.poss = [];
this.loading = false;
this.list = [];
this.resize();
this.wait_list = []
this.width = this.itemWidth
this.num_x = 1
this.gap_x = 0
this.gap_y = 0
this.poss = []
this.loading = false
this.list = []
this.resize()
if(this.imgDom){
this.imgDom.remove();
this.imgDom = null;
this.imgDom = null
}
},
push(arr) {
@@ -206,8 +181,8 @@ export default defineComponent({
deleteItem(id){
for (let index = 0; index < this.list.length; index++) {
if(this.list[index].id == id){
this.list.splice(index, 1);
this.resize();
this.list.splice(index,1)
this.resize()
break;
}
}
@@ -220,7 +195,7 @@ export default defineComponent({
}
let url = this.wait_list[0].canvasUrl || this.wait_list[0].url;
let data = this.wait_list[0];
let data = this.wait_list[0]
this.imgDom = document.createElement("img");
this.imgDom.src = url;
this.imgDom.style.width = this.itemWidth + "px";
@@ -229,7 +204,7 @@ export default defineComponent({
this.imgDom.style.top = "-99999px";
document.body.appendChild(this.imgDom);
this.imgDom.addEventListener("load", () => {
if (!this.imgDom) return;
if(!this.imgDom) return
var idx = 0;
var pos_num = this.poss[idx];
for (var i = 1; i < this.poss.length; i++) {
@@ -243,18 +218,19 @@ export default defineComponent({
let height = this.imgDom.offsetHeight+this.computedHeight;
let top = this.poss[idx] + this.gap_y;
let left = (idx + 1) * this.gap_x + idx * width;
let imgHeight = height - this.computedHeight;
let imgHeight = height - this.computedHeight
this.poss[idx] = top + height;
let obj = {
canvasUrl:url,
style: { width, height, top, left, imgHeight },
...data,
...data
};
this.list.push(obj);
this.imgDom.remove();
this.imgDom = null;
this.imgDom = null
this.wait_list.splice(0, 1);
this.$el.style.height = Math.max(...this.poss) + this.gap_y + "px";
this.$el.style.height =
Math.max(...this.poss) + this.gap_y + "px";
if (this.wait_list.length <= 0) {
this.loading = false;
this.$emit("loadend");
@@ -278,7 +254,8 @@ export default defineComponent({
for (var i = 0; i < num_x; i++) poss.push(0);
this.poss = poss;
this.reset();
});
})
},
reset() {
for (let i = 0; i < this.list.length; i++) {
@@ -300,16 +277,16 @@ export default defineComponent({
this.$el.style.height = Math.max(...this.poss) + this.gap_y + "px";
},
setItemDetail(data){
this.$emit("getImgScale", data);
this.$emit('getImgScale',data)
},
portfolioLike(data){
this.$emit("setPortfolioLike", data);
this.$emit('setPortfolioLike',data)
}
},
},
});
})
</script>
<style lang="less" scoped>
<style lang='less' scoped>
.Falls {
width: 100%;
height: auto;
@@ -342,7 +319,7 @@ export default defineComponent({
width: 100%;
object-fit: cover;
height: 100%;
transition: all 0.3s;
transition: all .3s;
}
.falls_item_user_Original{
font-weight: 600;
@@ -423,16 +400,14 @@ export default defineComponent({
>label{
// cursor: pointer;
}
> label,
> div {
>label,>div{
display: flex;
align-items: center;
i{
// font-size: 1.8rem;
font-size: 12px;
}
svg,
i {
svg,i{
color: #9e9ea7;
display: flex;
// width: 10px;
@@ -447,6 +422,8 @@ export default defineComponent({
}
}
}
}
}
</style>

View File

@@ -1,488 +1,311 @@
<template>
<div class="chat" :class="{active:!openChat}" @click.stop="">
<div
class="top"
:class="{ active: !isChattingRecords }"
@click="
() => {
isChattingRecords = !isChattingRecords;
}
"
>
<div class="top" :class="{active:!isChattingRecords}" @click="()=>{isChattingRecords=!isChattingRecords}">
<i class="fi fi-br-angle-small-down"></i>
</div>
<div
v-show="!openChat"
class="left"
@click="
() => {
openChat = !openChat;
isChattingRecords = true;
}
"
>
<div v-show="!openChat" class="left" @click="()=>{openChat = !openChat;isChattingRecords=true}">
<i class="fi fi-br-angle-small-down"></i>
</div>
<div class="chatBox">
<div
class="chattingRecords"
v-show="chatList.length > 0 && isChattingRecords"
>
<div class="chattingRecords" v-show="chatList.length > 0 && isChattingRecords">
<div class="itemBox" ref="chatBox">
<div
class="item"
v-for="item in chatList"
:class="{ user: item.role == 'user' }"
>
<div class="item" v-for="item in chatList" :class="{user:item.role == 'user'}">
<div class="textBox">
<div class="icon">
<img src="@/assets/images/icon/favicon.png" alt="" />
<img src="@/assets/images/icon/favicon.png" alt="">
</div>
<div
class="text"
v-show="
item.content.think ||
item.content.message ||
item.content.img ||
item.content.color
"
>
<div class="text" v-show="item.content.think || item.content.message || item.content.img || item.content.color">
<span class="content">
<div
class="showThink"
:class="{ active: item.content?.isThink }"
v-show="item.content.think"
@click="
() =>
item.content?.isThink
? (item.content.isThink = false)
: (item.content.isThink = true)
"
>
<div class="showThink" :class="{active:item.content?.isThink}" v-show="item.content.think" @click="()=>item.content?.isThink?(item.content.isThink = false):(item.content.isThink = true)">
<div>已深度思考</div>
<i class="fi fi-br-angle-small-down"></i>
</div>
<div class="think" v-show="item.content?.isThink">
{{ item.content.think }}
</div>
<div class="think" v-show="item.content?.isThink">{{item.content.think}}</div>
<div class="txt">{{item.content.message}}</div>
</span>
<div class="fileBox">
<div
v-if="item?.fileList?.length > 0"
class="item"
v-for="fileItem in item.fileList"
>
<div v-if="item?.fileList?.length > 0" class="item" v-for="fileItem in item.fileList">
<div>{{fileItem.name}}</div>
</div>
</div>
<div class="imgBox">
<img
v-if="item.content?.img?.length > 0"
v-for="imgItem in item.content?.img"
:src="imgItem.minioUrl"
alt=""
/>
<img v-if="item.content?.img?.length > 0" v-for="imgItem in item.content?.img" :src="imgItem.minioUrl" alt="">
</div>
<div class="colorBox">
<div
v-if="item.content?.color?.length > 0"
class="item"
v-for="colorItem in item.content?.color"
>
<div
class="color"
:style="{
'background-color': `rgba(${colorItem.rgb.replace(
/\s+/g,
','
)})`,
}"
></div>
<div class="text">
{{ colorItem.rgb.replace(/\s+/g, ",") }}
<div v-if="item.content?.color?.length > 0" class="item" v-for="colorItem in item.content?.color">
<div class="color" :style="{'background-color':`rgba(${colorItem.rgb.replace(/\s+/g, ',')})`}"></div>
<div class="text">{{ colorItem.rgb.replace(/\s+/g, ',') }}</div>
</div>
</div>
</div>
</div>
<i
class="fi fi-br-loading"
v-if="
!item.content.think &&
!item.content.message &&
!item.content.img &&
!item.content.color
"
></i>
<i class="fi fi-br-loading" v-if="!item.content.think && !item.content.message && !item.content.img && !item.content.color"></i>
</div>
</div>
</div>
</div>
<div class="content" @click="openChattingRecords">
<textarea
ref="textarea"
@input="inputText($event)"
@keydown.enter.prevent="sendChat"
placeholder="Write your message"
></textarea>
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="(item, index) in filList">
<div class="item" v-for="item,index in filList">
<div>{{item.name}}</div>
<span
class="icon iconfont icon-shanchu"
@click="deleteFile(item, index)"
></span>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
</div>
</div>
<i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)" />
<input type="file" @change="handleFileUpload($event)">
</i>
<div
class="enableThinking"
:class="{ active: enableThinking }"
@click="() => (enableThinking = !enableThinking)"
>
Deep Thinking
</div>
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div>
</div>
<div class="sendBox">
<div class="maxNum">{{ chatContent?.length }}/10000</div>
<div
class="send"
:class="{ active: chatContent?.length > 0 }"
@click="sendChat"
>
<div class="send" :class="{active:chatContent?.length>0}" @click="sendChat">
<i class="fi fi-ss-paper-plane-top"></i>
</div>
</div>
</div>
</div>
</div>
<div
v-show="openChat"
class="right"
@click="
() => {
openChat = !openChat;
isChattingRecords = false;
}
"
>
<div v-show="openChat" class="right" @click="()=>{openChat = !openChat;isChattingRecords=false}">
<i class="fi fi-br-angle-small-down"></i>
</div>
</div>
</template>
<script lang="ts">
import {
defineComponent,
computed,
ref,
inject,
nextTick,
createVNode,
toRefs,
reactive,
watch,
} from "vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { defineComponent,computed,ref,inject,nextTick,createVNode,toRefs, reactive, watch} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal, message, Upload, CascaderProps } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import { setCookie, getCookie, WriteCookie } from "@/tool/cookie";
import { useRouter, useRoute } from "vue-router";
import { useRouter,useRoute } from 'vue-router'
export default defineComponent({
components: {},
props: {},
emits: ["chatChange"],
components:{
},
props:{
},
emits:['chatChange'],
setup(props,{emit}) {
const store = useStore();
const route = useRoute();
const route = useRoute()
const data = reactive({
chatContent: "",
chatContent:'',
openChat:true,
chatList: [] as any,
chatList:[
] as any,
isChattingRecords:false,
selectObject:computed(()=>store.state.Workspace.probjects) as any,//选择的项目
filList:[] as any,
setIsShowMark: inject("setIsShowMark") as any,
setIsShowMark:inject('setIsShowMark') as any,
isFinish:true,
enableThinking:false,//深度思考
});
})
const dataDom = reactive({
textarea:null as any,
chatBox:null as any,
});
watch(
() => data.selectObject.id,
(newValue, oldValue) => {
if (
newValue &&
(data.selectObject.httpType == "SERIES_DESIGN" ||
data.selectObject.httpType == "SINGLE_DESIGN")
) {
data.chatList = [];
if (route.query?.create) return;
})
watch(()=>data.selectObject.id,(newValue,oldValue)=>{
if(newValue && (data.selectObject.httpType == 'SERIES_DESIGN' || data.selectObject.httpType == 'SINGLE_DESIGN')){
data.chatList = []
if(route.query?.create)return
nextTick(()=>{
getChatHistory(newValue);
});
getChatHistory(newValue)
})
}
}
);
})
const inputText = (e:any)=>{
if(e.target.value.length <= 1000){
data.chatContent = e.target.value;
data.chatContent = e.target.value
}else{
e.target.value = data.chatContent;
e.target.value = data.chatContent
}
e.target.style.height = `${e.target.scrollHeight}px`;
};
const sendChat = () => {
if (!data.isFinish) return;
if (!data.chatContent) return;
let fileList;
if (data.filList) {
fileList = JSON.parse(JSON.stringify(data.filList));
} else {
fileList = [];
}
let fileUrl =
fileList.filter((item: any) => item.type == "file").length > 0
? fileList.filter((item: any) => item.type == "file")[0].minioPath
: "";
let imageUrlList =
fileList.filter((item: any) => item.type == "image").length > 0
? fileList
.filter((item: any) => item.type == "image")
.map((item: any) => item.minioPath)
.join(",")
: "";
data.chatList.push({
content: { message: data.chatContent, think: "" },
role: "user",
fileList: fileList,
});
data.chatList.push({
content: { message: "", think: "" },
role: "system",
});
const eventSource = new EventSource(
`${import.meta.env.VITE_APP_BASE_URL}${
Https.httpUrls.llmStream
}?token=${getCookie("token")}&prompt=${data.chatContent}&projectId=${
data.selectObject.id
}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${
data.enableThinking
}`
);
data.chatContent = "";
dataDom.textarea.value = "";
data.filList = [];
const sendChat = ()=>{
if(!data.isFinish)return
if(!data.chatContent)return
let fileList
if(data.filList){
fileList = JSON.parse(JSON.stringify(data.filList))
}else{
fileList = []
}
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : ''
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : ''
data.chatList.push({content:{message:data.chatContent,think:''},role:'user',fileList:fileList})
data.chatList.push({content:{message:'',think:''},role:'system'})
const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=${data.selectObject.id}&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}`);
data.chatContent = ''
dataDom.textarea.value = ''
data.filList = []
eventSource.onmessage = function(event) {
data.isFinish = false;
console.log("收到数据:", JSON.parse(event.data));
data.isFinish = false
console.log('收到数据:', JSON.parse(event.data));
// if(event.data.status == 'DESIGN_SIGNAL'){
// emit('chatChange',{type:'design'})
// }else if(event.data.status == 'RUNNING'){
// data.chatList[data.chatList.length-1].content.message+=JSON.parse(event.data).content
// }
const container = dataDom.chatBox;
if (container?.scrollHeight)
container.scrollTop = container.scrollHeight;
if(container?.scrollHeight)container.scrollTop = container.scrollHeight;
const eventData = JSON.parse(event.data);
if (eventData.type == "text") {
data.chatList[data.chatList.length - 1].content.message +=
eventData.content;
} else if (eventData.type == "think") {
data.chatList[data.chatList.length - 1].content.think +=
eventData.content;
const eventData = JSON.parse(event.data)
if(eventData.type == 'text'){
data.chatList[data.chatList.length-1].content.message+=eventData.content
}else if(eventData.type == 'think'){
data.chatList[data.chatList.length-1].content.think+=eventData.content
}else if(eventData.type == "tools_response"){
let nameList = [
"moodboard",
"printboard",
"sketchboard",
"generate_color_code",
];
let nameList = ['moodboard','printboard','sketchboard','generate_color_code']
let nameData = {
moodboard: "moodBoard",
printboard: "printBoard",
sketchboard: "sketchBoard",
} as any;
let getData = "";
moodboard:'moodBoard',
printboard:'printBoard',
sketchboard:'sketchBoard',
} as any
let getData = ''
if(nameList.indexOf(eventData.tools_name) > -1){
if (data.chatList[data.chatList.length - 1].content.message)
data.chatList.push({ content: { message: "" }, role: "system" });
if (eventData.tools_name == "generate_color_code") {
data.chatList[data.chatList.length - 1].content.color =
JSON.parse(
JSON.parse(event.data).content
).receiveCollectionElementList;
getData = "colorBoard";
if(data.chatList[data.chatList.length - 1].content.message)data.chatList.push({content:{message:''},role:'system'})
if(eventData.tools_name == 'generate_color_code'){
data.chatList[data.chatList.length-1].content.color = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList
getData = 'colorBoard'
}else{
data.chatList[data.chatList.length - 1].content.img = JSON.parse(
JSON.parse(event.data).content
).receiveCollectionElementList;
getData = nameData[eventData.tools_name];
data.chatList[data.chatList.length-1].content.img = JSON.parse(JSON.parse(event.data).content).receiveCollectionElementList
getData = nameData[eventData.tools_name]
}
data.chatList.push({ content: { message: "" }, role: "system" });
} else if (eventData.tools_name == "design_control_signal") {
emit("chatChange", { type: eventData.tools_name, design: true });
data.chatList.push({content:{message:''},role:'system'})
}else if(eventData.tools_name == 'design_control_signal'){
emit('chatChange',{type:eventData.tools_name,design:true})
}
emit("chatChange", { type: eventData.type, module: getData });
emit('chatChange',{type:eventData.type,module:getData})
}
//emit('chatChange',{type:JSON.parse(event.data).status})
};
eventSource.onerror = function(error) {
if (eventSource.readyState === EventSource.CLOSED) {
data.chatList[data.chatList.length - 1].content.message =
"服务器繁忙,请稍后再试。";
data.chatList[data.chatList.length-1].content.message='服务器繁忙,请稍后再试。'
} else {
eventSource.close();
data.isFinish = true;
eventSource.close()
data.isFinish = true
}
};
};
}
const getChatHistory = (objectId:number)=>{
if (!data.isFinish) return;
if(!data.isFinish)return
let value = {
projectId:objectId,
page:1,
pageSize:100,
};
}
Https.axiosPost(Https.httpUrls.getChatHistory,value).then((rv)=>{
if(rv){
rv.content.forEach((item:any,index:number) => {
if (rv.content[rv.content.length - index - 1].role == "system") {
let text = rv.content[rv.content.length - index - 1].content;
if(rv.content[rv.content.length - index -1].role == 'system'){
let text = rv.content[rv.content.length - index -1].content
if(rv.content[rv.content.length - index -1].isImage == 2){
rv.content[rv.content.length - index -1].content={
img: JSON.parse(
rv.content[rv.content.length - index - 1].content
),
};
} else if (
rv.content[rv.content.length - index - 1].isImage == 1
) {
img : JSON.parse(rv.content[rv.content.length - index -1].content)
}
}else if(rv.content[rv.content.length - index -1].isImage==1){
rv.content[rv.content.length - index -1].content={
color: JSON.parse(
rv.content[rv.content.length - index - 1].content
),
};
color : JSON.parse(rv.content[rv.content.length - index -1].content)
}
}else{
let think = "";
let message = "";
if (
text.split("[TEXT]").length > 1 &&
text.split("[THINK]").length > 1
) {
think = text.split("[TEXT]")[0];
text.split("[TEXT]").forEach((text: any, index: number) => {
if (index == 0) return;
message += "[TEXT]" + text;
let think = ''
let message = ''
if(text.split('[TEXT]').length > 1 && text.split('[THINK]').length > 1){
think = text.split('[TEXT]')[0]
text.split('[TEXT]').forEach((text:any,index:number) => {
if(index == 0)return
message += ('[TEXT]'+text)
});
}else{
message = text;
message = text
}
rv.content[rv.content.length - index -1].content = {
message:message,
think:think,
};
}
}
}else{
let content = JSON.parse(
rv.content[rv.content.length - index - 1].content
);
content.fileList = [];
let content = JSON.parse(rv.content[rv.content.length - index -1].content)
content.fileList = []
if(content.file || content.image){
let getName = (url:any)=>{
let minio = url.splice("?")[0];
return minio.splice("/")[minio.splice("/").length - 1];
};
let minio = url.splice('?')[0]
return minio.splice('/')[minio.splice('/').length-1]
}
if(content.file){
content.file.forEach((item:any)=>{
content.fileList.push({
name: getName(item),
type: "file",
url: item,
});
});
content.fileList.push({name:getName(item),type:'file',url:item})
})
}
if(content.image){
content.image.forEach((item:any)=>{
content.fileList.push({
name: getName(item),
type: "image",
url: item,
});
});
content.fileList.push({name:getName(item),type:'image',url:item})
})
}
}
rv.content[rv.content.length - index - 1].content = content;
rv.content[rv.content.length - index -1].content = content
}
data.chatList.push(rv.content[rv.content.length - index - 1]);
data.chatList.push(rv.content[rv.content.length - index -1])
});
}
});
};
})
}
const openChattingRecords = ()=>{
data.isChattingRecords = true;
data.isChattingRecords = true
// let setRecords = ()=>{
// data.isChattingRecords = false
// document.removeEventListener('click',setRecords)
// }
// document.addEventListener('click',setRecords)
};
const handleFileUpload = (event: any) => {
if (event.target.files[0].size > 5 * 1024 * 1024) {
// 5MB
message.info("The file size cannot exceed 5MB.");
return;
}
let type = event.target.files[0].type.startsWith("image/");
const handleFileUpload = (event:any)=>{
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
message.info('The file size cannot exceed 5MB.');
return
}
let type = event.target.files[0].type.startsWith('image/')
if(type){
if (
data.filList.filter((item: any) => item.type == "image").length >= 5
) {
message.info("You can only upload five pictures.");
return;
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
message.info('You can only upload five pictures.');
return
}
}else{
if (
data.filList.filter((item: any) => item.type == "file").length >= 1
) {
message.info("You can only upload one file.");
return;
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
message.info('You can only upload one file.');
return
}
}
data.setIsShowMark(true);
data.setIsShowMark(true)
const formData = new FormData();
formData.append("file", event.target.files[0]);
formData.append('file', event.target.files[0]);
let config:any = {
headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' },
params:formData,
};
}
Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
.then((rv: any) => {
let obj = {
name:event.target.files[0].name,
type: type ? "image" : "file",
type:type?'image':'file',
minioPath:rv[0],
url:rv[1],
};
data.filList.push(obj);
}
data.filList.push(obj)
// data.filList.unshift(rv)
data.setIsShowMark(false);
data.setIsShowMark(false)
}
).catch(rv=>{
data.setIsShowMark(false)
})
.catch((rv) => {
data.setIsShowMark(false);
});
};
}
const deleteFile = (item:any,index:number)=>{
data.filList.splice(index, 1);
};
data.filList.splice(index,1)
}
return{
...toRefs(dataDom),
...toRefs(data),
@@ -491,12 +314,13 @@ export default defineComponent({
openChattingRecords,
handleFileUpload,
deleteFile,
};
}
},
provide() {
return {};
return {
}
},
});
})
</script>
<style lang="less" scoped>
.chat{
@@ -507,7 +331,7 @@ export default defineComponent({
bottom: 3.2rem;
top: auto;
width: 50%;
transition: all 0.3s;
transition: all .3s;
border-radius: 2.4rem;
display: flex;
border: 1px solid #e5e5e5;
@@ -539,6 +363,7 @@ export default defineComponent({
> .text{
> .content{
> .txt{
}
> .showThink{
display: none;
@@ -547,9 +372,9 @@ export default defineComponent({
> .fileBox{
> .item{
height: 3rem;
padding: 0.5rem 1rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: 0.5rem;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
@@ -566,6 +391,7 @@ export default defineComponent({
> .icon{
display: none;
}
}
}
@@ -589,11 +415,12 @@ export default defineComponent({
// word-wrap: break-word;
> .content{
> .txt{
}
> .showThink{
cursor: pointer;
display: flex;
padding: 0.7rem 1.4rem;
padding: .7rem 1.4rem;
margin-bottom: 1.2rem;
background: rgb(237 237 237);
border-radius: 1rem;
@@ -606,7 +433,7 @@ export default defineComponent({
}
> i{
display: flex;
transition: all 0.3s;
transition: all .3s;
}
}
> .think{
@@ -627,14 +454,14 @@ export default defineComponent({
width: 10rem;
height: 10rem;
cursor: pointer;
margin: 0.5rem;
margin: .5rem;
}
}
> .colorBox{
display: flex;
flex-wrap: wrap;
>.item{
margin: 0.5rem;
margin: .5rem;
border-radius: 1rem;
overflow: hidden;
border: 1px solid;
@@ -669,6 +496,7 @@ export default defineComponent({
}
}
}
}
}
}
@@ -699,9 +527,9 @@ export default defineComponent({
display: flex;
> .item{
height: 3rem;
padding: 0.5rem 1rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: 0.5rem;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
@@ -719,16 +547,17 @@ export default defineComponent({
}
> .enableThinking{
width: 10rem;
padding: 0.2rem 0.4rem;
padding: .2rem .4rem;
text-align: center;
font-size: 1.4rem;
border: 1px solid #000;
border-radius: 0.4rem;
border-radius: .4rem;
cursor: pointer;
margin-left: 1rem;
&.active{
background: #000;
color: #fff;
}
}
}
@@ -756,11 +585,11 @@ export default defineComponent({
> .maxNum{
font-size: 1.2rem;
margin-right: 0.8rem;
margin-right: .8rem;
font-weight: 400;
}
> .send{
opacity: 0.5;
opacity: .5;
cursor: no-drop;
&.active{
opacity: 1;
@@ -771,9 +600,7 @@ export default defineComponent({
}
}
}
> .right,
> .left,
> .top {
> .right,> .left,>.top{
display: flex;
align-items: center;
cursor: pointer;
@@ -782,7 +609,7 @@ export default defineComponent({
> i{
display: flex;
font-size: 2rem;
transition: all 0.3s;
transition: all .3s;
}
}
> .top{

View File

@@ -928,8 +928,8 @@ export default defineComponent({
right: 1rem;
top: 1rem;
// opacity: 0;
width: 3.5rem;
height: 3.5rem;
width: 3rem;
height: 3rem;
transition: all 0.3s ease-in-out;
}
&.modal_imgItem:nth-child(even) {
@@ -942,10 +942,10 @@ export default defineComponent({
}
.pin_block{
position: absolute;
left: 1rem;
left: .5rem;
top: 1rem;
width: 8rem;
height: 3.5rem;
width: 7rem;
height: 3rem;
border-radius: 3rem;
background: rgba(0,0,0,.7);
color: #fff;
@@ -960,8 +960,8 @@ export default defineComponent({
padding-left: .2rem;
}
i{
width: 3rem;
height: 3rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
display: flex;
align-items: center;
@@ -974,7 +974,7 @@ export default defineComponent({
}
}
span{
font-size: 1.8rem;
font-size: 1.4rem;
font-weight: 600;
}
}

View File

@@ -882,8 +882,8 @@ export default defineComponent({
right: 1rem;
top: 1rem;
// opacity: 0;
width: 3.5rem;
height: 3.5rem;
width: 3rem;
height: 3rem;
transition: all 0.3s ease-in-out;
}
&.modal_imgItem:nth-child(even) {
@@ -900,10 +900,10 @@ export default defineComponent({
}
.pin_block{
position: absolute;
left: 1rem;
left: .5rem;
top: 1rem;
width: 8rem;
height: 3.5rem;
width: 7rem;
height: 3rem;
border-radius: 3rem;
background: rgba(0,0,0,.7);
color: #fff;
@@ -918,8 +918,8 @@ export default defineComponent({
padding-left: .2rem;
}
i{
width: 3rem;
height: 3rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
display: flex;
align-items: center;
@@ -932,7 +932,7 @@ export default defineComponent({
}
}
span{
font-size: 1.8rem;
font-size: 1.4rem;
font-weight: 600;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -65,6 +65,7 @@ export default defineComponent({
}else{
data.openType = ''
data.dataLoad = false
return
}
// if((query.history || query.id) != (oldQuery.history || oldQuery.id)){
// }

View File

@@ -5,14 +5,7 @@
<div class="title">How can I help you today?</div>
<div class="selectFlow">
<div class="select">
<div
class="item"
@click="setFlow(item)"
:class="{ active: item.title == selectFlow.title }"
v-for="item in flowList"
>
{{ item.title }}
</div>
<div class="item" @click="setFlow(item)" :class="{active:item.title == selectFlow.title}" v-for="item in flowList">{{ item.title }}</div>
</div>
<div class="describe">
<p v-for="item in selectFlow.describe">{{ item }}</p>
@@ -20,50 +13,24 @@
</div>
<div class="chatOrSetting">
<div class="select">
<div
class="item"
@click="setChatOrSetting('chat')"
:class="{ active: chatOrSetting == 'chat' }"
>
Chat
</div>
<div
class="item"
@click="setChatOrSetting('setting')"
:class="{ active: chatOrSetting == 'setting' }"
>
Setting
</div>
<div class="item" @click="setChatOrSetting('chat')" :class="{active:chatOrSetting == 'chat'}">Chat</div>
<div class="item" @click="setChatOrSetting('setting')" :class="{active:chatOrSetting == 'setting'}">Setting</div>
</div>
</div>
<div class="chatBox" v-show="chatOrSetting == 'chat'">
<textarea
ref="textarea"
@input="inputText($event)"
@keydown.enter.prevent="sendChat"
placeholder="Write your message"
></textarea>
<textarea ref="textarea" @input="inputText($event)" @keydown.enter.prevent="sendChat" placeholder="Write your message"></textarea>
<div class="btn">
<div class="uploadBox">
<div class="filList">
<div class="item" v-for="(item, index) in filList">
<div class="item" v-for="item,index in filList">
<div>{{item.name}}</div>
<span
class="icon iconfont icon-shanchu"
@click="deleteFile(item, index)"
></span>
<span class="icon iconfont icon-shanchu" @click="deleteFile(item,index)"></span>
</div>
</div>
<i class="fi fi-rs-paperclip-vertical">
<input type="file" @change="handleFileUpload($event)" />
<input type="file" @change="handleFileUpload($event)">
</i>
<div
class="enableThinking"
:class="{ active: enableThinking }"
@click="() => (enableThinking = !enableThinking)"
>
Deep Thinking
</div>
<div class="enableThinking" :class="{active:enableThinking}" @click="()=>enableThinking = !enableThinking">Deep Thinking</div>
</div>
<div class="sendBox">
<div class="maxNum">{{ chatContent.length }}/10000</div>
@@ -74,19 +41,10 @@
</div>
</div>
<div v-show="chatOrSetting != 'chat'" class="workspaceBox">
<workspace
@setProject="setProject"
:httpWorkflowType="selectFlow.value"
></workspace>
<workspace @setProject="setProject" :httpWorkflowType="selectFlow.value"></workspace>
</div>
<div class="hint" v-show="chatOrSetting == 'chat'">
<div
class="item"
v-for="item in hintList"
@click="addChatContent(item)"
>
{{ item }}
</div>
<div class="item" v-for="item in hintList" @click="addChatContent(item)">{{ item }}</div>
</div>
</div>
</div>
@@ -96,129 +54,103 @@
</div>
</template>
<script lang="ts">
import {
defineComponent,
computed,
ref,
provide,
nextTick,
createVNode,
toRefs,
reactive,
onMounted,
} from "vue";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { defineComponent,computed,ref,provide,nextTick,createVNode,toRefs, reactive, onMounted} from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { Modal, message, Upload, CascaderProps } from "ant-design-vue";
import { useI18n } from "vue-i18n";
import { getCookie, clonAllCookie } from "@/tool/cookie";
import router from "@/router";
import workspace from "./workspace.vue";
import { Modal,message,Upload,CascaderProps } from 'ant-design-vue';
import { useI18n } from 'vue-i18n'
import {getCookie,clonAllCookie} from '@/tool/cookie'
import router from '@/router';
import workspace from './workspace.vue'
export default defineComponent({
components:{
workspace,
},
props: {},
emits: ["newProject"],
props:{
},
emits:['newProject'],
setup(props,{emit}) {
const store = useStore();
const data = reactive({
flowList:[
{
title: "Series Design",
value: "SERIES_DESIGN",
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
"Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
],
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.',
]
},
{
title: "Single Design",
value: "SINGLE_DESIGN",
title:'Single Design',
value:'SINGLE_DESIGN',
describe:[
"Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.",
],
'Single Design centers on the independent design of a single clothing category, such as a T-shirt, dress, or jacket, without considering coordination with other items. Use the Moodboard, Printboard, Colorboard, and Sketchboard in the Design Assests panel to gather inspiration and focus on crafting a unique piece. Once completed, optimize your design in the Draft and Collection panels with tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to display your individual creation.',
]
},
],
selectFlow:{
title: "Series Design",
value: "SERIES_DESIGN",
title:'Series Design',
value:'SERIES_DESIGN',
describe:[
"Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.",
],
'Series Design focuses on the coordinated design of multi-category clothing, ideal for creating a unified fashion collection. You can use the Moodboard, Printboard, Colorboard, Sketchboard, and Mannequin sections in the Design Assests panel to organize your inspiration and design complementary clothing combinations. Finally, refine your designs in the Draft and Collection panels using tools like To Product Image, Relight, and Transfer Pose, then export to the Canvas to showcase your complete series design.',
]
},
chatContent: "",
chatContent:'',
hintList:[
"设计一套田园风衣服",
"设计一套夏日风衣服",
"设计一套未来风格的衣服",
'设计一套田园风衣服',
'设计一套夏日风衣服',
'设计一套未来风格的衣服',
],
enableThinking:false,//深度思考
uploadFile:null as any,
loadingShow:false,
text: "",
text:'',
filList:[] as any,
textarea:null as any,
chatOrSetting: "chat",
});
const dataDom = reactive({});
chatOrSetting:'chat',
})
const dataDom = reactive({
})
const setFlow = (item:any)=>{
data.selectFlow = item;
};
data.selectFlow = item
}
const inputText = (e:any)=>{
if(e.target.value.length <= 1000){
data.chatContent = e.target.value;
data.chatContent = e.target.value
}else{
e.target.value = data.chatContent;
e.target.value = data.chatContent
}
e.target.style.height = `${e.target.scrollHeight}px`;
};
}
const addChatContent = (item:any)=>{
if (data.textarea.value?.length + item.length > 10000) return;
data.chatContent += item;
data.textarea.value += item;
};
if((data.textarea.value?.length + item.length) > 10000)return
data.chatContent += item
data.textarea.value += item
}
const sendChat = ()=>{
if (!data.chatContent) return;
data.loadingShow = true;
let fileList = JSON.parse(JSON.stringify(data.filList));
let fileUrl =
fileList.filter((item: any) => item.type == "file").length > 0
? fileList.filter((item: any) => item.type == "file")[0].minioPath
: "";
let imageUrlList =
fileList.filter((item: any) => item.type == "image").length > 0
? fileList
.filter((item: any) => item.type == "image")
.map((item: any) => item.minioPath)
.join(",")
: "";
Https.axiosGet(Https.httpUrls.chatCreateProject, {
params: {
prompt: data.chatContent,
process: data.selectFlow.value,
fileUrl: fileUrl,
imageUrlList,
},
})
.then((rv) => {
if(!data.chatContent)return
data.loadingShow = true
let fileList = JSON.parse(JSON.stringify(data.filList))
let fileUrl = (fileList.filter((item:any)=>item.type == 'file').length > 0) ? fileList.filter((item:any)=>item.type == 'file')[0].minioPath : ''
let imageUrlList = (fileList.filter((item:any)=>item.type == 'image').length > 0)? fileList.filter((item:any)=>item.type == 'image').map((item:any)=>item.minioPath).join(',') : ''
Https.axiosGet(Https.httpUrls.chatCreateProject, {params:{prompt:data.chatContent,process:data.selectFlow.value,fileUrl:fileUrl,imageUrlList}}).then((rv)=>{
if(rv){
data.loadingShow = false;
data.loadingShow = false
let value = {
id:rv,
fileList:fileList,
chatContent:data.chatContent,
enableThinking:data.enableThinking,
};
emit("newProject", value);
}
emit('newProject',value)
}
}).catch(()=>{
data.loadingShow = false
})
.catch(() => {
data.loadingShow = false;
});
// let projectId = ''
// const eventSource = new EventSource(`${import.meta.env.VITE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`);
// const eventSource = new EventSource(`${process.env.VUE_APP_BASE_URL}${Https.httpUrls.llmStream}?token=${getCookie('token')}&prompt=${data.chatContent}&projectId=&fileUrl=${fileUrl}&imageUrlList=${imageUrlList}&enableThinking=${data.enableThinking}&process=${data.selectFlow.value}`);
// eventSource.onmessage = function(event) {
// let eventData = JSON.parse(event.data)
// if(eventData.status == "[PROJECT_CREATE_SIGNAL]"){
@@ -236,63 +168,58 @@ export default defineComponent({
// }
// data.loadingShow = false
// };
};
const handleFileUpload = (event: any) => {
if (event.target.files[0].size > 5 * 1024 * 1024) {
// 5MB
message.info("The file size cannot exceed 5MB.");
return;
}
let type = event.target.files[0].type.startsWith("image/");
const handleFileUpload = (event:any)=>{
if (event.target.files[0].size > 5 * 1024 * 1024) { // 5MB
message.info('The file size cannot exceed 5MB.');
return
}
let type = event.target.files[0].type.startsWith('image/')
if(type){
if (
data.filList.filter((item: any) => item.type == "image").length >= 5
) {
message.info("You can only upload five pictures.");
return;
if(data.filList.filter((item:any)=>item.type == 'image').length >= 5){
message.info('You can only upload five pictures.');
return
}
}else{
if (
data.filList.filter((item: any) => item.type == "file").length >= 1
) {
message.info("You can only upload one file.");
return;
if(data.filList.filter((item:any)=>item.type == 'file').length >= 1){
message.info('You can only upload one file.');
return
}
}
data.loadingShow = true;
data.loadingShow = true
const formData = new FormData();
formData.append("file", event.target.files[0]);
formData.append('file', event.target.files[0]);
let config:any = {
headers: { "Content-Type": "multipart/form-data", Accept: "*/*" },
headers:{'Content-Type':'multipart/form-data','Accept':'*/*' },
params:formData,
};
}
Https.axiosPost(Https.httpUrls.llmUploadFile,formData,config)
.then((rv: any) => {
let obj = {
name:event.target.files[0].name,
type: type ? "image" : "file",
type:type?'image':'file',
minioPath:rv[0],
url:rv[1],
};
data.filList.push(obj);
data.loadingShow = false;
}
data.filList.push(obj)
data.loadingShow = false
}
).catch(rv=>{
data.loadingShow = false
})
.catch((rv) => {
data.loadingShow = false;
});
};
}
const deleteFile = (item:any,index:number)=>{
data.filList.splice(index, 1);
};
data.filList.splice(index,1)
}
const setChatOrSetting = (str:any)=>{
data.chatOrSetting = str;
};
data.chatOrSetting = str
}
const setProject = (item:any)=>{
router.push(`home?history=${item.id}`);
};
router.push(`home?history=${item.id}`)
}
onMounted(()=>{
store.commit("createProbject");
});
store.commit('createProbject')
})
return{
...toRefs(dataDom),
...toRefs(data),
@@ -304,12 +231,13 @@ export default defineComponent({
deleteFile,
setChatOrSetting,
setProject,
};
}
},
provide() {
return {};
return {
}
},
});
})
</script>
<style lang="less" scoped>
.newProject{
@@ -355,14 +283,14 @@ export default defineComponent({
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: 0.2rem;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: 0.6rem 0.8rem;
padding: .6rem .8rem;
min-width: 25%;
text-align: center;
font-weight: 600;
@@ -376,7 +304,7 @@ export default defineComponent({
}
> .describe{
margin-top: 1.6rem;
margin-left: 0.8rem;
margin-left: .8rem;
> p{
margin: 0;
color: #71717a;
@@ -393,14 +321,14 @@ export default defineComponent({
border: 1px solid #0000001a;
border-radius: 2.4rem;
display: flex;
padding: 0.2rem;
padding: .2rem;
border-radius: 2rem;
> div{
white-space: nowrap;
justify-content: space-between;
border-radius: 2.2rem;
font-size: 1.6rem;
padding: 0.6rem 0.8rem;
padding: .6rem .8rem;
min-width: 10rem;
text-align: center;
font-weight: 600;
@@ -414,7 +342,7 @@ export default defineComponent({
}
}
> .chatBox{
margin-top: 0.4rem;
margin-top: .4rem;
border-radius: 2.4rem;
position: relative;
background: #f5f5f5;
@@ -442,9 +370,9 @@ export default defineComponent({
display: flex;
> .item{
height: 3rem;
padding: 0.5rem 1rem;
padding: .5rem 1rem;
background: #efeff1;
border-radius: 0.5rem;
border-radius: .5rem;
margin-right: 1rem;
font-size: 1.4rem;
line-height: 2rem;
@@ -462,16 +390,17 @@ export default defineComponent({
}
> .enableThinking{
width: 10rem;
padding: 0.2rem 0.4rem;
padding: .2rem .4rem;
margin-left: 1rem;
text-align: center;
font-size: 1.4rem;
border: 1px solid #000;
border-radius: 0.4rem;
border-radius: .4rem;
cursor: pointer;
&.active{
background: #000;
color: #fff;
}
}
}
@@ -499,7 +428,7 @@ export default defineComponent({
> .maxNum{
font-size: 1.2rem;
margin-right: 0.8rem;
margin-right: .8rem;
font-weight: 400;
}
}

View File

@@ -17,33 +17,12 @@
<div class="generalModel_btn">
<div class="generalModel_closeIcon" @click.stop="cancelDsign()">
<!-- <i class="fi fi-rr-cross-small"></i> -->
<svg
width="46"
height="46"
viewBox="0 0 46 46"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white" fill-opacity="0.3"/>
<rect
x="32.5063"
y="12"
width="3"
height="29"
rx="1.5"
transform="rotate(45 32.5063 12)"
fill="white"
/>
<rect
x="34.6274"
y="32.5059"
width="3"
height="29"
rx="1.5"
transform="rotate(135 34.6274 32.5059)"
fill="white"
/>
<rect x="32.5063" y="12" width="3" height="29" rx="1.5" transform="rotate(45 32.5063 12)" fill="white"/>
<rect x="34.6274" y="32.5059" width="3" height="29" rx="1.5" transform="rotate(135 34.6274 32.5059)" fill="white"/>
</svg>
</div>
</div>
<div class="login_page">
@@ -54,8 +33,7 @@
<div class="login_type_list">
<div
:class="[
'login_type_item',
'username_login_item',
'login_type_item','username_login_item',
'login_active',
]"
>
@@ -83,70 +61,40 @@
<div v-show="passwordConditionShow" class="conditionShow">
<div class="item">
<div class="icon">
<i
v-show="!passwordCondition.length"
class="fi fi-br-cross-small"
></i>
<i
v-show="passwordCondition.length"
class="fi fi-br-check"
></i>
<i v-show="!passwordCondition.length" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.length" class="fi fi-br-check"></i>
</div>
<div class="text">At least 8 characters long</div>
</div>
<div class="item">
<div class="icon">
<i
v-show="!passwordCondition.special"
class="fi fi-br-cross-small"
></i>
<i
v-show="passwordCondition.special"
class="fi fi-br-check"
></i>
<i v-show="!passwordCondition.special" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.special" class="fi fi-br-check"></i>
</div>
<div class="text">Must contain special characters</div>
</div>
<div class="item">
<div class="icon">
<i
v-show="!passwordCondition.group"
class="fi fi-br-cross-small"
></i>
<i
v-show="passwordCondition.group"
class="fi fi-br-check"
></i>
</div>
<div class="text">
Mix of uppercase, lowercase and numbers
<i v-show="!passwordCondition.group" class="fi fi-br-cross-small"></i>
<i v-show="passwordCondition.group" class="fi fi-br-check"></i>
</div>
<div class="text">Mix of uppercase, lowercase and numbers</div>
</div>
</div>
<input
class="login_form_input"
:class="{
active:
Object.values(passwordCondition).filter(
(value) => value === true
).length < 3,
}"
:class="{active:Object.values(passwordCondition).filter(value => value === true).length<3}"
:type="passwordType"
placeholder="Enter your password"
v-model="password"
@keydown.enter="submitPerLogin()"
@input="passwordInput"
@focus="() => (passwordConditionShow = true)"
@blur="() => (passwordConditionShow = false)"
@focus="()=>passwordConditionShow = true"
@blur="()=>passwordConditionShow = false"
/>
<div
class="icon iconfont icon-yanjing_yincang_o password_show_icon"
@click="changePasswordType()"
></div>
<div class="icon iconfont icon-yanjing_yincang_o password_show_icon" @click="changePasswordType()"></div>
</div>
<span style="font-weight: 400; opacity: 0.7"
>You must satisfy ALL password conditions to register.</span
>
<span style="font-weight: 400;opacity: .7;">You must satisfy ALL password conditions to register.</span>
<div class="login_form_title marign_top30">Email</div>
<input
class="login_form_input"
@@ -156,10 +104,7 @@
/>
<!-- 邮箱登录 start -->
<div
class="login_form_email"
:class="{ active: emailStap === 2 }"
>
<div class="login_form_email" :class="{active:emailStap===2}">
<!-- <div v-show="loginType == 'email'" class="login_form_email"> -->
<!-- <div v-show="emailStap === 1" class="forget_password_content">
<div class="forget_password_content_block" @click="changeLoginType('username')">
@@ -186,14 +131,12 @@
</div> -->
<div v-show="emailStap === 2" class="email_last_step">
<div class="email_last_step_block" >
<span class="email_last_step_content"
>Verify with one-time verification code</span
>
<i
class="fi fi-br-cross email_last_step_block_icon"
@click="emailLastStepFun()"
></i>
<i class="fi fi-br-cross email_last_step_block_icon" @click="emailLastStepFun()"></i>
</div>
<div class="email_last_step_bottom">
<div class="email_last_step_des">
@@ -214,8 +157,7 @@
<div class="email_last_step_des">
<div class="sent_email_content email_tip_content">
Please check the junk box if you haven't received
verification code
Please check the junk box if you haven't received verification code
</div>
</div>
</div>
@@ -225,35 +167,24 @@
<div class="login_form_title marign_top30">
<label :class="{active:emailStap == 2}">
<input :state="emailStap" type="checkbox" v-model="checked" />
<input :state="emailStap" type="checkbox" v-model="checked">
<span>I agree to all Term, Privacy Policy and Fees</span>
</label>
</div>
<div class="thirdPartyLogin marign_top30">
<div class="label">
<div
class="mask"
v-show="!checked"
@click="isCheckAgreement"
></div>
<googleLogin
@googelLogin="googelLogin"
text="Register with Google"
></googleLogin>
<div class="mask" v-show="!checked" @click="isCheckAgreement"></div>
<googleLogin @googelLogin="googelLogin" text="Register with Google"></googleLogin>
</div>
<div class="label">
<div
class="mask"
v-show="!checked"
@click="isCheckAgreement"
></div>
<div class="mask" v-show="!checked" @click="isCheckAgreement"></div>
<weiXinLogin text="Register with wechat"></weiXinLogin>
</div>
<!-- <phoneLogin></phoneLogin> -->
</div>
<div
class="login_submit_button marign_top40"
style="width: 100%"
style="width: 100%;"
:state="emailStap"
@click="submitPerLogin()"
>
@@ -263,8 +194,10 @@
<!-- <div class="login_text" >
<div class="forget_password_text" @click="changeIsLogin(2)">Forgot your password</div>
</div> -->
</div>
<!-- 账号密码登录 end -->
</div>
<!-- 邮箱登录 end -->
@@ -272,14 +205,13 @@
<!-- 忘记密码 start -->
<div class="forget_password_content" v-else>
<div
class="forget_password_content_block"
@click="forgetPasswordLastStepFun()"
>
<div class="forget_password_content_block" @click="forgetPasswordLastStepFun()">
<!-- <span class="icon iconfont fi-br-arrow-left"></span
> -->
<i class="fi fi-br-arrow-left"></i>
<span class="forget_password_content_title">Retrieve password</span>
<span class="forget_password_content_title"
>Retrieve password</span
>
</div>
<div v-show="frogetPasswordStep === 1">
<div class="forget_passored_form_content">
@@ -307,7 +239,9 @@
</div>
<div class="tip_content">
<span v-show="time">{{ time }}s</span>
<span v-show="!time" @click="forgetPasswordNextStepFun()"
<span
v-show="!time"
@click="forgetPasswordNextStepFun()"
>Resend</span
>
</div>
@@ -333,9 +267,11 @@
</div>
</div>
<!-- 忘记密码 end -->
</div>
</div>
</a-modal>
</template>
<script lang="ts">
@@ -351,35 +287,32 @@ import phoneLogin from "@/component/LoginPage/phoneLogin.vue";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import { setLang } from "@/tool/guide";
import md5 from "md5";
const md5 = require("md5");
export default defineComponent({
components: {
VerificationCodeInput,
googleLogin,
weiXinLogin,
phoneLogin,
VerificationCodeInput,googleLogin,weiXinLogin,phoneLogin
},
setup(){
let timer:any = 0;
const { locale } = useI18n();
const {locale} = useI18n()
const store = useStore();
let register = reactive({
registerModel:false,
registerModelMask:true,
pageWidth: "50%",
pageWidth:'50%',
passwordConditionShow:false,
passwordCondition:{
length:false,
special:false,
group:false,
},
});
})
return{
store,
timer,
...toRefs(register),
locale,
};
locale
}
},
data() {
return {
@@ -399,21 +332,22 @@ export default defineComponent({
newPassword: "", //新密码
isCheckRobot: false,
time: 60, //60秒倒计时
passwordType: "password",
userId: "",
loginTime: true,
passwordType:'password',
userId:'',
loginTime:true
};
},
mounted(){
const data = this.$route.query;
if (data?.state == "weiXin") {
this.wechatLogin(data);
const data = this.$route.query
if(data?.state == 'weiXin'){
this.wechatLogin(data)
}
},
methods: {
init(){
this.registerModel = true;
this.emailLastStepFun();
this.registerModel = true
this.emailLastStepFun()
},
changeLoginType(type: string) {
this.loginType = type;
@@ -446,24 +380,27 @@ export default defineComponent({
operationType: "LOGIN",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.emailStap = 2;
this.time = 60;
this.emailCode = ["", "", "", "", "", ""];
this.emailCode = ["", "", "", "", "", ""]
this.createTimer();
}
});
}
);
},
//邮箱登录的上一步
emailLastStepFun() {
this.emailStap = 1;
(this.username = ""), (this.password = ""), (this.email = "");
(this.checked = false),
(this.loginType = "username"),
(this.emailCode = ["", "", "", "", "", ""]),
this.clearTimer();
this.username = "",
this.password = "",
this.email = "";
this.checked=false,
this.loginType = "username",
(this.emailCode = ["", "", "", "", "", ""]), this.clearTimer();
},
//忘记密码的下一步
@@ -476,12 +413,15 @@ export default defineComponent({
email: this.forgetPasswordEmail,
operationType: "FORGET_PWD",
};
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountSendEmail, data).then(
(rv: any) => {
if (rv) {
this.frogetPasswordStep = 2;
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.createTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.createTimer();
}
});
}
);
},
//忘记密码的上一步
forgetPasswordLastStepFun() {
@@ -490,37 +430,35 @@ export default defineComponent({
} else {
this.frogetPasswordStep = this.frogetPasswordStep - 1;
this.forgetPasswordEmail = "";
(this.forgetEmailCode = ["", "", "", "", "", ""]), this.clearTimer();
(this.forgetEmailCode = ["", "", "", "", "", ""]),
this.clearTimer();
}
},
//改变勾选是否是机器人
checkRobot() {
this.isCheckRobot = !this.isCheckRobot;
},
passwordInput(){
this.isPassword(this.password);
this.isPassword(this.password)
},
isPassword(password:any){
this.passwordCondition.length = /.{8,}/.test(password);
this.passwordCondition.special =
/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password);
this.passwordCondition.group =
/[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password);
return Object.values(this.passwordCondition).filter(
(value) => value === true
).length;
this.passwordCondition.length = /.{8,}/.test(password)
this.passwordCondition.special = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)
this.passwordCondition.group = /[a-z]/.test(password) && /[A-Z]/.test(password) && /\d/.test(password)
return Object.values(this.passwordCondition).filter(value => value === true).length;
},
//提交账号密码预先登录
submitPerLogin() {
//输入账号密码
if(this.emailStap>=2){
return;
}else{
if (/aida/i.test(this.username)) {
message.info(
'The name cannot contain "AiDA" or any combination of its uppercase and lowercase forms.'
);
message.info('The name cannot contain "AiDA" or any combination of its uppercase and lowercase forms.');
return;
}
if (!this.username || !this.password) {
@@ -544,77 +482,79 @@ export default defineComponent({
}
if(this.isPassword(this.password) < 3){
message.info("You must satisfy ALL password conditions to register.");
return;
return
}
let data = {
userPassword: md5(this.password + "abc"),
userName: this.username,
userEmail: this.email,
browserIdentifiers: "",
country: "",
createDate: "",
credits: 0,
id: 0,
isBeginner: 0,
isTrial: 0,
language: "",
systemUser: 0,
updateDate: "",
validEndTime: 0,
validStartTime: 0,
"browserIdentifiers": "",
"country": "",
"createDate": "",
"credits": 0,
"id": 0,
"isBeginner": 0,
"isTrial": 0,
"language": "",
"systemUser": 0,
"updateDate": "",
"validEndTime": 0,
"validStartTime": 0
};
// this.loginType = 'email'
if(this.loginTime){
this.loginTime = false;
Https.axiosPost(Https.httpUrls.designWorksRegister, data)
.then((rv: any) => {
this.loginTime = false
Https.axiosPost(Https.httpUrls.designWorksRegister, data).then(
(rv: any) => {
// if (rv) {
// this.loginType = 'email'
// }
this.emailStap = 2;
if (rv) {
this.userId = rv.userId;
this.loginType = "email";
this.userId = rv.userId
this.loginType = 'email'
this.time = 60;
this.emailCode = ["", "", "", "", "", ""];
this.emailCode = ["", "", "", "", "", ""]
this.createTimer();
}
})
.catch((res) => {
}
).catch(res=>{
this.emailStap = 1;
});
setTimeout(() => {
this.loginTime = true;
this.loginTime = true
}, 2000);
}
}
},
isCheckAgreement(){
message.info("Agree to all terms, privacy fees and policies");
message.info(
"Agree to all terms, privacy fees and policies"
);
},
changePasswordType(){
this.passwordType =
this.passwordType === "password" ? "text" : "password";
this.passwordType = this.passwordType === 'password' ? 'text' : 'password'
},
//微信登录
wechatLogin(value:any) {
let data = {
code : value.code,
type: 1,
};
type:1
}
Https.axiosGet(Https.httpUrls.parseWeChatCode, {params:data})
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
//谷歌登录
googelLogin(value:any) {
let data = { credential: value, type: 1 };
let data = {credential : value,type:1}
Https.axiosGet(Https.httpUrls.parseGoogleCredential, {params:data})
.then((rv: any) => {
this.setSuccessLogin(rv);
this.setSuccessLogin(rv)
})
.catch((res) => {});
},
@@ -634,9 +574,9 @@ export default defineComponent({
setCookie("userInfo", JSON.stringify(rv));
let userid:any = {
ueserId:rv.userId,
systemUser: rv.systemUser,
};
if (rv.email) userid.email = rv.email;
systemUser:rv.systemUser
}
if(rv.email)userid.email = rv.email
this.store.commit("upUserDetail", userid);
if (window.innerWidth < 768) {
@@ -647,31 +587,36 @@ export default defineComponent({
} else {
this.turnToHomePage("/home");
}
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
sessionStorage.setItem(
"isTimeOne",
JSON.stringify(false)
); //是否需要公告 提示 弹窗
let randomNum: any =
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
Math.floor(Math.random() * 9000000000000000) +
1000000000000000;
sessionStorage.setItem("sessionId", randomNum);
sessionStorage.setItem("record", JSON.stringify([]));
}
},
//邮箱登录提交
submitEmailLogin(emailVerifyCode: any) {
let affiliateRef = sessionStorage.getItem("affiliateRef");
let affiliateRef = sessionStorage.getItem('affiliateRef');
let data = {
email: this.email,
emailVerifyCode: emailVerifyCode,
loginType: "EMAIL",
userId:this.userId,
userEmail: this.email,
userName: this.username,
userPassword: md5(this.password + "abc"),
invitationCode: affiliateRef ? affiliateRef : "",
"userEmail": this.email,
"userName": this.username,
"userPassword": md5(this.password + "abc"),
invitationCode:affiliateRef?affiliateRef:'',
};
Https.axiosPost(Https.httpUrls.designWorksRegisterCode, data)
.then((rv: any) => {
this.setSuccessLogin(rv);
})
.catch((res) => {});
Https.axiosPost(Https.httpUrls.designWorksRegisterCode, data).then(
(rv: any) => {
this.setSuccessLogin(rv)
}
).catch(res=>{
});
},
//修改密码提交
@@ -682,12 +627,14 @@ export default defineComponent({
password: md5(this.newPassword + "abc"),
verifyEmail:false,
};
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then((rv: any) => {
Https.axiosPost(Https.httpUrls.accountResetPwd, data).then(
(rv: any) => {
if (rv) {
message.success("Changing the password successfully");
this.changeIsLogin(1);
}
});
}
);
},
//创建定时器
@@ -710,7 +657,7 @@ export default defineComponent({
//跳转到首页
turnToHomePage(str:any) {
this.getLang();
this.getLang()
// this.$router.push("/home");
// console.log(window.location.search.substring(1));
this.store.commit("clearAllData");
@@ -721,20 +668,22 @@ export default defineComponent({
},
//获取当前语言
getLang(){
let data = {};
Https.axiosPost(Https.httpUrls.getUserLanguage, data).then((rv: any) => {
let data ={}
Https.axiosPost(Https.httpUrls.getUserLanguage, data).then(
(rv: any) => {
if (rv) {
this.locale = rv;
setLang(rv);
this.locale = rv
setLang(rv)
}
});
}
);
},
turnToWindow(url: any) {
window.open(url);
},
cancelDsign(){
this.registerModel = false;
},
this.registerModel = false
}
},
});
</script>
@@ -770,7 +719,7 @@ export default defineComponent({
// transform: translate(-50%,-50%);
// width: 60rem;
// width: 80%;
background: #ffffff;
background: #FFFFFF;
// box-shadow: -0.3rem 2rem 5.9rem 0px rgba(200,200,200,0.3);
padding: 2rem 6rem 2rem;
box-sizing: border-box;
@@ -790,7 +739,7 @@ export default defineComponent({
top: 0;
background: #fff;
transform: scale(0);
transition: 0.3s all;
transition: .3s all;
border: 2px solid;
border-radius: 20px;
.email_last_step{
@@ -813,7 +762,7 @@ export default defineComponent({
text-align: center;
font-size: 3.6rem;
font-weight: bold;
color: #d7d7d7;
color: #D7D7D7;
cursor: pointer;
height: 4rem;
line-height: 4rem;
@@ -875,14 +824,14 @@ export default defineComponent({
left: auto;
transform: translateY(-5rem);
background: #404040;
color: #fff;
color: #FFF;
font-size: 1.4rem;
padding: 2rem;
border-radius: 2rem;
> .item{
display: flex;
align-items: center;
margin-bottom: 0.5rem;
margin-bottom: .5rem;
&:last-child{
margin-bottom: 0;
}
@@ -910,7 +859,7 @@ export default defineComponent({
font-size: 1.4rem;
box-sizing: border-box;
outline: none;
transition: all 0.3s;
transition: all .3s;
&:hover{
border: 0.1rem solid #000;
}
@@ -955,6 +904,8 @@ export default defineComponent({
transform: translateY(1rem);
display: inline-block;
}
}
.login_submit_button {
@@ -967,9 +918,9 @@ export default defineComponent({
font-weight: 500;
color: #ffffff;
cursor: pointer;
transition: all 0.3s;
transition: all .3s;
&:hover{
background: #3c3c3c;
background: #3C3C3C;
}
&[state="2"] {
cursor: not-allowed;
@@ -994,7 +945,7 @@ export default defineComponent({
left: 50%;
transform: translate(-50%,-50%);
width: 60rem;
background: #ffffff;
background: #FFFFFF;
box-shadow: -0.3rem 2rem 5.9rem 0px rgba(200,200,200,0.3);
border-radius: 1rem;
padding: 3rem 6rem 6.5rem;
@@ -1034,7 +985,7 @@ export default defineComponent({
width: 100%;
height: 5rem;
margin-top: 1rem;
border: 0.1rem solid #dfdfdf;
border: 0.1rem solid #DFDFDF;
border-radius: 2.5rem;
padding-left: 2.1rem;
line-height: 5rem;
@@ -1069,6 +1020,7 @@ export default defineComponent({
}
}
.marign_top20 {
margin-top: 2rem;
}
@@ -1126,4 +1078,5 @@ export default defineComponent({
}
}
}
</style>

View File

@@ -1,843 +1,142 @@
<template>
<div class="generalMiniCanvas">
<div class="addDetails_canvasCenter">
<div class="generalMiniCanvas_input generalMiniCanvas_item" :class="{spread:spreadState}">
<div class="generalMiniCanvas_input_item brushwork" v-show="canvasState == 'pencil'">
<span >{{ $t('exportModel.Brushwork') }}:</span>
<a-select ref="select" class="label_select" size="small" v-model:value="brushworkValue"
style="width: 20rem"
@change="brushworkChange"
>
<a-select-option class="label_select_item" v-for="item in brushList" :value="item.value">
<img :src="item.url" alt="">
</a-select-option>
</a-select>
<div class="generalCanvas">
<div class="canvasBox" ref="canvasBox">
<editCanvas v-if="canvasLoad" :config="canvasConfig" :clothingImageUrl="imgUrl" ref="editCanvas"></editCanvas>
</div>
<div class="generalMiniCanvas_input_item" v-show="(canvasState != 'move' && canvasState != 'liquidation' && canvasState != 'movePosition' && canvasState != 'zoomIn' && canvasState != 'zoomOut' && brushworkValue != 'RibbonBrush' && brushworkValue != 'LongfurBrush')">
<span>{{ $t('exportModel.Size') }}</span>
<input type="range" @input="setPencilWidth" min="1" max="50" v-model="canvasPencilWidth[canvasState]">
<div class="mark_loading" v-show="isShowMark">
<a-spin size="large" />
</div>
<div class="generalMiniCanvas_input_item" v-show="canvasState == 'liquidation'">
<span>{{ $t('exportModel.Size') }}</span>{{ canvasPencilWidth.routes }}
<input type="range" @change="routesChange('routes')" min="1" max="100" v-model="canvasPencilWidth.routes">
</div>
<div class="generalMiniCanvas_input_item" v-show="canvasState == 'liquidation'">
<span>{{ $t('exportModel.density') }}</span>
<input type="range" @change="routesChange('density')" min="1" max="100" v-model="canvasPencilWidth.density">
</div>
<div class="generalMiniCanvas_input_item" v-show=" canvasState == 'pencil'">
<span>{{ $t('exportModel.Color') }}</span>
<input type="color" @input="setPencilColor" v-model="canvasPencilColor">
</div>
</div>
<div class="exportCanvasBox_center_data">
<div class="generalMiniCanvas_btn generalMiniCanvas_item" :class="{spread:spreadState}">
<!-- <div @click="setOperation('')" class="generalMiniCanvas_btn_item">
<div>新增</div>
</div> -->
<i class="icon iconfont icon-chehui" @click="canvasGeneral.historyState('')"></i>
<i class="icon iconfont icon-fanchehui" @click="canvasGeneral.historyState('reverse')"></i>
<i class="icon iconfont icon-move" @click="setOperation('movePosition')" :class="{active:canvasState == 'movePosition'}"></i>
<!-- <i class="icon iconfont icon-move" @click="setOperation('move')" :class="{active:canvasState == 'move'}"></i> -->
<i class="icon iconfont icon-bianji" @click="setOperation('pencil')" :class="{active:canvasState == 'pencil'}"></i>
<i class="icon iconfont icon-xiangpi_huaban1" @click="setOperation('eraser')" :class="{active:canvasState == 'eraser'}"></i>
<!-- <i class="icon iconfont icon-IC-yehua" @click="setOperation('liquidation')"></i> -->
<i class="icon iconfont icon-IC-yehua" @click="setLiquefaction()"></i>
<!-- <div class="icon iconfont icon-xiala" :class="{btnRotate:spreadState}" @click="()=>spreadState = !spreadState"></div> -->
<i class="fi fi-rr-zoom-in" @click="setOperation('zoomIn')" :class="{active:canvasState == 'zoomIn'}"></i>
<i class="fi fi-rr-zoom-out" @click="setOperation('zoomOut')" :class="{active:canvasState == 'zoomOut'}"></i>
</div>
<div class="exportCanvasBox_center_box">
<div class="exportCanvasBox_center">
</div>
<!-- <div v-show="arrows.show" class="moveDom" :style="arrows.domStyle"></div>
<div v-show="arrows.show" class="jiantouDom" :style="arrows.jiantouStyle"> </div> -->
<div class="editFrontBack_pencilbtn" v-show="loadingShow" :style="pencilbtnStyle"></div>
</div>
</div>
</div>
<div class="exportCanvasBox_submit" @click="setSubmit(false)">
<div class="started_btn">
{{ $t('addDetails.submit') }}
</div>
</div>
<liquefaction ref="liquefaction" @submitLiquefaction="submitLiquefaction"></liquefaction>
</div>
</template>
<script>
import { defineComponent, ref, reactive, watch, onMounted, onBeforeUnmount, nextTick, toRefs } from "vue";
import creditsDetail from "@/component/Pay/creditsDetail.vue";
import { exportSele,JSRectUpdata,JSchangeType,JScanvasMouseDown,JSSetRemoveImage,JScreateCheck,JSSetTexture } from "@/tool/canvasDrawing";
import {defineComponent, toRefs, provide, h, ref, nextTick, onBeforeUnmount, reactive, onMounted,
} from "vue";
import {message} from 'ant-design-vue'
import { Https } from "@/tool/https";
import { useStore } from "vuex";
import { useI18n } from "vue-i18n";
import canvasGeneral from "@/tool/canvasGeneral";
import { getMousePosition } from "@/tool/mdEvent";
import liquefaction from "@/component/modules/liquefaction.vue";
import canvasGeneral from "@/tool/canvasGeneralCopy";
import editCanvas from "@/component/Canvas/CanvasEditor/index.vue";
export default defineComponent({
components: {
creditsDetail,
liquefaction
editCanvas,
},
emits: ['submitBase64Data'],
props:{
imgUrl:{
type:String,
default:''
}
},
},
// watch: {
// // imgUrl: function(newVal, oldVal) {
// // console.log(newVal);
// // // 当propertyName数据发生变化时执行相应的操作
// // }
// imgUrl(newVal, oldVal) {
// console.log(`imgUrl changed from ${oldVal} to ${newVal}`);
// },
// },
emits:['submitBase64Data'],
setup(props,{emit}) {
let presentState = ref('paypal');
let showPayOrder = ref(false);
let loadingShow = ref(false);
let { t } = useI18n();
let canvas = reactive({});
let scale = 2;
let ratio = [1,1]
let exportWH = 512
let pencilbtnStyle = ref({
background:'',
width:0+'px',
height:0+'px',
display:'none',
left:0+'px',
top:0+'px',
})
let canvasBtn = reactive({
canvasState:'move',
canvasPencilWidth:{
pencil:20,
eraser:20,
routes:30,
density:30,
},
canvasPencilColor:'#000000',
spreadState:false,
})
let canvasWH = ref(0);
let arrows = ref({
show:false,
domStyle:{
left:0,
top:0,
width:0,
height:0,
},
jiantouStyle:{
height:'1px',
transform:`translateY(-100%) rotate(${90}deg)`,
}
})
watch(
() => props.imgUrl,
(newValue, oldValue) => {
init()
const { t } = useI18n();
const store = useStore();
const isShowMark = ref(false)
const component = reactive({
})
const data = reactive({
canvasLoad:false,
canvasConfig:{
},
})
const dataDom = reactive({
editCanvas:null,
canvasBox:null,
})
const openSetData = ()=>{
data.canvasLoad = true
}
const addImage = (value)=>{
console.log(value)
dataDom.editCanvas.addImageToLayer(value.imgUrl)
}
const addBottomImage = (value)=>{
dataDom.editCanvas.changeFixedImage(value)
}
const getData = async ()=>{
}
const getCanvasData = ()=>{
return canvasExport
}
onMounted(() => {
init()
})
onBeforeUnmount(()=>{
canvasGeneral.canvasClear()
})
let reverseCanvasState = ref([])//存放canvas操作
let normalCanvasState = ref([])//存放canvas操作
let canvasState = ref()//存放canvas操作
let keyDown = []//监听键盘的 keydown 和 keyup 事件
let isMovePostion = false
let init = ()=>{
normalCanvasState.value = []
reverseCanvasState.value = []
showPayOrder.value = true;
ratio = [1,1]
nextTick(()=>{
let canvasBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center");
document.removeEventListener('mousemove', mouseMove);
document.removeEventListener('touchmove', touchmove);
let img = new Image();
img.onload = async function(){
loadingShow.value = true
let height = canvasBox.offsetHeight;
canvasWH.value = height
// canvasBox.style.width = height+'px'
let wScale = 1
let hScale = 1
if(img.width>img.height){
hScale = img.height/img.width
exportWH = img.width
}else{
wScale = img.width/img.height
exportWH = img.height
}
ratio = [wScale,hScale]
canvas = canvasGeneral.canvasInit(canvasBox,{
width:canvasWH.value * wScale,
height:canvasWH.value * hScale,
})
canvas.selection = false;
// canvas.set({
// backgroundColor: 'lightblue'
// });
scale = img.height/canvas.height
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
fabric.Object.prototype.cornerSize = 10
fabric.Object.prototype.transparentCorners = false
await fabric.Image.fromURL(props.imgUrl, async function(img) {
// 设置背景图对象的宽度和高度与 canvas 相同
img.scaleToWidth(canvas.width);
img.scaleToHeight(canvas.height);
img.set({
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
// 将背景图添加到 canvas 的底层
await canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
setPencilWidth()
canvasGeneral.updateCanvasState()
},{ crossOrigin: "Anonymous" });
// 鼠标抬起事件
canvas.on('mouse:up', function(event) {
if(isMovePostion)isMovePostion = false
// if(canvasBtn.canvasState != 'move')canvasGeneral.updateCanvasState('mouseUp')
});
canvas.on("mouse:down", event=>setCanvasDown(event));
canvas.on('mouse:wheel', opt => {
const delta = opt.e.deltaY // 滚轮,向上滚一下是 -100向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
canvas.zoomToPoint(
{ // 关键点
x: opt.e.offsetX,
y: opt.e.offsetY
},
zoom
)
opt.e.preventDefault()
opt.e.stopPropagation()
upDataPencilWidth(zoom)
})
canvas.on("mouse:move", event=>setCanvasMove(event));
//画布上移动
document.addEventListener('mousemove', mouseMove);
document.addEventListener('touchmove', touchmove);
setOperation('pencil')
img.remove()
if(props.imgUrl){
let img = new Image()
img.onload = ()=>{
let domHeight = dataDom.canvasBox.offsetHeight
let imgHeight = img.height
data.canvasConfig.height = domHeight
data.canvasConfig.width = imgHeight/domHeight * img.width
// canvasWH.value = height
// // canvasBox.style.width = height+'px'
// let wScale = 1
// let hScale = 1
// if(img.width>img.height){
// hScale = img.height/img.width
// exportWH = img.width
// }else{
// wScale = img.width/img.height
// exportWH = img.height
// }
// ratio = [wScale,hScale]
// canvas = canvasGeneral.canvasInit(canvasBox,{
// width:canvasWH.value * wScale,
// height:canvasWH.value * hScale,
// })
// canvas.selection = false;
// dataDom.editCanvas.addImageToLayer(img)
data.canvasLoad = true
}
img.src = props.imgUrl
})
}
let clearCanvas = ()=>{
canvasBtn.canvasState = 'move'
canvasBtn.spreadState = false
canvasGeneral.canvasClear()
}
let mouseMove = (event)=>{
let e = getMousePosition(event,false)
setDomMove(e)
}
let touchmove = (event)=>{
let e = getMousePosition(event,true)
setDomMove(e)
}
let setDomMove = (event)=>{
if(canvas.isDrawingMode){
canvas.setCursor('none');
}
let canvasCenterBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center_box");
if(!canvasCenterBox)return
let parentX = event.clientX - canvasCenterBox.getBoundingClientRect().left
let parentY = event.clientY - canvasCenterBox.getBoundingClientRect().top
pencilbtnStyle.value.left = parentX + "px"
pencilbtnStyle.value.top = parentY+'px'
}
let setCanvasMove = (event) =>{
if(canvasBtn.canvasState == 'movePosition' && isMovePostion)setCanvasPosition(event)
}
let lastPosX = 0
let lastPosY = 0
let setCanvasDown = (event)=>{
if(canvasBtn.canvasState == 'movePosition'){
isMovePostion = true;
lastPosX = event.pointer.x;
lastPosY = event.pointer.y;
return
}
if(canvasBtn.canvasState == 'zoomIn' || canvasBtn.canvasState == 'zoomOut'){
setCanvasZoom(event)
return
}
}
let setCanvasPosition = (event)=>{
const e = event;
const vpt = canvas.viewportTransform;
vpt[4] += e.pointer.x - lastPosX; // 更新水平偏移
vpt[5] += e.pointer.y - lastPosY; // 更新垂直偏移
canvas.requestRenderAll(); // 请求重绘画布
lastPosX = e.pointer.x;
lastPosY = e.pointer.y;
}
let setCanvasZoom = (opt)=>{
let zoom = canvas.getZoom() // 获取画布当前缩放值
let num = -100
if(canvasBtn.canvasState == 'zoomOut') num = 100
zoom *= 0.999 ** num
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
// console.log(zoom);
canvas.zoomToPoint(
{ // 关键点
x: opt.pointer.x,
y: opt.pointer.y
},
zoom
)
opt.e.preventDefault()
opt.e.stopPropagation()
upDataPencilWidth(zoom)
}
let setOperation = (str)=>{
canvasBtn.canvasState = str
let canvasCenterBox = document.querySelector(".generalMiniCanvas .exportCanvasBox_center_box");
let classList = canvasCenterBox.className.split(' ');
canvasCenterBox.className = 'exportCanvasBox_center_box'
if(str == 'move'){
setMove()
pencilbtnStyle.value.display = `none`
canvasCenterBox.className = 'exportCanvasBox_center_box'
}else if(str == 'pencil'){
setPencil()
pencilbtnStyle.value.display = `block`
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'eraser'){
setEraser()
pencilbtnStyle.value.display = `block`
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'liquidation'){
canvas.isDrawingMode = false
canvasCenterBox.className = 'exportCanvasBox_center_box cursorNone'
}else if(str == 'zoomIn' || str == 'zoomOut'){
pencilbtnStyle.value.display = `none`
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = false);
canvasCenterBox.className = 'exportCanvasBox_center_box'
}else if(str == 'movePosition'){
canvas.isDrawingMode = false
pencilbtnStyle.value.display = `none`
canvas.forEachObject((obj) =>obj.selectable = false);
canvasCenterBox.className = 'exportCanvasBox_center_box cursorMove'
}
}
let brushworkValue = ref('PencilBrush')
let brushworkChange = (value)=>{
brushworkValue.value = value
setPencil()
}
let setMove = ()=>{
canvas.isDrawingMode = false
canvas.forEachObject((obj) =>obj.selectable = true);
}
let brushList = ref([
{
value:'PencilBrush',
url:'/image/brush/PencilBrush.jpg'
},{
value:'Marking',
url:'/image/brush/PencilBrush-2.jpg'
},{
value:'InkBrush',
url:'/image/brush/InkBrush.jpg'
},{
value:'CrayonBrush',
url:'/image/brush/CrayonBrush.jpg'
},{
value:'RibbonBrush',
url:'/image/brush/RibbonBrush.jpg'
},{
value:'MarkerBrush',
url:'/image/brush/MarkerBrush.jpg'
},{
value:'WritingBrush',
url:'/image/brush/WritingBrush.jpg'
},{
value:'LongfurBrush',
url:'/image/brush/LongfurBrush.jpg'
},{
value:'SpraypaintBrush',
url:'/image/brush/SpraypaintBrush.jpg'
},
])
let setPencil = ()=>{
let pencil
canvas.isDrawingMode = true//开启绘画模式
if(brushworkValue.value == 'PencilBrush'){
pencil = new fabric.PencilBrush(canvas,{}); //普通笔
}else if(brushworkValue.value == 'Marking'){
pencil = new fabric.PencilBrush(canvas,); //记号笔
}else if(brushworkValue.value == 'InkBrush'){
pencil = new fabric.InkBrush(canvas,{}); //油画笔
}else if(brushworkValue.value=='CrayonBrush'){
pencil = new fabric.CrayonBrush(canvas,{}); //蜡笔
}else if(brushworkValue.value == 'RibbonBrush'){
pencil = new fabric.RibbonBrush(canvas,{width: 1,}); //色带
}else if(brushworkValue.value == 'MarkerBrush'){
pencil = new fabric.MarkerBrush(canvas,{}); //书写笔
// pencil = new fabric.PenBrush(canvas,{}); //书写笔
}else if(brushworkValue.value == 'WritingBrush'){
pencil = new fabric.WritingBrush(canvas,{}); //毛笔
}else if(brushworkValue.value == 'LongfurBrush'){
pencil = new fabric.LongfurBrush(canvas,{width: 1,}); //色带
}else if(brushworkValue.value == 'SpraypaintBrush'){
pencil = new fabric.SpraypaintBrush(canvas,{}); //长毛刷
}
canvas.freeDrawingBrush = pencil
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
canvas.freeDrawingBrush.isEraser = false
setPencilWidth()
pencilColor()
}
let setEraser = ()=>{
canvas.isDrawingMode = true
let eraser = new fabric.EraserBrush(canvas)
canvas.freeDrawingBrush = eraser
canvas.requestRenderAll();
canvas.freeDrawingBrush.isEraser = true
pencilbtnStyle.value.background = `rgb(255,255,255)`
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]);
setPencilWidth()
}
let upDataPencilWidth = (zoom)=>{
if(canvasBtn.canvasPencilWidth[canvasBtn?.canvasState]){
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]) / zoom;
}
}
let deleteObj = ()=> {
// if(!canvas.getActiveObjects()){
// return
// }
let target = canvas.getActiveObjects()
target.forEach((item)=>{
canvas.fxRemove(item, {
onComplete(){
canvas.discardActiveObject(); // 丢弃当前选中的对象
canvas.renderAll(); // 重新渲染 Canvas
}
})
canvas.FX_DURATION = 300
})
}
let setTimeOut = {
pencilWidth:null,
color:null,
}
let setPencilWidth = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOut.pencilWidth)
setTimeOut.pencilWidth = setTimeout(()=>{
let zoom = canvas.getZoom() // 获取画布当前缩放值
canvas.freeDrawingBrush.width = Number(canvasBtn.canvasPencilWidth[canvasBtn.canvasState]) / zoom
pencilbtnStyle.value.height = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
pencilbtnStyle.value.width = canvasBtn.canvasPencilWidth[canvasBtn.canvasState]+'px'
if(brushworkValue.value == 'RibbonBrush' || brushworkValue.value == 'LongfurBrush'){
canvas.freeDrawingBrush.width = 1;
pencilbtnStyle.value.height = 1+'px'
pencilbtnStyle.value.width = 1+'px'
}
},300)
}
let setPencilColor = ()=>{//切换颜色给铅笔设置颜色
clearTimeout(setTimeOut.color)
// clearTimeout(setTimeOut.colorHistory)
setTimeOut.color = setTimeout(()=>{
pencilColor()
},200)
// setTimeOut.colorHistory = setTimeout(()=>{
// colorHistoryList.value.push(canvasPencilColor.value)
// },1000)
}
let hexToRgba=(hex, alpha)=> {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
let pencilColor = ()=>{
if(canvas.freeDrawingBrush.isEraser){
canvas.freeDrawingBrush.color = '#FFFFFF';
}else{
pencilbtnStyle.value.background = canvasBtn.canvasPencilColor
if(brushworkValue.value == 'Marking'){
console.log(canvasBtn.canvasPencilColor);
console.log(hexToRgba(canvasBtn.canvasPencilColor,.5));
canvas.freeDrawingBrush.color = hexToRgba(canvasBtn.canvasPencilColor,.5)
}else{
canvas.freeDrawingBrush.color = canvasBtn.canvasPencilColor
data.canvasLoad = true
}
}
}
let routesChange = (str)=>{
canvasBtn.canvasPencilWidth[str] = Math.round(canvasBtn.canvasPencilWidth[str]/10)*10;
if (canvasBtn.canvasPencilWidth[str] < 10) {
canvasBtn.canvasPencilWidth[str] = 10; // 设置为最小值
} else if (canvasBtn.canvasPencilWidth[str] > 100) {
canvasBtn.canvasPencilWidth[str] = 100; // 设置为最大值
}
}
let setSubmit = (liquefation)=>{
return new Promise((resolve,reject)=>{
var allObjects = canvas.getObjects();
// return
// if(allObjects.length == 0){
// return message.info(t('addDetails.jsContent1'))
// }
var canvasDom = document.createElement("canvas");
let exportCanvas = new fabric.Canvas(canvasDom, {
backgroundColor: "#FFFFFF",
width: exportWH * ratio[0],
height: exportWH * ratio[1],
isDrawingMode: false, // 开启绘图模式
});
canvas.backgroundImage.clone(async (back)=>{
back.set({
scaleX:1,
scaleY:1,
left:back.left*scale,
top:back.top*scale ,
onBeforeUnmount(()=>{
data.canvasLoad = false
// canvasGeneral.canvasClear()
})
exportCanvas.backgroundImage = back
await new Promise((resolve, reject) => {
if(allObjects.length == 0)resolve('')
allObjects.forEach((item,index)=>{
// let obj = fabric.util.object.clone(item);
if(item.type == 'circle')return
let obj
item.clone((cloned)=>{
console.log(cloned);
obj = cloned
console.log(obj.set);
if(obj.set){
obj.set(
{
scaleX:(item.scaleX?item.scaleX:1)*scale,
scaleY:(item.scaleY?item.scaleY:1)*scale,
left:item.left*scale,
top:item.top*scale,
}
)
}
// else{
// console.log(item.width,scale);
// obj.width = (item.width?item.width:1)*scale
// obj.height = (item.height?item.height:1)*scale
// obj.left = item.left*scale
// obj.top = item.top*scale
// }
exportCanvas.add(obj)
if(index == allObjects.length - 1){
resolve('')
}
})
})
})
let position = JSON.parse(JSON.stringify(canvas.viewportTransform))
position[4] *= scale
position[5] *= scale
//设置画布当前那位置和缩放
// exportCanvas.viewportTransform = position
let data = exportCanvas.toDataURL("image/png");
if(liquefation){
return resolve(data)
}
cancelDsign()
clearCanvas()
emit('submitBase64Data',data)
resolve('')
})
})
}
let cancelDsign = ()=>{
showPayOrder.value = false
}
let liquefactionData = ref(null)
let liquefaction = ref(null)
let submitLiquefaction = (rv)=>{
// const originalWidth = liquefactionData.value.width // 保存原始宽度
// const originalHeight = liquefactionData.value.height; // 保存原始高度
canvas.viewportTransform = [1,0,0,1,0,0]
fabric.Image.fromURL(rv, function(img) {
// 设置背景图对象的宽度和高度与 canvas 相同
img.scaleToWidth(canvas.width);
img.scaleToHeight(canvas.height);
img.set({
scaleX: canvas.width / img.width,
scaleY: canvas.height / img.height
});
// 将背景图添加到 canvas 的底层
canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas));
if(!fabric.Object.prototype.controls.deleteControl){
JSSetRemoveImage(deleteObj)
}else{
fabric.Object.prototype.controls.deleteControl.mouseUpHandler = deleteObj
}
setPencilWidth()
canvasGeneral.updateCanvasState()
},{ crossOrigin: "Anonymous" });
}
let setLiquefaction =async ()=>{
// const activeObjects = canvas.backgroundImage // 获取选中的对象
// console.log(setSubmit(true));
let activeObjects = await setSubmit(true)
if (activeObjects) {
liquefactionData.value = activeObjects
liquefaction.value.init(activeObjects)
} else {
// message.info(useI18.t('exportModel.jsContent6'))
return null;
}
}
return {
presentState,
showPayOrder,
loadingShow,
t,
pencilbtnStyle,
...toRefs(canvasBtn),
arrows,
liquefactionData,
liquefaction,
init,
setOperation,
setPencilWidth,
setPencilColor,
setSubmit,
cancelDsign,
submitLiquefaction,
setLiquefaction,
routesChange,
brushList,
brushworkValue,
brushworkChange,
canvasGeneral,
...toRefs(data),
...toRefs(dataDom),
isShowMark,
addImage,
getData,
getCanvasData,
};
},
data() {
data(prop) {
return {
};
},
computed: {
},
watch: {
},
mounted() {},
methods: {
},
});
</script>
<style lang="less">
.generalMiniCanvas{
position: relative;
height: 100%;
display: flex;
<style lang="less" scoped>
.generalCanvas{
width: 100%;
// flex-direction: column;
margin: 0 auto;
flex-direction: row;
flex: 1;
overflow: hidden;
.generalMiniCanvas_item{
// position: relative;
background: #fff;
position: absolute;
display: flex;
// border: 0.2rem solid #c4c4c4;
width: 25rem;
border-radius: 4px; /* 设置圆角半径 */
flex-wrap: wrap;
.generalMiniCanvas_btn_item{
display: flex;
align-items: center;
padding: 1rem 0;
}
}
.generalMiniCanvas_input,.generalMiniCanvas_btn{
z-index: 2;
padding: 1rem 1.5rem;
height: 100%;
position: relative;
width: auto;
flex-wrap: nowrap;
display: flex;
flex-direction: column;
}
.generalMiniCanvas_input{
flex-direction: row;
align-items: center;
margin-left: 7rem;
height: 6rem;
.generalMiniCanvas_input_item{
display: flex;
margin-right: 3rem;
align-items: center;
&.brushwork{
img{
width: 100%;
max-height: 100%;
object-fit: contain;
}
}
span{
margin-right: 1rem;
}
}
.generalMiniCanvas_input_item:last-child{
margin-right: 0;
}
}
.generalMiniCanvas_btn{
input{
// width: 100%;
width: 30rem;
// margin-top: 1rem;
flex: 1;
}
.icon-xiala{
position: absolute;
width: 2rem;
bottom: 0;
transform: translate(-50%, 90%);
left: 50%;
width: 6rem;
background: #fff;
text-align: center;
cursor: pointer;
&.icon-xiala::before{
transition: all .3s;
}
&.btnRotate::before{
transform: rotate(180deg);
display: block;
}
}
i{
font-size: 2.5rem;
cursor: pointer;
width: 4rem;
height: 4rem;
display: flex;
align-items: center;
justify-content: center;
&.active{
border: 1px solid;
border-radius: .4rem;
}
}
&.spread{
transform: translate(-50%,0);
}
}
.addDetails_canvasCenter{
flex: 1;
overflow: hidden;
display: flex;
// flex-direction: column;
// flex-direction: row;
position: relative;
margin: 0 auto;
flex-direction: column;
}
.exportCanvasBox_center_data{
flex: 1;
display: flex;
overflow: hidden;
}
.exportCanvasBox_center_box{
padding: 3rem;
height: 100%;
padding-top: 4rem;
> .canvasBox{
flex: 1;
position: relative;
overflow: hidden;
width: 100%;
background: #e6e6e6;
cursor: inherit;
&.cursorNone:hover{
cursor: none;
}
&.cursorMove:hover{
cursor: move;
canvas{
cursor: move !important;
}
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center{
height: 100%;
flex: 1;
position: relative;
overflow: hidden;
background: #e6e6e6;
// overflow: scroll;
.canvas-container{
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.editFrontBack_pencilbtn{
position: absolute;
z-index: 1;
border-radius: 50%;
border: 1px solid #000;
pointer-events: none;
transform: translate(-50%,-50%);
}
}
.exportCanvasBox_center:hover{
.generalMiniCanvas_btn{
// transform: translate(-50%,-101%);
// &.spread{
// transform: translate(-50%,0);
// }
}
}
}
.exportCanvasBox_submit{
margin-top: auto;
margin-left: 1rem;
text-align: center;
}
</style>

View File

@@ -21,8 +21,8 @@ import "swiper/css/pagination";
// import "@/tool/fabric.brushes.js";
// import "@/tool/fabric.min.js";
const app = createApp(App);
flexible();
flexible()
// alert(window.innerWidth)
import { getCookie, setCookie } from "@/tool/cookie";
import loadingGif from "./assets/images/homePage/loading.gif";

View File

@@ -1,11 +1,16 @@
import { getUniversalZoomLevel } from "@/tool/util";
let flexible = (designWidth, maxWidth,minWidth) =>{
var doc = document, win = window, docEl = doc.documentElement, remStyle = document.createElement("style"), tid;
designWidth = designWidth || 1920;
maxWidth = maxWidth || 2560;
minWidth = minWidth || 1024;
minWidth = minWidth || 500;
// minWidth = minWidth || 1024;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
var height = docEl.getBoundingClientRect().height;
width = getUniversalZoomLevel() * width
height = getUniversalZoomLevel() * height
maxWidth = maxWidth || 1920;
if(width/height>1.98) width = height * 1.98;
width > maxWidth && (width = maxWidth);

View File

@@ -1,37 +1,36 @@
import Fingerprint2 from "fingerprintjs2"; //获取浏览器唯一标识
import Fingerprint2 from 'fingerprintjs2';//获取浏览器唯一标识
const isEmail = (email) => {
// let reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,})$/
let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
let result = reg.test(email);
return result;
};
let reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
let result = reg.test(email)
return result
}
const getUploadUrl = () => {
let url = import.meta.env.VITE_APP_BASE_URL || "";
let url = process.env.VUE_APP_BASE_URL || ''
// let url = "http://18.167.251.121:10086"
return url;
};
return url
}
const getMinioUrl = (url) => {
const { pathname } = new URL(url);
const result = pathname.slice(1);
return result;
};
const rgbaToHex = (rgba) => {
// rgba转16进制
let hex = "#";
return result
}
const rgbaToHex = (rgba)=> { // rgba转16进制
let hex = '#';
rgba.forEach((i,index) => {
if(index == 3){
hex += Math.round(i * 255).toString(16);
hex += Math.round(i * 255).toString(16)
}else{
hex += Number(i).toString(16).padStart(2, "0");
hex += Number(i).toString(16).padStart(2, '0');
}
});
return hex;
};
}
function base64ToFile(urlData,name) {
let arr = urlData.split(",");
let arr = urlData.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
@@ -40,13 +39,12 @@ function base64ToFile(urlData, name) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], name, {
type: mime,
type: mime
});
}
function dataURLtoBlob(dataurl) {
//吧data url转为blob对象
var arr = dataurl.split(",");
function dataURLtoBlob(dataurl) {//吧data url转为blob对象
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
@@ -57,43 +55,37 @@ function dataURLtoBlob(dataurl) {
return new Blob([u8arr], { type: mime });
}
function blobToFile(blob, fileName) {
//给blob文件设置名字和日期
function blobToFile(blob, fileName) {//给blob文件设置名字和日期
blob.lastModifiedDate = new Date();
blob.name = fileName;
return blob;
}
//下载图片
function downloadIamge(imgsrc, name) {
// 下载图片地址和图片名
var image = new Image();
function downloadIamge(imgsrc, name) { // 下载图片地址和图片名
var image = new Image()
// 解决跨域 Canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.setAttribute('crossOrigin', 'anonymous')
image.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
var url = canvas.toDataURL("image/png"); // 得到图片的base64编码数据
var a = document.createElement("a"); // 生成一个a元素
var event = new MouseEvent("click"); // 创建一个单击事件
a.download = name || "generate"; // 设置图片名称
a.href = url; // 将生成的URL设置为a.href属性
a.target = "_blank";
a.dispatchEvent(event); // 触发a的单击事件
image.remove();
};
image.src = imgsrc;
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
var context = canvas.getContext('2d')
context.drawImage(image, 0, 0, image.width, image.height)
var url = canvas.toDataURL('image/png') // 得到图片的base64编码数据
var a = document.createElement('a') // 生成一个a元素
var event = new MouseEvent('click') // 创建一个单击事件
a.download = name || 'generate' // 设置图片名称
a.href = url // 将生成的URL设置为a.href属性
a.target = '_blank'
a.dispatchEvent(event) // 触发a的单击事件
image.remove()
}
image.src = imgsrc
}
function dataURLtoFile(dataurl, filename) {
//吧url转为文件对象指定文件名称
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
function dataURLtoFile(dataurl, filename) {//吧url转为文件对象指定文件名称
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
@@ -101,44 +93,42 @@ function dataURLtoFile(dataurl, filename) {
return blobToFile(blob, filename);
}
const base64toFile = (dataurl, filename = "file") => {
//转换base64
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split("/")[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
const base64toFile = (dataurl, filename = 'file') => {//转换base64
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime,
});
};
type: mime
})
function rgbToHsv([R, G, B]) {
//根据rgb获取hsv
R /= 255;
G /= 255;
B /= 255;
const max = Math.max(R, G, B);
const min = Math.min(R, G, B);
const delta = max - min;
var H, S, V;
}
function rgbToHsv([R, G, B]) {//根据rgb获取hsv
R /= 255
G /= 255
B /= 255
const max = Math.max(R, G, B)
const min = Math.min(R, G, B)
const delta = max - min
var H, S, V
if (delta === 0) {
H = 0;
} else if (max === R) {
H = ((G - B) / delta) % 6;
} else if (max === G) {
H = (B - R) / delta + 2;
} else {
// max === B
} else { // max === B
H = (R - G) / delta + 4;
}
H = Math.round(H * 60); // 范围为 0-360
if (H < 0) {
H = 360 + H;
H = 360 + H
}
if (max === 0) {
S = 0;
@@ -147,11 +137,10 @@ function rgbToHsv([R, G, B]) {
}
S = Math.round(S * 100); // 范围为 0-100
V = Math.round(max * 100); // 范围为 0-100
return [H, S, V];
return [H, S, V]
}
const formatTime = (timestamp, fmt) => {
//吧时间戳转为YYYY-MM-DD hh:mm:ss格式
const formatTime = (timestamp, fmt) => {//吧时间戳转为YYYY-MM-DD hh:mm:ss格式
// date = new Date(), fmt = 'MM/dd/yyyy';
let date = new Date();
date.setTime(timestamp * 1000);
@@ -161,46 +150,38 @@ const formatTime = (timestamp, fmt) => {
}
// console.log(formatRule)
let o = {
"M+": date.getMonth() + 1, // 月份
"D+": date.getDate(), // 日
"h+": date.getHours(), // 小时
"m+": date.getMinutes(), // 分
"s+": date.getSeconds(), // 秒
"q+": Math.floor((date.getMonth() + 3) / 3), // 季度
"S+": date.getMilliseconds(), // 毫秒
a: date.getHours() > 12 ? "PM" : "AM", // 上午还是下午
'M+': date.getMonth() + 1, // 月份
'D+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
'S+': date.getMilliseconds(), // 毫秒
'a': date.getHours() > 12
? 'PM'
: 'AM' // 上午还是下午
};
if (/(Y+)/.test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
);
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
if (/(a)/.test(fmt) && o["h+"] > 12) {
o["h+"] = o["h+"] - 12;
if (/(a)/.test(fmt) && o['h+'] > 12) {
o['h+'] = o['h+'] - 12
}
for (let k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
if (new RegExp('(' + k + ')').test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1)
? (o[k])
: (('00' + o[k]).substr(('' + o[k]).length)));
}
}
return fmt;
};
}
const isMoible = () => {
//判断是否是移动端
let is_mobile =
navigator.userAgent
.toLowerCase()
.match(
/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i
) != null;
const isMoible = () => {//判断是否是移动端
let is_mobile = navigator.userAgent.toLowerCase().match(/(ipad|ipod|iphone|android|coolpad|mmp|smartphone|midp|wap|xoom|symbian|j2me|blackberry|wince)/i) != null;
// alert(navigator.userAgent.toLowerCase())
var isiPad = navigator.maxTouchPoints && navigator.maxTouchPoints > 1;
var isiPad = (navigator.maxTouchPoints && navigator.maxTouchPoints > 1);
// if (is_mobile) {
// return true//判断是否在正则内
// } else if(window.matchMedia("(pointer:fine)").matches){
@@ -209,11 +190,11 @@ const isMoible = () => {
// isiPad//判断触摸点
// }
if (is_mobile) {
return true; //判断是否在正则内
return true//判断是否在正则内
} else{
return isiPad; //判断触摸点
return isiPad//判断触摸点
}
}
};
let setPubDate = (date)=>{
const timestamp = new Date(date);
@@ -244,18 +225,16 @@ let setPubDate = (date) => {
} else {
return `1 minute ago`;
}
};
}
function getBrowserInfo() {
//获取是什么浏览器
function getBrowserInfo() {//获取是什么浏览器
var agent = navigator.userAgent.toLowerCase();
var userAgent = navigator.userAgent;
var regStr_ie = /msie [\d.]+;/gi;
var regStr_ff = /firefox\/[\d.]+/gi;
var regStr_ff = /firefox\/[\d.]+/gi
var regStr_chrome = /chrome\/[\d.]+/gi;
var regStr_saf = /safari\/[\d.]+/gi;
var isIE =
userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
//IE
if (agent.indexOf("msie") > 0) {
@@ -274,11 +253,13 @@ function getBrowserInfo() {
return agent.match(regStr_saf);
}
}
async function murmur() {
//生成唯一标识 ,暂时没有使用
async function murmur(){//生成唯一标识 ,暂时没有使用
return await new Promise((resolve,reject)=>{
Fingerprint2.get(function (components) {
const values = components.map(function (component, index) {
const values = components.map(function (
component,
index
) {
if (index === 0) {
//把微信浏览器里UA的wifi或4G等网络替换成空,不然切换网络会ID不一样
return component.value.replace(/\bNetType\/\w+\b/, "");
@@ -287,9 +268,9 @@ async function murmur() {
});
// 生成最终id murmur
let murmur = Fingerprint2.x64hash128(values.join(""), 31);
resolve(murmur);
});
resolve(murmur)
});
})
}
/**
* @description: 计算canvas渐变起始坐标
@@ -343,7 +324,7 @@ function calculateGradientCoordinate(width, height, angle) {
const alpha = Math.round(
(Math.asin(width / Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2))) *
180) /
Math.PI
Math.PI,
);
// 当渐变轴分别于矩形的两条对角线重合情况下的四种结果
@@ -447,49 +428,45 @@ function calculateGradientCoordinate(width, height, angle) {
const setGradual = (colorObj,colorWidth,colorHeight)=>{
return new Promise((resolve, reject) => {
let width = colorWidth || 320;
let height = colorHeight || 700;
let width = colorWidth || 320
let height = colorHeight || 700
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
let { x0, y0, x1, y1 } = calculateGradientCoordinate(
width,
height,
colorObj.angle
);
let {x0, y0, x1, y1} = calculateGradientCoordinate(width,height,colorObj.angle)
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
colorObj.gradientList.forEach((item) => {
let left = item.left.split("%")[0] / 100;
let rgba = `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`;
colorObj.gradientList.forEach(item => {
let left = item.left.split('%')[0]/100
let rgba = `rgba(${item.rgba.r},${item.rgba.g},${item.rgba.b},${item.rgba.a})`
gradient.addColorStop(left, rgba); // 起始颜色
});
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
// let dataURL = canvas.toDataURL('image/jpg');
resolve(canvas.toDataURL("image/jpg"));
});
};
resolve(canvas.toDataURL('image/jpg'))
})
}
function segmentImage(markerImage,fullImage,size){
return new Promise((resolve, reject) => {
const markerCanvas = document.createElement("canvas");
const fullCanvas = document.createElement("canvas");
const nullCanvas = document.createElement("canvas");
const ctx1 = markerCanvas.getContext("2d");
const ctx2 = fullCanvas.getContext("2d");
const ctx3 = nullCanvas.getContext("2d");
markerCanvas.width = size.width;
markerCanvas.height = size.height;
fullCanvas.height = size.height;
fullCanvas.width = size.width;
nullCanvas.height = size.height;
nullCanvas.width = size.width;
let targetFrontUrl = "";
let targetBackUrl = "";
const markerCanvas = document.createElement('canvas');
const fullCanvas = document.createElement('canvas');
const nullCanvas = document.createElement('canvas');
const ctx1 = markerCanvas.getContext('2d');
const ctx2 = fullCanvas.getContext('2d');
const ctx3 = nullCanvas.getContext('2d');
markerCanvas.width=size.width
markerCanvas.height=size.height
fullCanvas.height=size.height
fullCanvas.width=size.width
nullCanvas.height=size.height
nullCanvas.width=size.width
let targetFrontUrl = ''
let targetBackUrl = ''
const marker = new Image();
const full = new Image();
marker.crossOrigin = "anonymous";
full.crossOrigin = "anonymous";
marker.crossOrigin = 'anonymous';
full.crossOrigin = 'anonymous';
marker.onload = () => {
ctx1.drawImage(marker,0,0 ,size.width, size.height);
full.onload = () => {
@@ -500,6 +477,7 @@ function segmentImage(markerImage, fullImage, size) {
};
marker.src = markerImage;
function segmentImageItem() {
const markerData = ctx1.getImageData(0, 0, size.width, size.height);
const fullData = ctx2.getImageData(0, 0, size.width, size.height);
@@ -513,7 +491,8 @@ function segmentImage(markerImage, fullImage, size) {
// (Math.abs(b - color.b) < threshold) || (Math.abs(0 - color.b) < threshold)
const isColorMatch = (r, g, b, color) =>
(color.r >= color.g && r >= g) || (color.r < color.g && r < g);
((color.r >= color.g) && r >= g) ||
((color.r < color.g) && r < g)
// (Math.abs(b - color.b) < threshold || Math.abs(0 - color.b) < threshold)
@@ -524,7 +503,7 @@ function segmentImage(markerImage, fullImage, size) {
const g = markerData.data[i + 1];
const b = markerData.data[i + 2];
let a = markerData.data[i + 3];
a > 1 ? (a = 255) : 0;
a>1?a = 255:0
if (r>=g && a>1) {
// 将完整图像中对应的像素复制到第一个输出图像
output1.data[i] = fullData.data[i];
@@ -569,23 +548,23 @@ function segmentImage(markerImage, fullImage, size) {
}
}
const createImageURL = (imageData) => {
const canvas = document.createElement("canvas");
const canvas = document.createElement('canvas');
canvas.width = size.width;
canvas.height = size.height;
const ctx = canvas.getContext("2d");
const ctx = canvas.getContext('2d');
ctx.putImageData(imageData, 0, 0);
let data = canvas.toDataURL("image/png");
canvas.remove();
let data = canvas.toDataURL('image/png')
canvas.remove()
return data;
};
targetBackUrl = createImageURL(output2);
targetFrontUrl = createImageURL(output1);
resolve({ targetFrontUrl, targetBackUrl });
markerCanvas.remove();
fullCanvas.remove();
nullCanvas.remove();
targetBackUrl =createImageURL(output2)
targetFrontUrl =createImageURL(output1)
resolve({targetFrontUrl, targetBackUrl})
markerCanvas.remove()
fullCanvas.remove()
nullCanvas.remove()
}
});
})
}
export {
isEmail,
@@ -607,4 +586,4 @@ export {
setGradual,
calculateGradientCoordinate,
segmentImage,
};
}

View File

@@ -35,7 +35,7 @@
<div v-for="historyTypeItem in historyData.updateTimeType" :key="historyTypeItem">
<div class="timeType" v-if="historyTypeItem == 'Todaylist' && item.Todaylist.length>0">Today</div>
<div class="timeType" v-if="historyTypeItem == 'Yesterdaylist' && item.Yesterdaylist.length>0">Yesterday</div>
<div class="timeType" v-if="historyTypeItem == 'WithinAWeeklist' && item.WithinAWeeklist.length>0">Within a wseek</div>
<div class="timeType" v-if="historyTypeItem == 'WithinAWeeklist' && item.WithinAWeeklist.length>0">Within a week</div>
<div class="timeType" v-if="historyTypeItem == 'EarlierTodaylist' && item.EarlierTodaylist.length>0">Earlier</div>
<div v-for="childItem,index in item[historyTypeItem]" class="detailItem history" @click="setHistory(item,childItem)" :class="{active:openTypeChild == childItem.id}">
<div class="text" style="width: 100%;">
@@ -844,13 +844,13 @@ export default defineComponent({
};
await Https.axiosPost(Https.httpUrls.accountLogout, data).then((rv) => {
// WriteCookie("token");
clonAllCookie()
});
this.$router.replace("/");
this.store.commit('createDetail')
this.store.commit('createProbject')
// WriteCookie("token");
clonAllCookie()
// window.location.reload()
},
@@ -983,6 +983,11 @@ export default defineComponent({
border-radius: 2rem;
&.history{
flex: 1;
> .detailBox{
>.detail{
min-height: 10rem;
}
}
}
> .titleBox{
padding: 1.2rem;
@@ -1027,7 +1032,6 @@ export default defineComponent({
> .detail{
position: relative;
height: 100%;
min-height: 10rem;
> img{
width: 100%;
}
@@ -1421,7 +1425,7 @@ export default defineComponent({
height: 6rem;
width: 6rem;
position: relative;
transform-origin: top;
// transform-origin: top;
overflow: hidden;
z-index: 2;
left: 0;
@@ -1429,9 +1433,10 @@ export default defineComponent({
cursor: pointer;
background: #fff;
img{
background: #000;
width: 100%;
height: 100%;
object-fit: contain;
object-fit: cover;
}
// transition: all .3s;
}

View File

@@ -123,7 +123,7 @@ export default defineComponent({
let {t} = useI18n()
let openEventsDetail = (item:any)=>{
let path = router.currentRoute._value.path.split('/')[1]
router.push(`/${path}/eventsDetail?id=${item.id}`)
router.push(`/${path}/eventsDetail?eventId=${item.id}`)
// router.push(`${path}?id=${item.id}`)
}
onMounted (()=>{
@@ -244,7 +244,7 @@ export default defineComponent({
display: flex;
flex-wrap: wrap;
.page_content_item{
max-width: 25%;
width: 25%;
padding: 2rem;
@media (max-width: 768px) {
max-width: 100%;
@@ -265,6 +265,7 @@ export default defineComponent({
color: #5f5f5f;
}
.page_content_item_title{
font-size: 1.6rem;
text-overflow: ellipsis; /* 显示省略号 */
overflow: hidden; /* 溢出隐藏 */
display: -webkit-box;

View File

@@ -10,7 +10,7 @@
<div v-show="!isScroll" class="modal_title_text_assistant gallery_btn white" :class="{active:'NewYear_2025' == worksSelect}" @click="setWorksSelect({value:'NewYear_2025'})">NewYear_2025</div>
</div> -->
<div class="page_content" ref="autoscrollDom">
<Falls ref="fall" @loadend="isShowMark = false" @setPortfolioLike="setPortfolioLike" :isScroll="isScroll" @getImgScale="getImgScale"></Falls>
<Falls ref="fall" @loadend="isShowMark = false" :itemWidth="failWidth" @setPortfolioLike="setPortfolioLike" :isScroll="isScroll" @getImgScale="getImgScale"></Falls>
<div class="page_loading_box" v-show="!isNoData">
<span class="page_loading" v-show="!isShowMark"></span>
<span v-show="isShowMark">
@@ -72,6 +72,7 @@ export default defineComponent({
let filter:any = reactive({
worksSelect: 'all',
isNull:true,
failWidth:300,
worksType: [
{
name: useI18n().t('works.all'),
@@ -163,16 +164,57 @@ export default defineComponent({
}
let getImgScale = (item:any)=>{
let newScaleModel = null
if(window.innerWidth < 768){
newScaleModel = newScaleImageMobile
}else{
if(getScreenOrientation() == 'landscape'){
newScaleModel = newScaleImage
newScaleModel.value.scaleImageMask = true
}else{
newScaleModel = newScaleImageMobile
}
newScaleModel.value.init(item)
}
function getScreenOrientation() {
// 优先使用标准API
if (screen.orientation) {
return screen.orientation.type.includes('portrait') ? 'portrait' : 'landscape';
}
// 回退到宽高比检测
return window.innerWidth > window.innerHeight ? 'landscape' : 'portrait';
}
// 监听方向变化
function setupOrientationListener(callback:any) {
// 标准事件
const handleOrientationChange = () => {
callback(getScreenOrientation());
};
// 优先使用标准API
if (screen.orientation) {
screen.orientation.addEventListener('change', handleOrientationChange);
}
// 回退到resize事件
else {
window.addEventListener('resize', handleOrientationChange);
}
// 返回清除监听的方法
return () => {
if (screen.orientation) {
screen.orientation.removeEventListener('change', handleOrientationChange);
} else {
window.removeEventListener('resize', handleOrientationChange);
}
};
}
const cleanup = setupOrientationListener((orientation:any) => {
if (orientation === 'portrait') {
// 竖屏逻辑
return 'portrait'
} else {
// 横屏逻辑
return 'landscape'
}
});
let getPorfolio = ()=>{
let data = filter.getListDate
if(filter.isShowMark && !filter.isNoData)return
@@ -253,6 +295,7 @@ export default defineComponent({
{ immediate: true } // 立即触发一次以处理初始参数
);
onMounted (()=>{
if(window.innerWidth < 1200)filter.failWidth = 120
nextTick(()=>{
setPorfolioDom()
})