初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,303 @@
import {
rePass,
nextStep,
smsCode,
registerConfig
} from "@/api/auth/login"
import {
captcha
} from "@/api/website"
export default {
data() {
var isMobile = (rule, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"))
} else {
if (/^\d{11}$/.test(value)) {
callback()
} else {
callback(new Error("请输入正确的手机号"))
}
}
}
let self = this
var setPass = function (rule, value, callback) {
let regConfig = self.registerConfig
if (!value) {
return callback(new Error("请输入新的登录密码"))
} else {
if (regConfig.pwd_len > 0) {
if (value.length < regConfig.pwd_len) {
return callback(new Error("密码长度不能小于" + regConfig.pwd_len + "位"))
} else {
callback()
}
} else {
if (regConfig.pwd_complexity != "") {
let passwordErrorMsg = "密码需包含",
reg = ""
if (regConfig.pwd_complexity.indexOf("number") != -1) {
reg += "(?=.*?[0-9])"
passwordErrorMsg += "数字"
} else if (regConfig.pwd_complexity.indexOf("letter") != -1) {
reg += "(?=.*?[a-z])"
passwordErrorMsg += "、小写字母"
} else if (regConfig.pwd_complexity.indexOf("upper_case") != -1) {
reg += "(?=.*?[A-Z])"
passwordErrorMsg += "、大写字母"
} else if (regConfig.pwd_complexity.indexOf("symbol") != -1) {
reg += "(?=.*?[#?!@$%^&*-])"
passwordErrorMsg += "、特殊字符"
} else {
reg += ""
passwordErrorMsg += ""
}
if (reg.test(value)) {
return callback(new Error(passwordErrorMsg))
} else {
callback()
}
}
}
}
}
var checkPass = function (rule, value, callback) {
if (!value) {
return callback(new Error("请输入确认密码"))
} else {
if (value !== self.formData.pass) {
callback(new Error("两次密码输入不一致"))
} else {
callback()
}
}
}
return {
formData: {
mobile: "",
vercode: "",
dynacode: "",
pass: "",
repass: "",
key: ""
},
step: 1,
activeName: "first",
isShowPhone: "",
captcha: {
id: "",
img: ""
},
// 验证码
dynacodeData: {
seconds: 120,
timer: null,
codeText: "获取动态码",
isSend: false
},
// 动态码
registerConfig: {},
rules: {
mobile: [{
required: true,
validator: isMobile,
trigger: "blur"
}],
vercode: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
dynacode: [{
required: true,
message: "请输入短信动态码",
trigger: "blur"
}],
pass: [{
required: true,
validator: setPass,
trigger: "blur"
}],
repass: [{
required: true,
validator: checkPass,
trigger: "blur"
}]
}
}
},
created() {
this.getCaptcha()
this.getRegisterConfig()
},
head() {
return {
title: '找回密码-' + this.$store.state.site.siteInfo.site_name
}
},
watch: {
"dynacodeData.seconds": {
handler(newValue, oldValue) {
if (newValue == 0) {
clearInterval(this.dynacodeData.timer)
this.dynacodeData = {
seconds: 120,
timer: null,
codeText: "获取动态码",
isSend: false
}
}
},
immediate: true,
deep: true
}
},
methods: {
/**
* 下一步
*/
nextStep(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
nextStep({
mobile: this.formData.mobile
}).then(res => {
if (res.code == -1) {
this.step = 2
} else {
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
if (err.code == 0) {
this.$message({
message: "该手机号未注册",
type: "warning"
})
} else {
this.$message.error(err.message)
}
})
} else {
return false
}
})
},
/**
* 获取动态验证码 下一步
*/
nextStepToSetPass(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
this.step = 3
} else {
return false
}
})
},
/**
* 重置密码
*/
resetPass(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
rePass({
password: this.formData.pass,
code: this.formData.dynacode,
key: this.formData.key,
mobile: this.formData.mobile
}).then(res => {
if (res.code >= 0) {
this.step = 4
this.$message({
message: res.message,
type: "success"
})
}
}).catch(err => {
this.$message.error(err.message)
})
} else {
return false
}
})
},
/**
* 获取验证码
*/
getCaptcha() {
captcha({
captcha_id: this.captcha.id
}).then(res => {
if (res.code >= 0) {
this.captcha.id = res.data.id
this.captcha.img = res.data.img
this.captcha.img = this.captcha.img.replace(/\r\n/g, "")
}
}).catch(err => {
this.$message.error(err.message)
})
},
/**
* 发送手机动态码
*/
sendMobileCode(formName) {
if (this.dynacodeData.seconds != 120) return
this.$refs[formName].clearValidate("dynacode")
this.$refs[formName].validateField("vercode", valid => {
if (!valid) {
if (this.isSend) return
this.isSend = true
smsCode({
captcha_id: this.captcha.id,
captcha_code: this.formData.vercode,
mobile: this.formData.mobile
}).then(res => {
if (res.code >= 0) {
this.formData.key = res.data.key
if (this.dynacodeData.seconds == 120 && this.dynacodeData.timer == null) {
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--
this.dynacodeData.codeText = this.dynacodeData.seconds + "s后可重新获取"
}, 1000)
} else {
this.$message({
message: res.message,
type: "warning"
})
this.isSend = false
this.getCaptcha()
}
}
}).catch(err => {
this.isSend = false
this.getCaptcha()
this.$message.error(err.message)
})
} else {
return false
}
})
},
/**
* 获取注册配置
*/
getRegisterConfig() {
registerConfig().then(res => {
if (res.code >= 0) {
this.registerConfig = res.data.value
}
})
}
}
}

View File

