Merge branch 'feature/task1.0.0' of http://internel-git.mashibing.cn/yanxuan-frontend/shop-pc into feature/task1.0.0

merge-requests/5/head
ch 2 years ago
commit ed7e8ea61d

@ -0,0 +1,12 @@
FROM node:12.13.1
WORKDIR /workload
COPY nuxt.config.js /workload/nuxt.config.js
COPY package.json /workload/package.json
COPY .nuxt /workload/.nuxt
RUN npm config set registry https://registry.npm.taobao.org \
&& npm install
EXPOSE 3000
CMD npm run start

@ -0,0 +1,228 @@
<template>
<div class="bs-login">
<el-dialog
:visible.sync="dialogTableVisible"
:show-close="false"
width="20%"
>
<div class="bs-login-wrap">
<img
class="bs-login-wrap__logo"
src="@/static/images/login/icon-logo.png"
/>
<div class="bs-login-wrap__content">
<el-form :model="form" :rules="rules" ref="ruleForm">
<el-form-item prop="phone">
<el-input
v-model="form.phone"
placeholder="请输入手机号"
></el-input>
</el-form-item>
<el-form-item prop="verificationCode">
<el-input
class="input-code"
v-model="form.verificationCode"
placeholder="请输入密码"
>
<el-button slot="suffix" type="text" @click="onSendCode">
{{ codeValue }}
</el-button>
</el-input>
</el-form-item>
<el-button class="login-wrap-content__login-btn" @click="onLogin"
>登录</el-button
>
</el-form>
<div class="login-wrap-content__agreement flex felx-start">
<div
class="wrap-content-agreement-icons"
@click="onAgreementSelect"
>
<img
v-if="isAcceptAgreement"
class="icon-choose"
src="@/static/images/login/icon-accept.png"
/>
<span v-else class="icon-unchoose"></span>
</div>
<span class="wrap-content-agreement__text flex-1">
同意用户协议隐私协议首次 登陆将自动注册
</span>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { Message } from "element-ui";
import { ApiGetCode, ApiPostLogin } from "@/plugins/api/account";
import { IsPhone } from "/plugins/utils";
const COUNT_DOWN_TIME = 60; //
export default {
name: "BsLogin",
props: {
visible: {
type: Boolean,
default: false,
},
},
data() {
const validatorPhone = (_, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"));
}
if (!IsPhone(value)) {
return callback(new Error("请输入正确的手机号"));
}
return callback();
};
return {
form: {
phone: "",
verificationCode: "",
},
isAcceptAgreement: false, //
countDown: 0, //
rules: {
phone: [{ validator: validatorPhone, trigger: "blur" }],
verificationCode: [
{ required: true, message: "请输入验证码", trigger: "change" },
],
},
};
},
computed: {
dialogTableVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:visible", val);
},
},
codeValue() {
return this.countDown ? `${this.countDown}s重新获取` : "获取验证码";
},
},
methods: {
onAgreementSelect() {
this.isAcceptAgreement = !this.isAcceptAgreement;
},
async onSendCode() {
if (this.countDown > 0 || !IsPhone(this.form.phone)) {
return;
}
this.countDown = COUNT_DOWN_TIME;
let time;
const { result, error } = await ApiGetCode({
phone: this.form.phone,
});
if (result) {
time = setInterval(() => {
if (this.countDown === 0) {
clearInterval(time);
return;
}
this.countDown -= 1;
}, 1e3);
return;
}
this.countDown = 0;
clearInterval(time);
Message.error(error.message || "验证码发送失败,请检查手机号是否正确");
},
onLogin() {
this.$refs.ruleForm.validate(async (valid) => {
if (valid) {
if (!this.isAcceptAgreement) {
Message.error("请勾选同意《用户协议》和《隐私协议》");
return;
}
await ApiPostLogin({ ...this.form });
}
});
},
},
};
</script>
<style lang="scss" scoped>
.bs-login {
/deep/.el-dialog {
.el-dialog__header {
display: none;
}
.el-dialog__body {
padding: 38px 30px;
}
.bs-login-wrap {
.bs-login-wrap__logo {
width: 198px;
height: 32px;
margin-bottom: 44px;
}
.bs-login-wrap__content {
.el-form {
.el-form-item {
margin-bottom: 24px;
.input-code {
.el-input__inner {
padding-right: 100px;
}
}
.el-input {
.el-input__suffix {
padding-right: 16px;
.el-button {
color: #ff512b;
}
}
.el-input__inner {
border-style: none;
background: #f8f8f8;
border-radius: 4px 4px 4px 4px;
}
}
}
.login-wrap-content__login-btn {
width: 100%;
height: 42px;
border-style: none;
color: #ffffff;
font-size: 16px;
margin-top: 14px;
background: linear-gradient(270deg, #ffa25a 0%, #ff7f39 100%);
border-radius: 4px 4px 4px 4px;
}
}
.login-wrap-content__agreement {
padding: 0 33px;
color: #999999;
font-size: 12px;
margin-top: 25px;
.wrap-content-agreement-icons {
cursor: pointer;
.icon-unchoose {
display: block;
width: 16px;
height: 16px;
border: 1px solid #cccccc;
border-radius: 50%;
}
.icon-choose {
width: 16px;
height: 16px;
}
}
.wrap-content-agreement__text {
display: block;
text-align: center;
margin-left: 8px;
}
}
}
}
}
}
</style>

@ -0,0 +1,54 @@
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
app: $IMAGES
name: $IMAGES
namespace: yanxuan
spec:
progressDeadlineSeconds: 600
replicas: 1
selector:
matchLabels:
app: $IMAGES
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 25%
template:
metadata:
labels:
app: $IMAGES
spec:
imagePullSecrets:
- name: aliyun-docker-hub
containers:
- image: '$REGISTRY/$DOCKERHUB_NAMESPACE/$IMAGES:$BUILD_NUMBER'
name: app
ports:
- containerPort: $JAR_PORD
protocol: TCP
resources:
limits:
cpu: '0.5'
memory: 500Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
terminationGracePeriodSeconds: 30
---
kind: Service
apiVersion: v1
metadata:
name: $IMAGES
namespace: yanxuan
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: $IMAGES
type: ClusterIP

@ -7,26 +7,29 @@
-->
<template>
<div class="layout">
<BsLogin :visible.sync="loginVisible" />
<Header />
<div class="layout-box"><Nuxt /></div>
<Nuxt />
<Footer />
</div>
</template>
<script>
import BsLogin from "@/components/BsLogin.vue";
import Header from "./module/header/index.vue";
import Footer from "./module/footer/index.vue";
export default {
name: "Layout",
components: { Header, Footer },
components: { Header, Footer, BsLogin },
data() {
return {
loginVisible: true,
};
},
};
</script>
<style lang="scss" scoped>
.layout-box {
width: 1200px;
margin: 0 auto;
}
.layout-footer{
.layout-footer {
height: 189px;
background: #ddd;
}

@ -169,16 +169,16 @@ export default {
//
async getCategroyData() {
const { result } = await ApiGetCategoryOneList();
if (result.data.length > 0) {
if (result && result.length > 0) {
this.categrayData = await Promise.all(
result.data.map(async (item) => {
const { result } = await ApiGetCategoryTwoAndGoods({
result.map(async (item) => {
const { result: resultGoods } = await ApiGetCategoryTwoAndGoods({
categoryId: item.id,
});
if (result.data.length > 0) {
if (resultGoods && resultGoods.length > 0) {
return {
...item,
list: result.data,
list: resultGoods.data,
};
}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Loading…
Cancel
Save