@@ -0,0 +1,537 @@
import {
mobileCode,
registerConfig,
wechatMobileCode,
} from "@/api/auth/login"
import {
adList,
captcha
} from "@/api/website"
import {
isWechatLogin
} from "@/api/wechat"
export default {
data: () => {
var isMobile = (rule, value, callback) => {
if (!value) {
return callback(new Error("手机号不能为空"))
} else {
if (/^\d{11}$/.test(value)) {
callback()
} else {
callback(new Error("请输入正确的手机号"))
}
}
}
return {
qrcodeData: {
time: 0,
timer: 0,
},
wx_key: '',
expire_time: '',
ischecked: false,
ischecked1: false,
activeName: "first", // tab切换
// 表单数据
formData: {
account: "",
password: "",
vercode: "",
mobile: "",
dynacode: "",
key: "",
checked: false,
autoLoginRange: 7
},
// 验证码
captcha: {
id: "",
img: ""
},
// 动态码
dynacodeData: {
seconds: 120,
timer: null,
codeText: "获取动态码",
isSend: false
},
// 提交防重复
isSub: false,
registerConfig: {
is_enable: 1,
register: '',
login: ''
},
accountRules: {
account: [{
required: true,
message: "请输入登录账号",
trigger: "blur"
}],
password: [{
required: true,
message: "请输入登录密码",
trigger: "blur"
}],
vercode: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}]
},
mobileRules: {
mobile: [{
required: true,
validator: isMobile,
trigger: "blur"
}],
vercode: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
dynacode: [{
required: true,
message: "请输入短信动态码",
trigger: "blur"
}]
},
wechatRules: {
mobile: [{
required: true,
validator: isMobile,
trigger: "blur"
}],
vercode: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}],
dynacode: [{
required: true,
message: "请输入短信动态码",
trigger: "blur"
}]
},
codeRules: {
mobile: [{
required: true,
validator: isMobile,
trigger: "blur"
}],
vercode: [{
required: true,
message: "请输入验证码",
trigger: "blur"
}]
},
loadingAd: true,
adList: [],
backgroundColor: '',
img: '',
third_party: 0,
wechatConfigStatus: 0,
}
},
created() {
this.ischecked = this.$route.params.third_party;
if (this.ischecked) {
this.weixinLogin()
}
this.getAdList()
this.getCaptcha()
this.getRegisterConfig()
this.getIsWechatLogin()
},
head() {
return {
title: '登录-' + this.$store.state.site.siteInfo.site_name
}
},
watch: {
"dynacodeData.seconds": {
handler(newValue, oldValue) {
if (newValue == 0) {
clearInterval(this.dynacodeData.timer)
this.dynacodeData = {
seconds: 120,
timer: null,
codeText: "获取动态码",
isSend: false
}
}
},
immediate: true,
deep: true
}
},
methods: {
getIsWechatLogin() {
isWechatLogin().then(res => {
if (res.code == 0) {
this.wechatConfigStatus = res.data.wechat_config_status;
}
})
},
getAdList() {
adList({
keyword: "NS_PC_LOGIN"
}).then(res => {
if (res.code == 0 && res.data.adv_list) {
this.adList = res.data.adv_list
for (let i = 0; i < this.adList.length; i++) {
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url)
}
this.backgroundColor = this.adList[0].background
}
this.loadingAd = false
}).catch(err => {
this.loadingAd = false
})
},
handleClick(tab, event) {
},
handleChange(curr, pre) {
this.backgroundColor = this.adList[curr].background
},
/**
* 账号登录
*/
accountLogin(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
var data = {
username: this.formData.account,
password: this.formData.password
}
if (this.captcha.id != "") {
data.captcha_id = this.captcha.id
data.captcha_code = this.formData.vercode
}
if (this.formData.checked) {
data.autoLoginRange = this.formData.autoLoginRange
}
if (this.isSub) return
this.isSub = true
this.$store
.dispatch("member/login", data)
.then(res => {
if (res.code >= 0) {
this.$message({
message: "登录成功!",
type: "success"
})
if (this.$route.query.redirect) {
const a = this.$route.query.redirect
const b = this.$route.query
this.$router.push(this.$route.query.redirect)
} else {
this.$router.push({
name: "member"
})
}
} else {
this.isSub = false
this.getCaptcha()
this.$message({
message: res.message,
type: "warning"
})
}
})
.catch(err => {
this.isSub = false
this.$message.error(err.message)
this.getCaptcha()
})
} else {
return false
}
})
},
/**
* 手机号登录
*/
mobileLogin(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
var data = {
mobile: this.formData.mobile,
key: this.formData.key,
code: this.formData.dynacode
}
if (this.captcha.id != "") {
data.captcha_id = this.captcha.id
data.captcha_code = this.formData.vercode
}
if (this.isSub) return
this.isSub = true
this.$store.dispatch("member/mobile_login", data).then(res => {
if (res.code >= 0) {
this.$message({
message: "登录成功!",
type: "success"
})
if (this.$route.query.redirect) {
this.$router.push(this.$route.query.redirect)
} else {
this.$router.push({
name: "member"
})
}
} else {
this.isSub = false
this.getCaptcha()
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.isSub = false
this.$message.error(err.message)
this.getCaptcha()
})
} else {
return false
}
})
},
/**
* 微信登录
*/
wechatLogin(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
var data = {
mobile: this.formData.mobile,
key: this.formData.key,
code: this.formData.dynacode
}
if (this.captcha.id != "") {
data.captcha_id = this.captcha.id
data.captcha_code = this.formData.vercode
}
if (this.isSub) return
this.isSub = true
this.$store.dispatch("wechat/wechatLogin", data).then(res => {
if (res.code >= 0) {
this.$message({
message: "登录成功!",
type: "success"
})
if (this.$route.query.redirect) {
this.$router.push(this.$route.query.redirect)
} else {
this.$router.push({
name: "member"
})
}
} else {
this.isSub = false
this.getCaptcha()
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.isSub = false
this.$message.error(err.message)
this.getCaptcha()
})
} else {
return false
}
})
},
weixinLogin() {
this.ischecked = true;
this.$store.dispatch("wechat/loginCode").then(res => {
if (res.code >= 0) {
this.img = res.data.qrcode;
this.wx_key = res.data.key;
this.expire_time = res.data.expire_time;
this.qrcodeData.timer = setInterval(() => {
this.checkLogin()
}, 2000);
}
})
},
// 检测是否扫码
checkLogin() {
this.qrcodeData.time += 2;
if (this.qrcodeData.time > this.expire_time) {
clearInterval(this.qrcodeData.timer);
return;
}
var data = {
key: this.wx_key
};
this.$store.dispatch("wechat/checkLogin", data).then(res => {
if (res.code >= 0) {
if (res.data.token != undefined) {
this.$message({
message: "登录成功!",
type: "success"
})
if (this.$route.query.redirect) {
this.$router.push(this.$route.query.redirect)
} else {
this.$router.push({
name: "member"
})
}
} else {
this.ischecked1 = true;
}
clearInterval(this.qrcodeData.timer);
}
})
},
closeWx() {
this.ischecked = false;
},
closeWx1() {
this.ischecked = false;
this.ischecked1 = false;
},
/**
* 获取注册配置
*/
getRegisterConfig() {
registerConfig()
.then(res => {
if (res.code >= 0) {
this.registerConfig = res.data.value
if (this.registerConfig.login.indexOf('username') != -1) {
this.activeName = 'first';
} else {
this.activeName = 'second';
}
}
})
},
/**
* 获取验证码
*/
getCaptcha() {
captcha({
captcha_id: this.captcha.id
}).then(res => {
if (res.code >= 0) {
this.captcha.id = res.data.id
this.captcha.img = res.data.img
this.captcha.img = this.captcha.img.replace(/\r\n/g, "")
}
}).catch(err => {
this.$message.error(err.message)
})
},
/**
* 发送手机动态码
*/
sendMobileCode(formName) {
if (this.dynacodeData.seconds != 120) return
this.$refs[formName].clearValidate("dynacode")
this.$refs[formName].validateField("mobile", valid => {
if (valid) {
return false
}
})
this.$refs[formName].validateField("vercode", valid => {
if (!valid) {
mobileCode({
mobile: this.formData.mobile,
captcha_id: this.captcha.id,
captcha_code: this.formData.vercode
}).then(res => {
if (res.code >= 0) {
this.formData.key = res.data.key
if (this.dynacodeData.seconds == 120 && this.dynacodeData.timer == null) {
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--
this.dynacodeData.codeText = this.dynacodeData.seconds + "s后可重新获取"
}, 1000)
}
}
}).catch(err => {
this.$message.error(err.message)
})
} else {
return false
}
})
},
/**
* 发送微信绑定手机动态码
*/
sendWechatMobileCode(formName) {
if (this.dynacodeData.seconds != 120) return
this.$refs[formName].clearValidate("dynacode")
this.$refs[formName].validateField("mobile", valid => {
if (valid) {
return false
}
})
this.$refs[formName].validateField("vercode", valid => {
if (!valid) {
wechatMobileCode({
mobile: this.formData.mobile,
captcha_id: this.captcha.id,
captcha_code: this.formData.vercode
}).then(res => {
if (res.code >= 0) {
this.formData.key = res.data.key
if (this.dynacodeData.seconds == 120 && this.dynacodeData.timer == null) {
this.dynacodeData.timer = setInterval(() => {
this.dynacodeData.seconds--
this.dynacodeData.codeText = this.dynacodeData.seconds + "s后可重新获取"
}, 1000)
}
}
}).catch(err => {
this.$message.error(err.message)
})
} else {
return false
}
})
},
keypress(e) {
let that = this;
var keycode = e.all ? e.keyCode : e.which;
if (keycode == 13) {
if (that.activeName == "first") {
that.accountLogin('ruleForm'); // 登录方法名
} else {
that.mobileLogin('mobileRuleForm'); // 登录方法名
}
return false;
}
}
}
}

View File

@@ -0,0 +1,324 @@
import {
mapGetters
} from "vuex"
import {
cartList
} from "@/api/goods/cart"
export default {
data: () => {
return {
cartList: [], // 购物车
checkAll: false,
totalPrice: "0.00",
totalCount: 0,
invalidGoods: [], // 失效商品集合
loading: true,
modifyNum: 1, // 防止数量跳动
}
},
created() {
this.getCartList()
},
computed: {
...mapGetters(["defaultGoodsImage"])
},
middleware: 'auth',
methods: {
// 获取购物车数据
getCartList() {
cartList({}).then(res => {
if (res.code >= 0 && res.data.length) {
this.handleCartList(res.data)
}
this.loading = false
}).catch(res => {
this.loading = false
})
},
// 处理购物车数据结构
handleCartList(data) {
this.invalidGoods = []
this.cartList = []
var temp = {}
data.forEach((item, index) => {
if (item.goods_state == 1) {
item.checked = true
if (temp["site_" + item.site_id] != undefined) {
temp["site_" + item.site_id].cartList.push(item)
} else {
temp["site_" + item.site_id] = {
siteId: item.site_id,
siteName: item.site_name,
checked: true,
cartList: [item]
}
}
} else {
this.invalidGoods.push(item)
}
})
this.invalidGoods.forEach(v => {
if (v.sku_spec_format) {
v.sku_spec_format = JSON.parse(v.sku_spec_format)
} else {
v.sku_spec_format = []
}
})
Object.keys(temp).forEach(key => {
this.cartList.push(temp[key])
})
this.calculationTotalPrice()
this.cartList.forEach(v => {
v.cartList.forEach(k => {
if (k.sku_spec_format) {
k.sku_spec_format = JSON.parse(k.sku_spec_format)
} else {
k.sku_spec_format = []
}
})
})
},
// 单选
singleElection(siteIndex, index) {
this.calculationTotalPrice()
},
// 店铺全选
siteAllElection(index) {
this.cartList[index].cartList.forEach(item => {
item.checked = this.cartList[index].checked
})
this.calculationTotalPrice()
},
// 全选
allElection() {
if (this.cartList.length) {
this.cartList.forEach(siteItem => {
siteItem.checked = this.checkAll
siteItem.cartList.forEach(item => {
item.checked = this.checkAll
})
})
}
this.calculationTotalPrice()
},
// 计算购物车总价
calculationTotalPrice() {
if (this.cartList.length) {
let totalPrice = 0,
totalCount = 0,
siteAllElectionCount = 0
this.cartList.forEach(siteItem => {
let siteGoodsCount = 0
siteItem.cartList.forEach(item => {
if (item.checked) {
siteGoodsCount += 1
totalCount += 1
totalPrice += item.discount_price * item.num
}
})
if (siteItem.cartList.length == siteGoodsCount) {
siteItem.checked = true
siteAllElectionCount += 1
} else {
siteItem.checked = false
}
})
this.totalPrice = totalPrice.toFixed(2)
this.totalCount = totalCount
this.checkAll = this.cartList.length == siteAllElectionCount
} else {
this.totalPrice = "0.00"
this.totalCount = 0
}
this.modifyNum = 1;
},
// 删除单个
deleteCart(siteIndex, cartIndex) {
this.$confirm("确定要删除该商品吗?", "提示信息", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$store.dispatch("cart/delete_cart", {
cart_id: this.cartList[siteIndex].cartList[cartIndex].cart_id.toString()
}).then(res => {
if (res.code >= 0) {
this.cartList[siteIndex].cartList.splice(cartIndex, 1)
if (this.cartList[siteIndex].cartList.length == 0) this.cartList.splice(siteIndex, 1)
this.calculationTotalPrice()
this.$message({
type: "success",
message: "删除成功"
})
} else {
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.$message.error(err.message)
})
})
},
// 删除选择的购物车
deleteCartSelected() {
var cartIds = []
var selectedItem = []
this.cartList.forEach((siteItem, siteIndex) => {
siteItem.cartList.forEach((item, cartIndex) => {
if (item.checked) {
cartIds.push(item.cart_id)
selectedItem.push({
siteIndex: siteIndex,
cartIndex: cartIndex,
siteId: siteItem.siteId,
cartId: item.cart_id
})
}
})
})
if (cartIds.length == 0) {
this.$message({
message: "请选择要删除的商品",
type: "warning"
})
return
}
this.$confirm("确定要删除选择的商品吗?", "提示信息", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$store.dispatch("cart/delete_cart", {
cart_id: cartIds.toString()
}).then(res => {
if (res.code >= 0) {
selectedItem.forEach(selectedItem => {
this.cartList.forEach((siteItem, siteIndex) => {
siteItem.cartList.forEach((item, cartIndex) => {
if (selectedItem.cartId == item.cart_id) {
siteItem.cartList.splice(cartIndex, 1)
}
if (siteItem.cartList.length == 0) {
this.cartList.splice(siteIndex, 1)
}
})
})
})
this.calculationTotalPrice()
this.$message({
type: "success",
message: "删除成功"
})
} else {
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.$message.error(err.message)
})
})
},
// 清空失效商品
clearInvalidGoods() {
this.$confirm("确认要清空这些商品吗?", "提示信息", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
var cartIds = []
this.invalidGoods.forEach(goodsItem => {
cartIds.push(goodsItem.cart_id)
})
if (cartIds.length) {
this.$store.dispatch("cart/delete_cart", {
cart_id: cartIds.toString()
}).then(res => {
if (res.code >= 0) {
this.invalidGoods = []
this.$message({
type: "success",
message: "删除成功"
})
} else {
this.$message({
message: res.message,
type: "warning"
})
}
}).catch(err => {
this.$message.error(err.message)
})
}
})
},
// 变更购物车数量
cartNumChange(num, params) {
if (num < 1 || !num) num = 1;
// 防止数量跳动
this.modifyNum = 0;
this.$store.dispatch("cart/edit_cart_num", {
num,
cart_id: this.cartList[params.siteIndex].cartList[params.cartIndex].cart_id
}).then(res => {
if (res.code >= 0) {
this.cartList[params.siteIndex].cartList[params.cartIndex].num = num;
this.calculationTotalPrice();
} else {
this.$message({
message: res.message,
type: "warning"
});
this.modifyNum = 1;
}
}).catch(err => {
this.$message.error(err.message);
this.modifyNum = 1;
})
},
// 结算
settlement() {
if (this.totalCount > 0) {
let cart_ids = []
this.cartList.forEach(siteItem => {
siteItem.cartList.forEach(item => {
if (item.checked) {
cart_ids.push(item.cart_id)
}
})
})
if (cart_ids.length > 100) {
this.$message({
message: '购物车最多支持100个商品一起购买',
type: "warning"
});
return;
}
var data = {
cart_ids: cart_ids.toString()
}
this.$store.dispatch("order/setOrderCreateData", data)
this.$router.push({
path: "/order/payment"
})
}
},
imageError(siteIndex, cartIndex) {
this.cartList[siteIndex].cartList[cartIndex].sku_image = this.defaultGoodsImage
},
imageErrorInvalid(index) {
this.invalidGoods[index].sku_image = this.defaultGoodsImage
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,258 @@
import {
goodsSkuPage,
brandPage
} from "@/api/goods/goods"
import {
mapGetters
} from "vuex"
import {
goodsCategoryInfo,
goodsCategoryList
} from "@/api/goods/goodscategory"
export default {
data: () => {
return {
goodsList: [],
total: 0,
keyword: "",
catewords: '',
currentPage: 1,
pageSize: 25,
is_free_shipping: 0,
filters: {
category_id: 0,
category_level: 0,
brand_id: 0,
min_price: "",
max_price: "",
order: "",
sort: "desc",
coupon: 0
},
loading: true,
first_index: 0,
categoryList: [],
selectCategoryId: 0,
// 全部商品分类链接
categoryAll: {
id: 0,
level: 0,
isAllow: true // 是否允许选中
},
brandList: [], // 品牌列表
brandInitialList: [],
currentInitial: "", // 当前选择品牌分区
choosedBrand: "", // 已选择的品牌,
isShowMoreBrand: false // 是否展开更多品牌
}
},
created() {
this.keyword = this.$route.query.keyword || ""
if (this.$route.query.keyword && process.client) window.document.title = `${this.$route.query.keyword} - ${this.siteInfo.site_name}`
this.filters.category_id = this.$route.query.category_id || ""
this.filters.category_level = this.$route.query.level || ""
this.filters.brand_id = this.$route.query.brand_id || ""
this.filters.coupon = this.$route.query.coupon || 0
this.getBrandList();
this.getGoodsList();
if (this.$route.query.category_id && this.$route.query.category_id > 0) {
this.categorySearch();
} else {
// 查询一级商品分类
this.getGoodsCategoryList();
}
},
computed: {
salesArrowDirection() {
let className = this.filters.order === 'sale_num' && this.filters.sort === 'desc' ? 'arrow-down' : 'arrow-up';
return className;
},
priceArrowDirection() {
let className = this.filters.order === 'discount_price' && this.filters.sort === 'desc' ? 'arrow-down' :
'arrow-up';
return className;
},
...mapGetters(["defaultGoodsImage", "siteInfo"])
},
methods: {
// 商品分类搜索
categorySearch() {
goodsCategoryInfo({
category_id: this.filters.category_id
}).then(res => {
if (res.code == 0 && res.data) {
let data = res.data;
this.catewords = data.category_full_name;
this.first_index = data.category_id_1;
this.categoryList = data.child_list;
this.selectCategoryId = this.filters.category_id;
// 设置全部的链接地址
switch (data.level) {
case 1:
this.categoryAll.level = 1;
this.categoryAll.id = data.category_id_1;
this.categoryAll.isAllow = true;
break;
case 2:
this.categoryAll.level = 1;
this.categoryAll.id = data.category_id_1;
this.categoryAll.isAllow = true;
if (this.categoryList[0].level == 3) {
this.categoryAll.level = 2;
this.categoryAll.id = data.category_id_2;
}
break;
case 3:
this.categoryAll.level = 2;
this.categoryAll.id = data.category_id_2;
this.categoryAll.isAllow = false;
break;
}
for (let i = 0; i < this.categoryList.length; i++) {
let item = this.categoryList[i];
if (item.category_id == this.categoryAll.id) {
this.categoryAll.id = 0;
this.categoryAll.isAllow = false; // 匹配到了分类,禁止选中 全部
break;
}
}
if (process.client) window.document.title = `${data.category_name} - ${this.siteInfo.site_name}`
}
})
},
// 一级商品分类列表
getGoodsCategoryList() {
goodsCategoryList({}).then(res => {
if (res.code == 0 && res.data) {
// 设置全部的链接地址
this.categoryAll.level = 1;
this.categoryAll.id = 0;
this.categoryAll.isAllow = true;
this.categoryList = res.data;
}
})
},
getGoodsList() {
const params = {
page: this.currentPage,
page_size: this.pageSize,
keyword: this.keyword,
...this.filters
}
goodsSkuPage(params || {}).then(res => {
const {
count,
page_count,
list
} = res.data
this.total = count
this.goodsList = list
this.loading = false
}).catch(err => {
this.loading = false
})
},
handlePageSizeChange(size) {
this.pageSize = size
this.getGoodsList()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.getGoodsList()
},
handlePriceRange() {
if (Number(this.filters.min_price) > Number(this.filters.max_price)) {
// es6解构赋值
[this.filters.min_price, this.filters.max_price] = [this.filters.max_price, this.filters.min_price]
}
this.getGoodsList()
},
changeSort(type) {
if (this.filters.order === type) {
this.$set(this.filters, "sort", this.filters.sort === "desc" ? "asc" : "desc")
} else {
this.$set(this.filters, "order", type)
this.$set(this.filters, "sort", "desc")
}
this.getGoodsList()
},
getBrandList() {
brandPage({
page: 1,
page_size: 0
}).then(res => {
if (res.code >= 0 && res.data) {
this.brandList = res.data.list;
if (this.filters.brand_id) {
for (var i = 0; i < this.brandList.length; i++) {
if (this.brandList[i].brand_id == this.filters.brand_id) {
this.choosedBrand = this.brandList[i];
}
}
}
}
});
},
handleChangeInitial(initial) {
this.currentInitial = initial
},
onChooseBrand(brand) {
this.choosedBrand = brand
this.filters.brand_id = brand.brand_id
this.getGoodsList()
},
closeBrand() {
this.choosedBrand = ""
this.filters.brand_id = ""
this.getGoodsList()
},
showPrice(data) {
let price = data.discount_price;
if (data.member_price && parseFloat(data.member_price) < parseFloat(price)) price = data.member_price;
return price;
}
},
watch: {
is_free_shipping: function (val) {
this.filters.is_free_shipping = val ? 1 : ""
this.getGoodsList()
},
$route: function (curr) {
this.currentPage = 1
if (curr.query.keyword && process.client) window.document.title = `${curr.query.keyword} - ${this.siteInfo.site_name}`
if (curr.query.level && curr.query.category_id > 0) {
this.filters.category_level = curr.query.level
this.filters.category_id = curr.query.category_id
this.getGoodsList()
this.categorySearch()
} else {
this.getGoodsCategoryList();
this.first_index = 0
this.selectCategoryId = 0
if (process.client) window.document.title = `${this.siteInfo.site_name}`
}
if (curr.query.category_id == undefined || curr.query.category_id == 0) {
this.catewords = ""
this.keyword = curr.query.keyword
this.filters.category_id = curr.query.category_id || ""
this.filters.category_level = curr.query.level || ""
this.filters.brand_id = curr.query.brand_id || ""
this.getGoodsList()
}
}
}
}

View File

@@ -0,0 +1,284 @@
import {
adList
} from "@/api/website"
import {
noticesList
} from "@/api/cms/notice"
import {
floors,
floatLayer,
apiDefaultSearchWords
} from "@/api/pc"
import {
mapGetters
} from "vuex"
import {
goodsPage,
timeList
} from "@/api/seckill"
import CountDown from "vue2-countdown"
export default {
name: "index",
components: {
CountDown
},
data: () => {
return {
loadingAd: true,
loadingFloor: true,
adList: [],
adLeftList: [],
adRightList: [],
adCenterList: [],
floorList: [],
floatLayer: {
is_show: false,
link: {
url: ""
}
},
isSub: false,
siteId: 0,
listData: [],
seckillTimeMachine: {
currentTime: 0,
startTime: 0,
endTime: 0
},
seckillText: "距离结束",
backgroundColor: "", // 顶部banner背景颜色
keyword: "",
defaultSearchWords: "",
isShow: false
}
},
watch: {
addonIsExit: {
handler: function () {
if (this.addonIsExit && this.addonIsExit.seckill == 1) {
this.getTimeList()
}
},
deep: true
}
},
created() {
this.getAdList()
this.getBigAdList()
this.getSmallAdList()
this.getCategoryBelowList()
this.getFloors()
this.getFloatLayer()
if (this.addonIsExit && this.addonIsExit.seckill == 1) {
this.getTimeList()
}
},
mounted() {
window.addEventListener("scroll", this.handleScroll)
},
computed: {
...mapGetters(["defaultHeadImage", "addonIsExit", "defaultGoodsImage", "member", "siteInfo", "cartCount"]),
optionLeft() {
return {
direction: 2,
limitMoveNum: 2
}
},
indexFloatLayerNum() {
let num = localStorage.getItem('indexFloatLayerNum') || 0;
return parseInt(num);
}
},
methods: {
countDownS_cb() {
},
countDownE_cb() {
this.seckillText = "活动已结束"
},
getAdList() {
adList({
keyword: "NS_PC_INDEX"
}).then(res => {
this.adList = res.data.adv_list
this.$store.dispatch("app/is_show", {
is_show: this.adList.length
}).then(res => {
})
for (let i = 0; i < this.adList.length; i++) {
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url)
}
this.backgroundColor = this.adList[0].background
this.loadingAd = false
}).catch(err => {
this.loadingAd = false
})
},
handleChange(curr, pre) {
this.backgroundColor = this.adList[curr].background
},
/**
* 广告位大图
*/
getBigAdList() {
adList({
keyword: "NS_PC_INDEX_MID_LEFT"
}).then(res => {
this.adLeftList = res.data.adv_list
for (let i = 0; i < this.adLeftList.length; i++) {
if (this.adLeftList[i].adv_url) this.adLeftList[i].adv_url = JSON.parse(this.adLeftList[i].adv_url)
}
this.loadingAd = false
}).catch(err => {
this.loadingAd = false
})
},
/**
* 广告位小图
*/
getSmallAdList() {
adList({
keyword: "NS_PC_INDEX_MID_RIGHT"
}).then(res => {
this.adRightList = res.data.adv_list
for (let i = 0; i < this.adRightList.length; i++) {
if (this.adRightList[i].adv_url) this.adRightList[i].adv_url = JSON.parse(this.adRightList[i].adv_url)
}
this.loadingAd = false
}).catch(err => {
this.loadingAd = false
})
},
getCategoryBelowList() {
adList({
keyword: "NS_PC_INDEX_CATEGORY_BELOW"
}).then(res => {
this.adCenterList = res.data.adv_list
for (let i = 0; i < this.adCenterList.length; i++) {
if (this.adCenterList[i].adv_url) this.adCenterList[i].adv_url = JSON.parse(this.adCenterList[i].adv_url)
}
this.loadingAd = false
}).catch(err => {
this.loadingAd = false
})
},
/**
* 限时秒杀
*/
getTimeList() {
timeList().then(res => {
if (res.code == 0 && res.data) {
let time = new Date(res.timestamp * 1000)
let currentTimes = time.getHours() * 60 * 60 + time.getMinutes() * 60 + time.getSeconds()
res.data.list.forEach((v, k) => {
if (v.seckill_start_time <= currentTimes && currentTimes < v.seckill_end_time) {
let seckillId = v.id
this.getGoodsList(seckillId)
let endTime = parseInt(time.getTime() / 1000) + (v.seckill_end_time - currentTimes)
this.seckillTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: endTime
}
}
})
}
})
},
/**
* 秒杀商品
*/
getGoodsList(id) {
goodsPage({
page_size: 0,
seckill_time_id: id,
site_id: this.siteId
}).then(res => {
if (res.code == 0 && res.data.list) {
this.listData = res.data.list
}
})
},
/**
* 图片加载失败
*/
imageError(index) {
this.listData[index].sku_image = this.defaultGoodsImage
},
/**
* 图片加载失败
*/
adLeftImageError(index) {
this.adLeftList[index].adv_image = this.defaultGoodsImage
},
/**
* 图片加载失败
*/
adRightImageError(index) {
this.adRightList[index].adv_image = this.defaultGoodsImage
},
adCenterImageError(index) {
this.adCenterList[index].adv_image = this.defaultGoodsImage
},
getFloors() {
floors().then(res => {
this.floorList = res.data;
})
},
getFloatLayer() {
floatLayer().then(res => {
if (res.code == 0 && res.data) {
this.floatLayer = res.data
if (this.floatLayer.is_show == 1) {
this.floatLayer.link = JSON.parse(this.floatLayer.url)
// 弹框形式,首次弹出 1每次弹出 0
if (!this.floatLayer.img_url) return
if (parseInt(this.floatLayer.number) >= 1) {
//缓存计数 == 弹出总数 禁止弹出
if (this.indexFloatLayerNum >= parseInt(this.floatLayer.number)) {
this.floatLayer.is_show_type = false
} else {
this.floatLayer.is_show_type = true
}
} else if (parseInt(this.floatLayer.number) == 0) {
this.floatLayer.is_show_type = true
}
} else {
this.floatLayer.is_show_type = false
}
}
})
},
closeFloat() {
if (parseInt(this.floatLayer.number) == 0) {
this.$store.commit("app/SET_FLOAT_LAYER", 0)
} else if (parseInt(this.floatLayer.number) >= 1 && this.indexFloatLayerNum != parseInt(this.floatLayer.number)) {
var count_num = this.indexFloatLayerNum + 1;
this.$store.commit("app/SET_FLOAT_LAYER", count_num)
} else if (this.indexFloatLayerNum == parseInt(this.floatLayer.number)) {
this.$store.commit("app/SET_FLOAT_LAYER", this.floatLayer.number)
}
this.floatLayer.is_show_type = false
this.$forceUpdate()
// this.$store.commit("app/SET_FLOAT_LAYER", -1)
},
// 监听滚动条
handleScroll() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop >= 680) {
this.isShow = true
} else {
this.isShow = false
}
}
},
destroyed() {
// 离开该页面需要移除这个监听的事件,不然会报错
console.log('// 离开该页面需要移除这个监听的事件,不然会报错');
window.removeEventListener("scroll", this.handleScroll)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,822 @@
import {
aftersale,
modifyClicks,
addGoodsbrowse,
goodsQrcode
} from "@/api/goods/goods"
import {
goodsCategoryInfo
} from "@/api/goods/goodscategory"
import {
goodsSkuDetail,
goodsSkuInfo,
evaluateConfig
} from "@/api/groupbuy"
import {
isCollect,
addCollect,
deleteCollect
} from "@/api/goods/goods_collect"
import {
goodsEvaluateList,
goodsEvaluateCount
} from "@/api/goods/evaluate"
import {
mapGetters
} from "vuex"
import CountDown from "vue2-countdown"
import {
getArea
} from "@/api/address"
import {
shopServiceOpen
} from "@/api/website.js"
export default {
data: () => {
return {
id: 0,
skuId: 0,
loading: true,
picZoomUrl: "",
thumbPosition: 0,
// 是否可以移动
moveThumbLeft: false,
moveThumbRight: false,
// 商品详情
goodsSkuDetail: {
video_url: ""
},
groupbuyText: "距离结束仅剩",
groupbuyTimeMachine: {
currentTime: 0,
startTime: 0,
endTime: 0
},
qrcode: "",
specDisabled: false,
specBtnRepeat: false, //防止重复
btnSwitch: false,
// 店铺详情
shopInfo: {},
whetherCollection: 0,
score: 0,
//评价
currentPage: 1,
pageSize: 25,
total: 0,
evaluaType: 0,//评价类型
evaluteCount: {},//评价数量
goodsEvaluateList: [],
evaluate_show: false, //是否显示评论
service: null,
number: 1,
limitNumber: 0,
tabName: "detail",
playerOptions: {
playbackRates: [0.5, 1.0, 1.5, 2.0, 3.0], // 可选的播放速度
autoplay: false, // 如果为true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 是否视频一结束就重新开始。
preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: "zh-CN",
aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3"
fluid: true, // 当true时Video.js player将拥有流体大小。换句话说它将按比例缩放以适应其容器。
sources: [{
type: "video/mp4", // 类型
src: "" // url地址
}],
poster: "", // 封面地址
notSupportedMessage: "此视频暂无法播放,请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true, // 当前时间和持续时间的分隔符
durationDisplay: true, // 显示持续时间
remainingTimeDisplay: true, // 是否显示剩余时间功能
fullscreenToggle: true // 是否显示全屏按钮
}
},
switchMedia: "img",
// 是否关注店铺
hasFollow: false,
// 客服配置
kefuConfig: {
system: '',
open_pc: '',
open_url: ''
},
// 省市区县
provinceArr: {},
cityArr: {},
districtArr: {},
// 省市区县 id
currTabAddres: "province",
hideRegion: false,
selectedAddress: {},
service_list: [], //商品服务
serverType: 'disable',
serverThird: '',
categoryNameArr: []
}
},
components: {
CountDown
},
created() {
this.id = this.$route.params.id;
if (this.addonIsExit && this.addonIsExit.groupbuy != 1) {
this.$message({
message: '团购插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
} else {
this.getGoodsSkuDetail()
this.shopServiceOpen()
this.getGoodsEvaluate()
this.goodsEvaluCount()
}
},
computed: {
...mapGetters(["token", "siteInfo", "defaultHeadImage", "defaultShopImage", "addonIsExit", 'locationRegion'])
},
watch: {
$route(curr) {
this.id = curr.query.id
if (this.addonIsExit && this.addonIsExit.groupbuy != 1) {
this.$message({
message: '团购插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
} else {
this.getGoodsSkuDetail()
this.shopServiceOpen()
}
},
addonIsExit() {
if (this.addonIsExit.groupbuy != 1) {
this.$message({
message: '团购插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
}
}
},
methods: {
shopServiceOpen() {
// todo 暂停使用
return;
shopServiceOpen().then((res) => {
if (res.code == 0) {
this.kefuConfig = res.data;
}
})
},
tabChange(tab, event) {
},
bundlingChange(tab, event) {
},
getGoodsSkuDetail() {
goodsSkuDetail({
groupbuy_id: this.id
}).then(res => {
let data = res.data
if (data.goods_sku_detail != null) {
this.goodsSkuDetail = data.goods_sku_detail
let categoryIdArr = data.goods_sku_detail.category_id.split(",")
categoryIdArr = categoryIdArr.filter((item) => {
return item && item.trim()
});
this.categorySearch(categoryIdArr[categoryIdArr.length - 1]);
// this.shopInfo = data.shop_info
this.service_list = data.goods_sku_detail.goods_service
this.skuId = this.goodsSkuDetail.sku_id
this.number = this.goodsSkuDetail.buy_num
this.limitNumber = this.goodsSkuDetail.buy_num
//团购倒计时
if (this.goodsSkuDetail.end_time - res.timestamp > 0) {
this.groupbuyTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: this.goodsSkuDetail.end_time
}
} else {
this.$message({
message: '活动已结束',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
}
if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
else this.goodsSkuDetail.sku_images = [];
// 多规格时合并主图
if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) {
this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(",");
this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.concat(this.goodsSkuDetail.goods_image);
}
//媒体
if (this.goodsSkuDetail.video_url) {
this.switchMedia = "video"
this.playerOptions.poster = this.$img(this.goodsSkuDetail.sku_images[0])
this.playerOptions.sources[0].src = this.$img(this.goodsSkuDetail.video_url)
}
this.picZoomUrl = this.goodsSkuDetail.sku_images[0]
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"
// 当前商品SKU规格
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_format)
// 商品属性
if (this.goodsSkuDetail.goods_attr_format) {
let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format);
this.goodsSkuDetail.goods_attr_format = this.$util.unique(goods_attr_format, "attr_id");
for (var i = 0; i < this.goodsSkuDetail.goods_attr_format.length; i++) {
for (var j = 0; j < goods_attr_format.length; j++) {
if (this.goodsSkuDetail.goods_attr_format[i].attr_id == goods_attr_format[j].attr_id && this.goodsSkuDetail.goods_attr_format[i].attr_value_id != goods_attr_format[j].attr_value_id) {
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name;
}
}
}
}
// 商品SKU格式
if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format)
window.document.title = `${this.goodsSkuDetail.sku_name} - ${this.siteInfo.site_name}`
this.loading = false
} else {
this.$router.push("/")
}
}).then(res => {
if (this.token != "") {
this.getWhetherCollection()
// this.isFollow()
}
// this.getAftersale()
this.modifyGoodsInfo()
this.getGoodsQrcode()
this.getEvaluateConfig()
this.getAddress('province', null, true);
if (!this.locationRegion) {
this.$store.commit("app/SET_LOCATION_REGION", {
"level_1": {
"id": 110000,
"pid": 0,
"name": "北京市",
"shortname": "北京",
"longitude": "116.40529",
"latitude": "39.904987",
"level": 1,
"sort": 1,
"status": 1,
"default_data": 1
},
"level_2": {
"id": 110100,
"pid": 110000,
"name": "北京市",
"shortname": "北京",
"longitude": "116.40529",
"latitude": "39.904987",
"level": 2,
"sort": 1,
"status": 1,
"default_data": 1
},
"level_3": {
"id": 110101,
"pid": 110100,
"name": "东城区",
"shortname": "东城",
"longitude": "116.418755",
"latitude": "39.917545",
"level": 3,
"sort": 3,
"status": 1,
"default_data": 1
}
});
}
this.selectedAddress = this.locationRegion;
this.provinceId = this.selectedAddress.level_1.id
this.getAddress('city', null, true, () => {
this.cityId = this.selectedAddress.level_2.id
if (this.cityId) this.getAddress('district', null, true)
});
}).catch(res => {
this.loading = false
this.$router.push("/")
})
},
categorySearch(category_id) {
goodsCategoryInfo({
category_id: category_id
}).then(res => {
if (res.code == 0 && res.data) {
this.categoryNameArr = [];
try {
let categoryArr = res.data.category_full_name.split("$_SPLIT_$");
categoryArr.forEach((item, index) => {
let obj = {};
obj.name = item;
obj.category_id = res.data["category_id_" + (index + 1)];
this.categoryNameArr.push(obj);
})
} catch (e) {
this.categoryNameArr = [];
}
}
})
},
getEvaluateConfig() {
evaluateConfig().then(res => {
if (res.code == 0) {
var data = res.data;
this.evaluateConfig = data;
if (this.evaluateConfig.evaluate_show == 1) {
//商品评论
this.evaluate_show = true
this.getGoodsEvaluate();
}
}
})
},
service_link() {
if (this.token) {
this.$refs.servicerMessage.show();
} else {
this.$message({
message: "您还未登录",
type: "warning"
})
}
},
changeThumbImg(tag) {
if (this.goodsSkuDetail.sku_images.length < 4) return
let page = this.goodsSkuDetail.sku_images.length % 4 // 可见数量4个
let position = 94
if (page == 0) page = this.goodsSkuDetail.sku_images.length - 4 // 可见数量4个
else if (page != 0 && page != 1 && page < 2) return
if (tag == "prev") {
if (this.thumbPosition != 0 && Math.round(this.thumbPosition, 2) != position) {
this.thumbPosition += position
// this.moveThumbLeft = true;
} else {
// this.moveThumbLeft = false;
}
} else if (tag == "next") {
if (Math.round(this.thumbPosition, 2) != -Math.round(position * page, 2)) {
this.thumbPosition -= position
// this.moveThumbRight = true;
} else {
// this.moveThumbRight = false;
}
}
},
//获取用户是否关注
getWhetherCollection() {
isCollect({
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
this.whetherCollection = res.data;
})
},
editCollection() {
//未关注添加关注
if (this.whetherCollection == 0) {
addCollect({
sku_id: this.skuId,
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
var data = res.data
if (data > 0) {
this.whetherCollection = 1
this.goodsSkuDetail.collect_num++
}
})
} else {
//已关注取消关注
deleteCollect({
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
var data = res.data
if (data > 0) {
this.whetherCollection = 0
this.goodsSkuDetail.collect_num--
}
})
}
},
// 售后保障
getAftersale() {
aftersale({}).then(res => {
if (res.code == 0 && res.data) {
let data = res.data.content
if (res.data.content) this.service = res.data.content
}
})
},
//更新商品信息
modifyGoodsInfo() {
//更新商品点击量
modifyClicks({
sku_id: this.skuId,
})
//添加足迹
addGoodsbrowse({
sku_id: this.skuId,
goods_id: this.goodsSkuDetail.goods_id
})
},
// 商品二维码
getGoodsQrcode() {
goodsQrcode({
sku_id: this.skuId
}).then(res => {
let data = res.data
if (data.path.h5.img) this.qrcode = this.$img(data.path.h5.img)
})
},
//商品评价数量
goodsEvaluCount() {
goodsEvaluateCount({
goods_id: this.id
}).then(res => {
if (res.code == 0 && res.data) {
this.evaluteCount = res.data
}
})
},
// 商品评价列表
getGoodsEvaluate() {
goodsEvaluateList({
page: this.currentPage,
page_size: this.pageSize,
goods_id: this.id,
explain_type: this.evaluaType == 0 ? '' : this.evaluaType
}).then(res => {
let list = []
let msg = res.message
if (res.code == 0 && res.data) {
list = res.data.list
this.total = res.data.count
}
for (var i = 0; i < list.length; i++) {
// 1好评2中评3差评
if (list[i].explain_type == 1) {
list[i].star = 5
} else if (list[i].explain_type == 2) {
list[i].star = 3
} else if (list[i].explain_type == 3) {
list[i].star = 1
}
if (list[i].images) {
list[i].images = list[i].images.split(",")
list[i].imagesFormat = []
for (var k = 0; k < list[i].images.length; k++) {
list[i].imagesFormat.push(this.$img(list[i].images[k]))
}
}
if (list[i].again_images) {
list[i].again_images = list[i].again_images.split(",")
list[i].againImagesFormat = []
for (var j = 0; j < list[i].again_images.length; j++) {
list[i].againImagesFormat.push(this.$img(list[i].again_images[j]))
}
}
if (list[i].is_anonymous == 1) list[i].member_name = list[i].member_name.replace(list[i].member_name.substring(1, list[i].member_name.length - 1), "***")
}
this.goodsEvaluateList = list
})
},
// 图片加载失败
imageErrorEvaluate(index) {
this.goodsEvaluateList[index].member_headimg = this.defaultHeadImage
},
handlePageSizeChange(size) {
this.pageSize = size
this.getGoodsEvaluate()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.getGoodsEvaluate()
},
changeSpec(skuId, spec_id) {
if (this.specDisabled) return
this.specBtnRepeat = false
this.skuId = skuId
// 清空选择
for (var i = 0; i < this.goodsSkuDetail.goods_spec_format.length; i++) {
var sku = this.goodsSkuDetail.goods_spec_format[i]
for (var j = 0; j < sku.value.length; j++) {
// 排除当前点击的规格值
if (spec_id == this.goodsSkuDetail.goods_spec_format[i].value[j].spec_id) {
this.goodsSkuDetail.goods_spec_format[i].value[j].selected = false
}
}
}
goodsSkuInfo({
sku_id: this.skuId,
id: this.goodsSkuDetail.groupbuy_id
}).then(res => {
let data = res.data
if (data != null) {
data.sku_images = data.sku_images.split(",")
this.picZoomUrl = data.sku_images[0]
this.playerOptions.poster = this.$img(data.sku_images[0])
// 当前商品SKU规格
if (data.sku_spec_format) data.sku_spec_format = JSON.parse(data.sku_spec_format)
// 商品SKU格式
if (data.goods_spec_format) data.goods_spec_format = JSON.parse(data.goods_spec_format)
this.keyInput(true)
//拼团倒计时
if (data.end_time - res.timestamp > 0) {
this.groupbuyTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: data.end_time
}
} else {
this.$message({
message: '活动已结束',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
}
this.specBtnRepeat = false
Object.assign(this.goodsSkuDetail, data)
} else {
this.$router.push("/")
}
})
},
changeNum(tag) {
if (this.goodsSkuDetail.stock == 0) return
var stock = this.goodsSkuDetail.stock
//最低购买数量
var min = this.goodsSkuDetail.buy_num
if (this.goodsSkuDetail.buy_num > this.goodsSkuDetail.stock) {
//限购数量大于库存总数取库存
stock = this.goodsSkuDetail.stock
} else {
stock = this.goodsSkuDetail.stock
}
if (tag == "+") {
// 加
if (this.number < stock) {
this.number++
}
} else if (tag == "-") {
// 减
if (this.number > min) {
this.number -= 1
}
}
},
blur() {
let newNumber = parseInt(this.number)
this.number = 0
setTimeout(() => {
this.number = newNumber
}, 0)
},
//输入数量
keyInput(flag, callback) {
setTimeout(() => {
var stock = this.goodsSkuDetail.stock
// 库存为0
if (stock == 0) {
this.number = 0
return
}
// 防止空
if (flag && this.number.length == 0) this.number = 1
// 防止输入0和负数、非法输入
if (flag && (this.number <= 0 || isNaN(this.number))) this.number = 1
if (this.number < this.goodsSkuDetail.buy_num) {
//最低购买数量
this.number = this.goodsSkuDetail.buy_num
}
if (flag) this.number = parseInt(this.number)
if (callback) callback()
}, 0)
},
// 播放回调
onPlayerPlay(player) {
},
// 暂停回调
onPlayerPause(player) {
},
// 视频播完回调
onPlayerEnded(player) {
},
// DOM元素上的readyState更改导致播放停止
onPlayerWaiting(player) {
},
// 已开始播放回调
onPlayerPlaying(player) {
},
// 当播放器在当前播放位置下载数据时触发
onPlayerLoadeddata(player) {
},
// 当前播放位置发生变化时触发。
onPlayerTimeupdate(player) {
},
//媒体的readyState为HAVE_FUTURE_DATA或更高
onPlayerCanplay(player) {
},
//媒体的readyState为HAVE_ENOUGH_DATA或更高。这意味着可以在不缓冲的情况下播放整个媒体文件。
onPlayerCanplaythrough(player) {
},
//播放状态改变回调
playerStateChanged(playerCurrentState) {
},
//将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于如果ready事件已经发生它将立即触发该函数。。
playerReadied(player) {
},
// 立即购买
buyNow() {
//纠正数量
this.keyInput(true, () => {
if (this.goodsSkuDetail.stock == 0) {
this.$message({
message: "商品已售罄",
type: "warning"
})
return
}
if (this.number.length == 0 || this.number == 0) {
this.$message({
message: "购买数量不能为0",
type: "warning"
})
return
}
// 团购
var data = {
groupbuy_id: this.goodsSkuDetail.groupbuy_id,
sku_id: this.skuId,
num: this.number
}
this.$store.dispatch("order/setGroupbuyOrderCreateData", data)
this.$router.push({
path: "/promotion/groupbuy/payment"
})
})
},
countDownS_cb() {
},
countDownE_cb() {
this.groupbuyText = "活动已结束"
this.$message({
message: '团购活动已结束',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
},
// 图片加载失败
imageErrorSpec(index) {
this.goodsSkuDetail.sku_images[index] = this.defaultGoodsImage
this.picZoomUrl = this.defaultGoodsImage
},
/**
* 获取地址
* @param {Object} type
* @param {Object} item
* @param {Object} first 是否第一次
*/
getAddress(type, item, first, callback) {
let pid = 0
switch (type) {
case 'province':
//加载省
pid = 0
break
case 'city':
//加载市
if (item) {
this.provinceId = item.id
}
pid = this.provinceId
this.cityArr = {}
this.districtArr = {}
break
case 'district':
//加载区县
if (item) this.cityId = item.id
pid = this.cityId
this.districtArr = {}
break
}
if (item) {
if (item.level <= 2) {
let len = item.level;
for (let i = len; i <= 3; i++) {
delete this.selectedAddress['level_' + i];
}
}
this.selectedAddress['level_' + item.level] = item;
}
if (!first) this.$store.commit("app/SET_LOCATION_REGION", this.selectedAddress)
this.$forceUpdate();
if (type == 'community') {
this.hideRegion = true;
setTimeout(() => {
this.hideRegion = false;
}, 10);
return;
}
getArea({
pid: pid
}).then(res => {
const {
code,
data
} = res;
if (data) {
switch (type) {
case 'province':
//加载省
this.provinceArr = data
break
case 'city':
//加载市
this.cityArr = data
break
case 'district':
//加载区县
this.districtArr = data
break
}
this.currTabAddres = type
if (callback) callback();
}
})
}
}
}

View File

@@ -0,0 +1,823 @@
import {
aftersale,
modifyClicks,
addGoodsbrowse,
goodsQrcode
} from "@/api/goods/goods"
import {
goodsCategoryInfo
} from "@/api/goods/goodscategory"
import {
seckillGoodsInfo,
goodsSkuDetail,
evaluateConfig
} from "@/api/seckill"
import {
isCollect,
addCollect,
deleteCollect
} from "@/api/goods/goods_collect"
import {
goodsEvaluateList,
goodsEvaluateCount
} from "@/api/goods/evaluate"
import {
mapGetters
} from "vuex"
import CountDown from "vue2-countdown"
import {
getArea
} from "@/api/address"
import {
shopServiceOpen
} from "@/api/website.js"
export default {
data: () => {
return {
id: 0,
skuId: 0,
loading: true,
picZoomUrl: "",
thumbPosition: 0,
// 是否可以移动
moveThumbLeft: false,
moveThumbRight: false,
// 商品详情
goodsSkuDetail: {
video_url: ""
},
seckillText: "距离结束仅剩",
seckillTimeMachine: {
currentTime: 0,
startTime: 0,
endTime: 0
},
qrcode: "",
specBtnRepeat: false, //防止重复
// 店铺详情
shopInfo: {},
whetherCollection: 0,
score: 0,
//评价
currentPage: 1,
pageSize: 10,
total: 0,
evaluaType: 0,//评价类型
evaluteCount: {},//评价数量
goodsEvaluateList: [],
evaluate_show: false, //是否显示评论
service: null,
number: 1,
tabName: "detail",
playerOptions: {
playbackRates: [0.5, 1.0, 1.5, 2.0, 3.0], // 可选的播放速度
autoplay: false, // 如果为true,浏览器准备好时开始回放。
muted: false, // 默认情况下将会消除任何音频。
loop: false, // 是否视频一结束就重新开始。
preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
language: "zh-CN",
aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3"
fluid: true, // 当true时Video.js player将拥有流体大小。换句话说它将按比例缩放以适应其容器。
sources: [{
type: "video/mp4", // 类型
src: "" // url地址
}],
poster: "", // 封面地址
notSupportedMessage: "此视频暂无法播放,请稍后再试", // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
controlBar: {
timeDivider: true, // 当前时间和持续时间的分隔符
durationDisplay: true, // 显示持续时间
remainingTimeDisplay: true, // 是否显示剩余时间功能
fullscreenToggle: true // 是否显示全屏按钮
}
},
switchMedia: "img",
// 是否关注店铺
hasFollow: false,
// 客服配置
kefuConfig: {
system: '',
open_pc: '',
open_url: ''
},
// 省市区县
provinceArr: {},
cityArr: {},
districtArr: {},
// 省市区县 id
currTabAddres: "province",
hideRegion: false,
selectedAddress: {},
service_list: [],
serverType: 'disable',
serverThird: '',
categoryNameArr: []
}
},
components: {
CountDown
},
created() {
this.id = this.$route.params.id;
if (this.addonIsExit && this.addonIsExit.seckill != 1) {
this.$message({
message: '秒杀插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
} else {
this.getGoodsSkuDetail()
this.getGoodsEvaluate()
this.goodsEvaluCount()
}
},
computed: {
...mapGetters(["token", "siteInfo", "defaultHeadImage", "defaultShopImage", "addonIsExit", 'locationRegion'])
},
watch: {
$route(curr) {
this.id = curr.query.id
if (this.addonIsExit && this.addonIsExit.seckill == 1) {
this.getGoodsSkuDetail()
this.shopServiceOpen()
} else {
this.$message({
message: '秒杀插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
}
},
addonIsExit() {
if (this.addonIsExit.seckill != 1) {
this.$message({
message: '秒杀插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
} else {
this.shopServiceOpen()
}
}
},
methods: {
shopServiceOpen() {
// todo 暂停使用
return;
shopServiceOpen().then((res) => {
if (res.code == 0) {
this.kefuConfig = res.data;
}
})
},
tabChange(tab, event) {
},
bundlingChange(tab, event) {
},
getGoodsSkuDetail() {
goodsSkuDetail({
seckill_id: this.id
}).then(res => {
let data = res.data
if (data.goods_sku_detail != null) {
this.goodsSkuDetail = data.goods_sku_detail
let categoryIdArr = data.goods_sku_detail.category_id.split(",")
categoryIdArr = categoryIdArr.filter((item) => {
return item && item.trim()
});
this.categorySearch(categoryIdArr[categoryIdArr.length - 1]);
// this.shopInfo = data.shop_info
// let num = (Number(this.shopInfo.shop_desccredit) + Number(this.shopInfo.shop_servicecredit) + Number(this.shopInfo
// .shop_deliverycredit)) / 3
// this.score = Number(num.toFixed(1));
this.service_list = data.goods_sku_detail.goods_service
this.skuId = this.goodsSkuDetail.sku_id
//秒杀倒计时
let time = new Date(res.timestamp * 1000)
let currentTime = time.getHours() * 60 * 60 + time.getMinutes() * 60 + time.getSeconds()
if (this.goodsSkuDetail.seckill_start_time <= currentTime && currentTime < this.goodsSkuDetail.seckill_end_time) {
let endTime = parseInt(time.getTime() / 1000) + (this.goodsSkuDetail.seckill_end_time - currentTime)
this.seckillTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: endTime
}
} else if (this.goodsSkuDetail.seckill_start_time > currentTime && currentTime < this.goodsSkuDetail.seckill_end_time) {
this.$message({
message: '限时秒杀活动还未开始',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
} else if (currentTime < this.goodsSkuDetail.seckill_start_time && currentTime > this.goodsSkuDetail.seckill_end_time) {
this.$message({
message: '限时秒杀活动已结束',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
}
if (this.goodsSkuDetail.sku_images) this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.split(",");
else this.goodsSkuDetail.sku_images = [];
// 多规格时合并主图
if (this.goodsSkuDetail.goods_spec_format && this.goodsSkuDetail.goods_image) {
this.goodsSkuDetail.goods_image = this.goodsSkuDetail.goods_image.split(",");
this.master_img = this.goodsSkuDetail.goods_image
this.goodsSkuDetail.sku_images = this.goodsSkuDetail.sku_images.concat(this.goodsSkuDetail.goods_image);
}
//媒体
if (this.goodsSkuDetail.video_url) {
this.switchMedia = "video"
this.playerOptions.poster = this.$img(this.goodsSkuDetail.sku_images[0])
this.playerOptions.sources[0].src = this.$img(this.goodsSkuDetail.video_url)
}
this.picZoomUrl = this.goodsSkuDetail.sku_images[0]
this.goodsSkuDetail.unit = this.goodsSkuDetail.unit || "件"
// 当前商品SKU规格
if (this.goodsSkuDetail.sku_spec_format) this.goodsSkuDetail.sku_spec_format = JSON.parse(this.goodsSkuDetail.sku_spec_format)
// 商品属性
if (this.goodsSkuDetail.goods_attr_format) {
let goods_attr_format = JSON.parse(this.goodsSkuDetail.goods_attr_format);
this.goodsSkuDetail.goods_attr_format = this.$util.unique(goods_attr_format, "attr_id");
for (var i = 0; i < this.goodsSkuDetail.goods_attr_format.length; i++) {
for (var j = 0; j < goods_attr_format.length; j++) {
if (this.goodsSkuDetail.goods_attr_format[i].attr_id == goods_attr_format[j].attr_id && this.goodsSkuDetail.goods_attr_format[i].attr_value_id != goods_attr_format[j].attr_value_id) {
this.goodsSkuDetail.goods_attr_format[i].attr_value_name += "、" + goods_attr_format[j].attr_value_name;
}
}
}
}
// 商品SKU格式
if (this.goodsSkuDetail.goods_spec_format) this.goodsSkuDetail.goods_spec_format = JSON.parse(this.goodsSkuDetail.goods_spec_format)
window.document.title = `${this.goodsSkuDetail.sku_name} - ${this.siteInfo.site_name}`
this.loading = false
} else {
this.$router.push("/")
}
}).then(res => {
if (this.token != "") {
this.getWhetherCollection()
// this.isFollow()
}
// this.getAftersale()
this.modifyGoodsInfo()
this.getEvaluateConfig()
this.getGoodsQrcode()
this.getAddress('province', null, true);
if (!this.locationRegion) {
this.$store.commit("app/SET_LOCATION_REGION", {
"level_1": {
"id": 110000,
"pid": 0,
"name": "北京市",
"shortname": "北京",
"longitude": "116.40529",
"latitude": "39.904987",
"level": 1,
"sort": 1,
"status": 1,
"default_data": 1
},
"level_2": {
"id": 110100,
"pid": 110000,
"name": "北京市",
"shortname": "北京",
"longitude": "116.40529",
"latitude": "39.904987",
"level": 2,
"sort": 1,
"status": 1,
"default_data": 1
},
"level_3": {
"id": 110101,
"pid": 110100,
"name": "东城区",
"shortname": "东城",
"longitude": "116.418755",
"latitude": "39.917545",
"level": 3,
"sort": 3,
"status": 1,
"default_data": 1
},
master_img: []
});
}
this.selectedAddress = this.locationRegion;
this.provinceId = this.selectedAddress.level_1.id
this.getAddress('city', null, true, () => {
this.cityId = this.selectedAddress.level_2.id
if (this.cityId) this.getAddress('district', null, true)
});
}).catch(res => {
this.loading = false
this.$router.push("/")
})
},
categorySearch(category_id) {
goodsCategoryInfo({
category_id: category_id
}).then(res => {
if (res.code == 0 && res.data) {
this.categoryNameArr = [];
try {
let categoryArr = res.data.category_full_name.split("$_SPLIT_$");
categoryArr.forEach((item, index) => {
let obj = {};
obj.name = item;
obj.category_id = res.data["category_id_" + (index + 1)];
this.categoryNameArr.push(obj);
})
} catch (e) {
this.categoryNameArr = [];
}
}
})
},
getEvaluateConfig() {
evaluateConfig().then(res => {
if (res.code == 0) {
var data = res.data;
this.evaluateConfig = data;
if (this.evaluateConfig.evaluate_show == 1) {
//商品评论
this.evaluate_show = true
this.getGoodsEvaluate();
}
}
})
},
service_link() {
if (this.token) {
this.$refs.servicerMessage.show()
} else {
this.$message({
message: "您还未登录",
type: "warning"
})
}
},
changeThumbImg(tag) {
if (this.goodsSkuDetail.sku_images.length < 4) return
let page = this.goodsSkuDetail.sku_images.length % 4 // 可见数量4个
let position = 94
if (page == 0) page = this.goodsSkuDetail.sku_images.length - 4 // 可见数量4个
else if (page != 0 && page != 1 && page < 2) return
if (tag == "prev") {
if (this.thumbPosition != 0 && Math.round(this.thumbPosition, 2) != position) {
this.thumbPosition += position
// this.moveThumbLeft = true;
} else {
// this.moveThumbLeft = false;
}
} else if (tag == "next") {
if (Math.round(this.thumbPosition, 2) != -Math.round(position * page, 2)) {
this.thumbPosition -= position
// this.moveThumbRight = true;
} else {
// this.moveThumbRight = false;
}
}
},
//获取用户是否关注
getWhetherCollection() {
isCollect({
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
this.whetherCollection = res.data
})
},
editCollection() {
//未关注添加关注
if (this.whetherCollection == 0) {
addCollect({
sku_id: this.skuId,
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
var data = res.data
if (data > 0) {
this.whetherCollection = 1
this.goodsSkuDetail.collect_num++
}
})
} else {
//已关注取消关注
deleteCollect({
goods_id: this.goodsSkuDetail.goods_id
}).then(res => {
var data = res.data
if (data > 0) {
this.whetherCollection = 0
this.goodsSkuDetail.collect_num--
}
})
}
},
// 售后保障
getAftersale() {
aftersale({}).then(res => {
if (res.code == 0 && res.data) {
let data = res.data.content
if (res.data.content) this.service = res.data.content
}
})
},
//更新商品信息
modifyGoodsInfo() {
//更新商品点击量
modifyClicks({
sku_id: this.skuId,
site_id: this.goodsSkuDetail.site_id
})
//添加足迹
addGoodsbrowse({
sku_id: this.skuId,
goods_id: this.goodsSkuDetail.goods_id
})
},
// 商品二维码
getGoodsQrcode() {
goodsQrcode({
sku_id: this.skuId
}).then(res => {
let data = res.data
if (data.path.h5.img) this.qrcode = this.$img(data.path.h5.img)
})
},
//商品评价数量
goodsEvaluCount() {
goodsEvaluateCount({
goods_id: this.id
}).then(res => {
if (res.code == 0 && res.data) {
this.evaluteCount = res.data
}
})
},
// 商品评价列表
getGoodsEvaluate() {
goodsEvaluateList({
page: this.currentPage,
page_size: this.pageSize,
goods_id: this.id,
explain_type: this.evaluaType == 0 ? '' : this.evaluaType
}).then(res => {
let list = []
if (res.code == 0 && res.data) {
list = res.data.list
this.total = res.data.count
}
for (var i = 0; i < list.length; i++) {
// 1好评2中评3差评
if (list[i].explain_type == 1) {
list[i].star = 5
} else if (list[i].explain_type == 2) {
list[i].star = 3
} else if (list[i].explain_type == 3) {
list[i].star = 1
}
if (list[i].images) {
list[i].images = list[i].images.split(",")
list[i].imagesFormat = []
for (var k = 0; k < list[i].images.length; k++) {
list[i].imagesFormat.push(this.$img(list[i].images[k]))
}
}
if (list[i].again_images) {
list[i].again_images = list[i].again_images.split(",")
list[i].againImagesFormat = []
for (var j = 0; j < list[i].again_images.length; j++) {
list[i].againImagesFormat.push(this.$img(list[i].again_images[j]))
}
}
if (list[i].is_anonymous == 1) list[i].member_name = list[i].member_name.replace(list[i].member_name.substring(1, list[i].member_name.length - 1), "***")
}
this.goodsEvaluateList = list
})
},
// 图片加载失败
imageErrorEvaluate(index) {
this.goodsEvaluateList[index].member_headimg = this.defaultHeadImage
},
handlePageSizeChange(size) {
this.pageSize = size
this.getGoodsEvaluate()
},
handleCurrentPageChange(page) {
this.currentPage = page
this.getGoodsEvaluate()
},
changeSpec(skuId, spec_id, disabled) {
if (disabled) return
this.specBtnRepeat = false
this.skuId = skuId
// 清空选择
for (var i = 0; i < this.goodsSkuDetail.goods_spec_format.length; i++) {
var sku = this.goodsSkuDetail.goods_spec_format[i]
for (var j = 0; j < sku.value.length; j++) {
// 排除当前点击的规格值
if (spec_id == this.goodsSkuDetail.goods_spec_format[i].value[j].spec_id) {
this.goodsSkuDetail.goods_spec_format[i].value[j].selected = false
}
}
}
seckillGoodsInfo({
sku_id: this.skuId,
seckill_id: this.goodsSkuDetail.seckill_id
}).then(res => {
let data = res.data.goods_sku_detail
if (data != null) {
data.sku_images = data.sku_images.split(",")
this.picZoomUrl = data.sku_images[0]
this.playerOptions.poster = this.$img(data.sku_image)
if (data.sku_images == "") {
data.sku_images = this.master_img;
this.picZoomUrl = data.sku_images[0]
this.playerOptions.poster = this.$img(data.sku_image)
} else {
data.sku_images = data.sku_images.concat(this.master_img);
}
// 当前商品SKU规格
if (data.sku_spec_format) data.sku_spec_format = JSON.parse(data.sku_spec_format)
// 商品SKU格式
if (data.goods_spec_format) data.goods_spec_format = JSON.parse(data.goods_spec_format)
if (data.goods_attr_format) data.goods_attr_format = JSON.parse(data.goods_attr_format)
this.keyInput(true)
// 限时折扣
if (data.promotion_type == 1) {
this.discountTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: data.end_time
}
}
this.specBtnRepeat = false
Object.assign(this.goodsSkuDetail, data)
} else {
this.$router.push("/")
}
})
},
changeNum(tag) {
if (this.goodsSkuDetail.stock == 0) return
var stock = this.goodsSkuDetail.stock
var min = 1
if (tag == "+") {
// 加
if (this.number < stock) {
this.number++
}
} else if (tag == "-") {
// 减
if (this.number > min) {
this.number -= 1
}
}
},
blur() {
let newNumber = parseInt(this.number)
this.number = 0
setTimeout(() => {
this.number = newNumber
}, 0)
},
//输入数量
keyInput(flag, callback) {
setTimeout(() => {
var stock = this.goodsSkuDetail.stock
// 库存为0
if (this.goodsSkuDetail.stock == 0) {
this.number = 0
return
}
// 防止空
if (flag && this.number.length == 0) this.number = 1
// 防止输入0和负数、非法输入
if (flag && (this.number <= 0 || isNaN(this.number))) this.number = 1
if (this.number > stock) {
this.number = stock
}
if (flag) this.number = parseInt(this.number)
if (callback) callback()
}, 0)
},
// 播放回调
onPlayerPlay(player) {
},
// 暂停回调
onPlayerPause(player) {
},
// 视频播完回调
onPlayerEnded(player) {
},
// DOM元素上的readyState更改导致播放停止
onPlayerWaiting(player) {
},
// 已开始播放回调
onPlayerPlaying(player) {
},
// 当播放器在当前播放位置下载数据时触发
onPlayerLoadeddata(player) {
},
// 当前播放位置发生变化时触发。
onPlayerTimeupdate(player) {
},
//媒体的readyState为HAVE_FUTURE_DATA或更高
onPlayerCanplay(player) {
},
//媒体的readyState为HAVE_ENOUGH_DATA或更高。这意味着可以在不缓冲的情况下播放整个媒体文件。
onPlayerCanplaythrough(player) {
},
//播放状态改变回调
playerStateChanged(playerCurrentState) {
},
//将侦听器绑定到组件的就绪状态。与事件监听器的不同之处在于如果ready事件已经发生它将立即触发该函数。。
playerReadied(player) {
},
// 立即购买
buyNow() {
//纠正数量
this.keyInput(true, () => {
if (this.goodsSkuDetail.stock == 0) {
this.$message({
message: "商品已售罄",
type: "warning"
})
return
}
if (this.number.length == 0 || this.number == 0) {
this.$message({
message: "购买数量不能为0",
type: "warning"
})
return
}
// 秒杀
var data = {
seckill_id: this.goodsSkuDetail.seckill_id,
num: this.number,
sku_id: this.skuId
};
this.$store.dispatch("order/setSeckillOrderCreateData", data)
this.$router.push({
path: "/promotion/seckill/payment"
})
})
},
countDownS_cb() {
},
countDownE_cb() {
this.seckillText = "活动已结束"
this.$message({
message: '限时秒杀活动已结束',
type: 'warning',
duration: 2000,
onClose: () => {
this.$router.push("/sku/" + this.goodsSkuDetail.sku_id)
}
});
},
// 图片加载失败
imageErrorSpec(index) {
this.goodsSkuDetail.sku_images[index] = this.defaultGoodsImage
this.picZoomUrl = this.defaultGoodsImage
},
/**
* 获取地址
* @param {Object} type
* @param {Object} item
* @param {Object} first 是否第一次
*/
getAddress(type, item, first, callback) {
let pid = 0
switch (type) {
case 'province':
//加载省
pid = 0
break
case 'city':
//加载市
if (item) {
this.provinceId = item.id
}
pid = this.provinceId
this.cityArr = {}
this.districtArr = {}
break
case 'district':
//加载区县
if (item) this.cityId = item.id
pid = this.cityId
this.districtArr = {}
break
}
if (item) {
if (item.level <= 2) {
let len = item.level;
for (let i = len; i <= 3; i++) {
delete this.selectedAddress['level_' + i];
}
}
this.selectedAddress['level_' + item.level] = item;
}
if (!first) this.$store.commit("app/SET_LOCATION_REGION", this.selectedAddress)
this.$forceUpdate();
if (type == 'community') {
this.hideRegion = true;
setTimeout(() => {
this.hideRegion = false;
}, 10);
return;
}
getArea({
pid: pid
}).then(res => {
const {
code,
data
} = res;
if (data) {
switch (type) {
case 'province':
//加载省
this.provinceArr = data
break
case 'city':
//加载市
this.cityArr = data
break
case 'district':
//加载区县
this.districtArr = data
break
}
this.currTabAddres = type
if (callback) callback();
}
})
}
}
}

View File

@@ -0,0 +1,298 @@
import {goodsPage, timeList} from '@/api/seckill';
import {mapGetters} from 'vuex';
import {adList} from '@/api/website';
import CountDown from 'vue2-countdown';
export default {
name: 'groupbuy',
components: {CountDown},
data: () => {
return {
loading: true,
timeList: [], //时间列表
seckillId: null, //选中的时间块
seckillName: null, //选中的时间块的名称
seckillIndex: null, //选中时间块的index
goodsList: [], //选中时间块的商品列表
index: null, //当前正在抢购的index
siteId: 0,
total: 0,
currentPage: 1,
pageSize: 25,
loadingAd: true,
adList: [],
seckillTimeMachine: {
currentTime: 0,
startTime: 0,
endTime: 0
},
seckillText: '距离结束仅剩',
thumbPosition: 0,
// 是否可以移动
moveThumbLeft: false,
moveThumbRight: false,
shouType: true,
isNoClick: false,
key: 0
};
},
watch: {
seckillId(newName, oldName) {
if (newName && newName != oldName) {
this.refresh();
}
},
addonIsExit() {
if (this.addonIsExit.seckill != 1) {
this.$message({
message: '秒杀插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
}
}
},
created() {
if (this.addonIsExit && this.addonIsExit.seckill != 1) {
this.$message({
message: '秒杀插件未安装',
type: 'warning',
duration: 2000,
onClose: () => {
this.$route.push('/');
}
});
} else {
this.getAdList();
this.getTimeList();
}
},
computed: {
isTrue() {
let num = 0;
if (this.timeList && this.timeList[this.index]) {
num = this.timeList[this.index].isNow;
}
return num;
},
...mapGetters(['defaultGoodsImage', 'addonIsExit'])
},
methods: {
/**
* 点击某个时间段
*/
handleSelected(i, item) {
this.key = i;
let text = this.timeList[i].name
if (i < this.index) {
this.$message.warning(text + '秒杀已结束')
} else if (i > this.index) {
this.shouType = false;
this.seckillId = item.id;
this.isNoClick = true;
this.seckillName = item.name;
// this.$message.warning(text+ '秒杀未开始')
//this.getGoodsList();
this.getTimeList();
} else {
this.seckillId = item.id;
this.shouType = true;
this.isNoClick = false;
this.seckillName = item.name;
//this.getGoodsList();
this.getTimeList();
}
},
/**
* 点击前后箭头
*/
changeThumbImg(tag) {
let _div = this.$refs.seckillTime.clientWidth;
let _i = document.querySelector('.seckill-time-ul').style.left.indexOf('px')
let _li = document.querySelector('.seckill-time-ul').style.left.substring(0, _i)
if (this.timeList.length < 4) return
let page = this.timeList.length % 4 // 可见数量4个
let position = 302.5
if (page == 0) page = this.timeList.length - 4 // 可见数量4个
else if (page != 0 && page != 1 && page < 2) return
if (tag == "prev") {
if (this.thumbPosition != 0 && Math.round(this.thumbPosition, 2) != position && position < Math.abs(this.thumbPosition)) {
this.thumbPosition += position
} else {
this.thumbPosition = 0
}
} else if (tag == "next") {
if (Math.round(this.thumbPosition, 2) != -Math.round(position * page, 2)) {
let _ul = this.timeList.length * position
let _left = _ul - _div
if (Math.abs(this.thumbPosition) - _left >= 0) {
this.thumbPosition = -_left
} else if (Math.abs(this.thumbPosition) - _left < -150) {
this.thumbPosition -= position
} else {
this.thumbPosition = -_left
}
} else {
}
}
},
countDownS_cb() {
},
countDownE_cb() {
this.seckillText = '活动已结束';
},
getAdList() {
adList({keyword: 'NS_PC_SECKILL'}).then(res => {
this.adList = res.data.adv_list;
for (let i = 0; i < this.adList.length; i++) {
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url);
}
this.loadingAd = false;
}).catch(err => {
this.loadingAd = false;
});
},
/**
* 秒杀时间段
*/
getTimeList() {
timeList().then(res => {
let data = res.data;
if (!data) return;
let time = new Date(res.timestamp * 1000);
let newTimes = time.getHours() * 60 * 60 + time.getMinutes() * 60 + time.getSeconds();
data.list.forEach((v, k) => {
if (v.seckill_start_time <= newTimes && newTimes < v.seckill_end_time) {
v.isNow = true;
if (this.shouType == true) {
this.seckillId = v.id;
this.seckillName = v.name;
this.index = k;
this.seckillIndex = k;
let endTime = parseInt(time.getTime() / 1000) + (v.seckill_end_time - newTimes);
this.seckillTimeMachine = {
currentTime: res.timestamp,
startTime: res.timestamp,
endTime: endTime
};
}
} else {
v.isNow = false;
}
// 处理时间格式
v.seckill_end_time_show = v.seckill_end_time_show.slice(0, 5);
v.seckill_start_time_show = v.seckill_start_time_show.slice(0, 5);
});
this.timeList = data.list;
if (!this.seckillId) {
for (let i = 0; i < data.list.length; i++) {
if (newTimes < data.list[i].seckill_start_time && i == 0) {
this.seckillId = data.list[i].id;
this.index = i;
this.seckillIndex = i;
} else if (newTimes < data.list[i].seckill_start_time && newTimes > data.list[i - 1].seckill_end_time && i != 0) {
this.seckillId = data.list[i].id;
this.index = i;
this.seckillIndex = i;
} else if (i == data.list.length - 1 && newTimes > data.list[i].seckill_end_time) {
this.seckillId = data.list[i].id;
this.index = i;
this.seckillIndex = i;
}
}
}
// this.$nextTick(function() {
// if (this.timeList.length > 0) {
// let _div = this.$refs.seckillTime.clientWidth;
// let _li = document.querySelector('.seckill-time-li').clientWidth
// let leftWidth = this.index * _li; // 抢购中的时间段距左边的位置
// let offsetWidth = leftWidth - (_li) * 4; // 需要左偏移的距离
// this.thumbPosition = -offsetWidth
// }
// });
}).catch(err => {
this.$message.error(err.message);
});
},
/**
* 秒杀商品
*/
getGoodsList() {
goodsPage({
page_size: this.pageSize,
page: this.currentPage,
seckill_time_id: this.seckillId,
site_id: this.siteId
}).then(res => {
this.goodsList = res.data.list;
this.goodsList.forEach(v => {
v.goods_image = v.goods_image.split(',')[0]
})
this.total = res.data.count;
this.loading = false;
}).catch(err => {
this.loading = false;
this.$message.error(err.message);
});
},
/**
* 商品详情
*/
toGoodsDetail(id, key) {
let time = new Date();
let newTimes = time.getHours() * 60 * 60 + time.getMinutes() * 60 + time.getSeconds();
if (this.timeList[this.key].seckill_start_time <= newTimes && newTimes < this.timeList[this.key].seckill_end_time) {
this.timeList[this.key].isNow = true;
} else {
this.timeList[this.key].isNow = false;
}
if (!this.timeList[this.key].isNow) {
this.$message.error('秒杀活动还未开启,敬请期待!')
return;
}
this.$router.push('/promotion/seckill/' + id);
},
handlePageSizeChange(size) {
this.pageSize = size;
this.refresh();
},
handleCurrentPageChange(page) {
this.currentPage = page;
this.refresh();
},
refresh() {
this.loading = true;
this.getGoodsList();
},
/**
* 图片加载失败
*/
imageError(index) {
this.goodsList[index].goods_image = this.defaultGoodsImage;
}
},
head() {
return {
title: '秒杀专区-' + this.$store.state.site.siteInfo.site_name,
meta: [{
name: 'description',
content: this.$store.state.site.siteInfo.seo_description
},
{
name: 'keyword',
content: this.$store.state.site.siteInfo.seo_keywords
}
]
}
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff