feat: init push online
32
package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vant/area-data": "^2.1.0",
|
"@vant/area-data": "^2.1.0",
|
||||||
|
"@zxing/library": "^0.21.3",
|
||||||
"image-conversion": "^2.1.1",
|
"image-conversion": "^2.1.1",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||||
@ -629,6 +630,28 @@
|
|||||||
"integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==",
|
"integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@zxing/library": {
|
||||||
|
"version": "0.21.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@zxing/library/-/library-0.21.3.tgz",
|
||||||
|
"integrity": "sha512-hZHqFe2JyH/ZxviJZosZjV+2s6EDSY0O24R+FQmlWZBZXP9IqMo7S3nb3+2LBWxodJQkSurdQGnqE7KXqrYgow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ts-custom-error": "^3.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.4.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@zxing/text-encoding": "~0.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@zxing/text-encoding": {
|
||||||
|
"version": "0.9.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
|
||||||
|
"integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
|
||||||
|
"license": "(Unlicense OR Apache-2.0)",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.16.0",
|
"version": "8.16.0",
|
||||||
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz",
|
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.16.0.tgz",
|
||||||
@ -1629,6 +1652,15 @@
|
|||||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ts-custom-error": {
|
||||||
|
"version": "3.3.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/ts-custom-error/-/ts-custom-error-3.3.1.tgz",
|
||||||
|
"integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vant/area-data": "^2.1.0",
|
"@vant/area-data": "^2.1.0",
|
||||||
|
"@zxing/library": "^0.21.3",
|
||||||
"image-conversion": "^2.1.1",
|
"image-conversion": "^2.1.1",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 215 KiB |
|
Before Width: | Height: | Size: 793 B |
|
Before Width: | Height: | Size: 876 B |
|
Before Width: | Height: | Size: 691 B |
|
Before Width: | Height: | Size: 304 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 528 B |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 419 B |
|
Before Width: | Height: | Size: 2.6 KiB |
BIN
public/img/logo-lr.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 208 KiB |
BIN
public/img/mallDetail-bg.jpg
Normal file
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 912 B |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 413 B |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 579 B |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 611 B |
|
Before Width: | Height: | Size: 558 B |
|
Before Width: | Height: | Size: 949 B |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 259 B |
|
Before Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 501 B |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 365 B |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
@ -16,9 +16,9 @@ const ERR_CODE = {
|
|||||||
SERVER_ERROR: 500,
|
SERVER_ERROR: 500,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getHeaders() {
|
function getHeaders(contentType = 'application/json') {
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': contentType,
|
||||||
};
|
};
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem('token');
|
||||||
if (token) {
|
if (token) {
|
||||||
@ -137,6 +137,26 @@ export const post = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data,
|
|||||||
export const put = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'PUT', timeout);
|
export const put = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'PUT', timeout);
|
||||||
export const del = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'DELETE', timeout);
|
export const del = (url, data, timeout = DEFAULT_TIMEOUT) => request(url, data, 'DELETE', timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST FormData 请求
|
||||||
|
* @param {string} url - 请求路径
|
||||||
|
* @param {FormData} formData - FormData 对象
|
||||||
|
* @param {number} timeout - 超时时间 ms
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export function postForm(url, formData, timeout = DEFAULT_TIMEOUT) {
|
||||||
|
const headers = {};
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
if (token) {
|
||||||
|
headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
}
|
||||||
|
return fetchWithTimeout(BASE_URL + url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers,
|
||||||
|
body: formData,
|
||||||
|
}, timeout).then(handleResponse).catch(handleError);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传文件
|
* 上传文件
|
||||||
* @param {string} url - 请求路径
|
* @param {string} url - 请求路径
|
||||||
@ -175,4 +195,4 @@ export function upload(url, files, timeout = 30000) {
|
|||||||
.catch(handleError);
|
.catch(handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default { get, post, put, del, upload, request };
|
export default { get, post, put, del, upload, postForm, request };
|
||||||
@ -1,13 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="base-list">
|
<div class="base-list" ref="listRef">
|
||||||
<div v-if="loading && list.length === 0" class="loading-wrap">
|
<div v-if="loading && list.length === 0" class="loading-wrap">
|
||||||
<van-loading size="24px">加载中...</van-loading>
|
<van-loading size="24px">加载中...</van-loading>
|
||||||
</div>
|
</div>
|
||||||
<template v-for="(item, index) in list" :key="item.id">
|
<template v-for="(item, index) in list" :key="item.id">
|
||||||
<slot :item="item" :index="index" />
|
<slot :item="item" :index="index" />
|
||||||
</template>
|
</template>
|
||||||
|
<div v-if="loading && list.length > 0" class="loading-wrap">
|
||||||
|
<van-loading size="24px">加载中...</van-loading>
|
||||||
|
</div>
|
||||||
<div v-if="finished && list.length > 0" class="finished-text">{{ finishedText }}</div>
|
<div v-if="finished && list.length > 0" class="finished-text">{{ finishedText }}</div>
|
||||||
<div v-if="finished && list.length === 0 && !loading" class="empty-text">暂无数据</div>
|
<div v-if="finished && list.length === 0 && !loading" class="empty-text">暂无数据</div>
|
||||||
|
<div ref="sentinel" class="sentinel"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -29,6 +33,7 @@ export default {
|
|||||||
list: [],
|
list: [],
|
||||||
page: 1,
|
page: 1,
|
||||||
requestId: 0,
|
requestId: 0,
|
||||||
|
observer: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:list', 'load', 'refresh'],
|
emits: ['update:list', 'load', 'refresh'],
|
||||||
@ -46,9 +51,32 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadMore()
|
this.$nextTick(() => {
|
||||||
|
this.observer = new IntersectionObserver((entries) => {
|
||||||
|
if (entries[0].isIntersecting && !this.loading && !this.finished) {
|
||||||
|
this.loadMore()
|
||||||
|
}
|
||||||
|
}, { rootMargin: '100px' })
|
||||||
|
if (this.$refs.sentinel) {
|
||||||
|
this.observer.observe(this.$refs.sentinel)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
window.addEventListener('scroll', this.onWindowScroll)
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
this.observer?.disconnect()
|
||||||
|
window.removeEventListener('scroll', this.onWindowScroll)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
onWindowScroll() {
|
||||||
|
if (this.finished || this.loading) return
|
||||||
|
const el = this.$refs.sentinel
|
||||||
|
if (!el) return
|
||||||
|
const rect = el.getBoundingClientRect()
|
||||||
|
if (rect.top < window.innerHeight) {
|
||||||
|
this.loadMore()
|
||||||
|
}
|
||||||
|
},
|
||||||
loadMore() {
|
loadMore() {
|
||||||
if (this.loading) return
|
if (this.loading) return
|
||||||
const currentRequestId = this.requestId
|
const currentRequestId = this.requestId
|
||||||
@ -58,7 +86,7 @@ export default {
|
|||||||
.then(res => {
|
.then(res => {
|
||||||
if (currentRequestId !== this.requestId) return
|
if (currentRequestId !== this.requestId) return
|
||||||
const data = this.parseData(res)
|
const data = this.parseData(res)
|
||||||
console.log(data);
|
// console.log(data);
|
||||||
const safeData = data || []
|
const safeData = data || []
|
||||||
|
|
||||||
if (this.page === 1) {
|
if (this.page === 1) {
|
||||||
@ -86,7 +114,6 @@ export default {
|
|||||||
this._skipWatch = true
|
this._skipWatch = true
|
||||||
this.loadMore()
|
this.loadMore()
|
||||||
this.$emit('refresh', this.list)
|
this.$emit('refresh', this.list)
|
||||||
// 同步重置,不再用 $nextTick
|
|
||||||
this._skipWatch = false
|
this._skipWatch = false
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- $isWechat() ? '' : title || -->
|
<!-- $isWechat() ? '' : title || -->
|
||||||
<van-nav-bar fixed :title="$route.meta.title" :safe-area-inset-top="true" placeholder left-arrow left-text="返回"
|
<van-nav-bar fixed :title="title || $route.meta.title" :safe-area-inset-top="true" placeholder left-arrow left-text="返回"
|
||||||
@click-left="back ? back() : $router.back();" :class="$isWechat() ? 'wechat-nav' : ''">
|
@click-left="back ? back() : $router.back();" :class="$isWechat() ? 'wechat-nav' : ''">
|
||||||
<template #right>
|
<template #right>
|
||||||
<slot v-if="$slots.right" name="right" />
|
<slot v-if="$slots.right" name="right" />
|
||||||
|
|||||||
18
src/main.js
@ -44,8 +44,22 @@ const router = createRouter({
|
|||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
import pinia from './stores';
|
import pinia from './stores';
|
||||||
|
import { useDatadicStore, dictCache } from './stores/datadic';
|
||||||
|
import { useUserStore } from './stores/user';
|
||||||
app.use(pinia);
|
app.use(pinia);
|
||||||
|
|
||||||
|
const datadicStore = useDatadicStore()
|
||||||
|
datadicStore.init()
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
app.config.globalProperties.$datadic = {
|
||||||
|
get: (code) => dictCache[code] || null,
|
||||||
|
getContent: (code) => dictCache[code] ? dictCache[code].contents : '',
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.globalProperties.$userInfo = userStore.getUserInfo;
|
||||||
|
|
||||||
app.config.globalProperties.$showDialog = showDialog;
|
app.config.globalProperties.$showDialog = showDialog;
|
||||||
app.config.globalProperties.$showConfirmDialog = showConfirmDialog;
|
app.config.globalProperties.$showConfirmDialog = showConfirmDialog;
|
||||||
app.config.globalProperties.$showNotify = showNotify;
|
app.config.globalProperties.$showNotify = showNotify;
|
||||||
@ -152,6 +166,7 @@ app.config.globalProperties.$token = (e) => {
|
|||||||
};
|
};
|
||||||
app.config.globalProperties.$file = (e) => {
|
app.config.globalProperties.$file = (e) => {
|
||||||
if (!e) return '/img/avatar.png';
|
if (!e) return '/img/avatar.png';
|
||||||
|
if (typeof e !== 'string') return '/img/avatar.png';
|
||||||
if (e.startsWith('http://') || e.startsWith('https://'))
|
if (e.startsWith('http://') || e.startsWith('https://'))
|
||||||
return e;
|
return e;
|
||||||
else
|
else
|
||||||
@ -315,7 +330,7 @@ app.config.globalProperties.$getShareLink = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CH
|
// CH
|
||||||
import { post, get, put, del, request } from './api/http';
|
import { post, get, put, del, request, postForm } from './api/http';
|
||||||
import { isLogin, formatGMT } from './api/user';
|
import { isLogin, formatGMT } from './api/user';
|
||||||
|
|
||||||
app.config.globalProperties.$post = post;
|
app.config.globalProperties.$post = post;
|
||||||
@ -323,6 +338,7 @@ app.config.globalProperties.$get = get;
|
|||||||
app.config.globalProperties.$put = put;
|
app.config.globalProperties.$put = put;
|
||||||
app.config.globalProperties.$del = del;
|
app.config.globalProperties.$del = del;
|
||||||
app.config.globalProperties.$request = request;
|
app.config.globalProperties.$request = request;
|
||||||
|
app.config.globalProperties.$postForm = postForm;
|
||||||
app.config.globalProperties.$isLogin = isLogin;
|
app.config.globalProperties.$isLogin = isLogin;
|
||||||
app.config.globalProperties.$formatGMT = formatGMT;
|
app.config.globalProperties.$formatGMT = formatGMT;
|
||||||
app.config.globalProperties.$formatCellphone = (e) => {
|
app.config.globalProperties.$formatCellphone = (e) => {
|
||||||
|
|||||||
@ -205,7 +205,7 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/GoodsDetail',
|
path: '/GoodsDetail',
|
||||||
name: 'GoodsDetail',
|
name: 'GoodsDetail',
|
||||||
component: () => import('./views/Goods/NGoodsDetail.vue'),
|
component: () => import('./views/Goods/GoodsDetail.vue'),
|
||||||
meta: { title: '商品详情' }
|
meta: { title: '商品详情' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -268,6 +268,12 @@ const routes = [
|
|||||||
component: () => import('./views/Merchant/MerchantIntroduction.vue'),
|
component: () => import('./views/Merchant/MerchantIntroduction.vue'),
|
||||||
meta: { title: '商家资料' }
|
meta: { title: '商家资料' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/QrReader',
|
||||||
|
name: 'QrReader',
|
||||||
|
component: () => import('./views/Operations/QrReader.vue'),
|
||||||
|
meta: { title: '扫一扫' }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/Checkout',
|
path: '/Checkout',
|
||||||
name: 'Checkout',
|
name: 'Checkout',
|
||||||
|
|||||||
38
src/stores/datadic.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { get } from '@/api/http'
|
||||||
|
|
||||||
|
// Module level cache for quick access
|
||||||
|
export let dictCache = {}
|
||||||
|
|
||||||
|
export const useDatadicStore = defineStore('datadic', {
|
||||||
|
state: () => ({
|
||||||
|
dicts: {},
|
||||||
|
loaded: false
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getByCode: (state) => (code) => {
|
||||||
|
return dictCache[code] || null
|
||||||
|
},
|
||||||
|
getContent: (code) => {
|
||||||
|
const item = dictCache[code]
|
||||||
|
return item ? item.contents : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async init() {
|
||||||
|
if (this.loaded) return
|
||||||
|
try {
|
||||||
|
const res = await get('/v1/client/CDatadicsClient')
|
||||||
|
if (res.status === 200 && res.data) {
|
||||||
|
res.data.forEach(item => {
|
||||||
|
dictCache[item.code] = item
|
||||||
|
})
|
||||||
|
this.dicts = dictCache
|
||||||
|
this.loaded = true
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('数据字典加载失败', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -2,4 +2,7 @@ import { createPinia } from 'pinia';
|
|||||||
|
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
|
||||||
|
export { useDatadicStore } from './datadic';
|
||||||
|
export { useUserStore } from './user';
|
||||||
|
|
||||||
export default pinia;
|
export default pinia;
|
||||||
@ -1,18 +1,55 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
|
import { post } from '@/api/http';
|
||||||
|
|
||||||
export const useUserStore = defineStore('user', {
|
export const useUserStore = defineStore('user', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
user: null,
|
|
||||||
token: localStorage.getItem('token') || '',
|
token: localStorage.getItem('token') || '',
|
||||||
|
// 用户基本信息
|
||||||
|
user: null,
|
||||||
|
cellphone: localStorage.getItem('cellphone') || '',
|
||||||
|
nickname: localStorage.getItem('nickname') || '',
|
||||||
|
userimg: localStorage.getItem('userimg') || '',
|
||||||
|
// 扩展字段
|
||||||
|
isshop: localStorage.getItem('isshop') || '',
|
||||||
|
iscenter: localStorage.getItem('iscenter') || '',
|
||||||
|
user_id: localStorage.getItem('user_id') || '',
|
||||||
|
huiyuankaid: localStorage.getItem('huiyuankaid') || '',
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isLogin: (state) => !!state.token,
|
isLogin: (state) => !!state.token,
|
||||||
getUser: (state) => state.user,
|
|
||||||
getToken: (state) => state.token,
|
getToken: (state) => state.token,
|
||||||
|
getUser: (state) => state.user,
|
||||||
|
getUserInfo: (state) => ({
|
||||||
|
cellphone: state.cellphone,
|
||||||
|
nickname: state.nickname,
|
||||||
|
userimg: state.userimg,
|
||||||
|
isshop: state.isshop,
|
||||||
|
iscenter: state.iscenter,
|
||||||
|
user_id: state.user_id,
|
||||||
|
huiyuankaid: state.huiyuankaid,
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setUser(user) {
|
setUser(user) {
|
||||||
this.user = user;
|
this.user = user;
|
||||||
|
if (user) {
|
||||||
|
// 同步到 localStorage 保持兼容
|
||||||
|
this.cellphone = user.cellphone || '';
|
||||||
|
this.nickname = user.nickname || '';
|
||||||
|
this.userimg = user.userimg || '';
|
||||||
|
this.isshop = user.isshop || '';
|
||||||
|
this.iscenter = user.col2 || '';
|
||||||
|
this.user_id = user.id || '';
|
||||||
|
this.huiyuankaid = user.huiyuankaid || '';
|
||||||
|
|
||||||
|
localStorage.setItem('cellphone', this.cellphone);
|
||||||
|
localStorage.setItem('nickname', this.nickname);
|
||||||
|
localStorage.setItem('userimg', this.userimg);
|
||||||
|
localStorage.setItem('isshop', this.isshop);
|
||||||
|
localStorage.setItem('iscenter', this.iscenter);
|
||||||
|
localStorage.setItem('user_id', this.user_id);
|
||||||
|
localStorage.setItem('huiyuankaid', this.huiyuankaid);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
setToken(token) {
|
setToken(token) {
|
||||||
this.token = token;
|
this.token = token;
|
||||||
@ -22,11 +59,36 @@ export const useUserStore = defineStore('user', {
|
|||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* 登录后获取用户信息
|
||||||
|
*/
|
||||||
|
async fetchUserInfo() {
|
||||||
|
try {
|
||||||
|
const res = await post('/v1/client/UserClient/info');
|
||||||
|
if (res.status === 200 && res.data) {
|
||||||
|
this.setUser(res.data);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('fetchUserInfo failed:', err);
|
||||||
|
}
|
||||||
|
},
|
||||||
clearUser() {
|
clearUser() {
|
||||||
this.user = null;
|
this.user = null;
|
||||||
this.token = '';
|
this.token = '';
|
||||||
localStorage.removeItem('token');
|
this.cellphone = '';
|
||||||
localStorage.removeItem('member_username');
|
this.nickname = '';
|
||||||
|
this.userimg = '';
|
||||||
|
this.isshop = '';
|
||||||
|
this.iscenter = '';
|
||||||
|
this.user_id = '';
|
||||||
|
this.huiyuankaid = '';
|
||||||
|
|
||||||
|
// 清除 localStorage
|
||||||
|
const keys = [
|
||||||
|
'token', 'cellphone', 'nickname', 'userimg',
|
||||||
|
'isshop', 'iscenter', 'user_id', 'huiyuankaid', 'member_username'
|
||||||
|
];
|
||||||
|
keys.forEach(key => localStorage.removeItem(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -3115,12 +3115,14 @@
|
|||||||
|
|
||||||
.line1 {
|
.line1 {
|
||||||
.type {
|
.type {
|
||||||
.bs;
|
// .bs;
|
||||||
.box;
|
.box;
|
||||||
.box-center-center;
|
.box-center-center;
|
||||||
width: 10vw;
|
color: #000000;
|
||||||
|
// width: 10vw;
|
||||||
height: 4.8vw;
|
height: 4.8vw;
|
||||||
background-color: #222222;
|
padding: 0 1.2vw;
|
||||||
|
background-color: #ffc6d4;
|
||||||
border-radius: 1.333vw;
|
border-radius: 1.333vw;
|
||||||
margin-right: 1.2vw;
|
margin-right: 1.2vw;
|
||||||
}
|
}
|
||||||
@ -3737,11 +3739,13 @@
|
|||||||
width: 86.67vw;
|
width: 86.67vw;
|
||||||
margin-top: -1.33vw;
|
margin-top: -1.33vw;
|
||||||
padding: 7.8vw 3.33vw 0;
|
padding: 7.8vw 3.33vw 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
.detail {
|
.detail {
|
||||||
.box;
|
.box;
|
||||||
.box-align-center;
|
.box-align-center;
|
||||||
margin-bottom: 3.07vw;
|
margin-bottom: 3.07vw;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: #000000;
|
color: #000000;
|
||||||
@ -5110,6 +5114,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vanupup {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 1.6vw;
|
||||||
|
padding: 8.93vw 10vw;
|
||||||
|
|
||||||
|
.code_box {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
|
||||||
|
.top {
|
||||||
|
.box;
|
||||||
|
.box-center-center;
|
||||||
|
margin-bottom: 6.93vw;
|
||||||
|
font-size: 4.27vw;
|
||||||
|
color: #333333;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.van-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ewm_box {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
.box-align-center;
|
||||||
|
padding: 5.2vw 4.53vw;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 1.6vw;
|
||||||
|
border: solid 0.53vw #4c4c4c;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 57.6vw;
|
||||||
|
height: 57.33vw;
|
||||||
|
margin-bottom: 4vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.opera {
|
.opera {
|
||||||
@ -5364,6 +5409,10 @@
|
|||||||
.f5;
|
.f5;
|
||||||
padding: 7.6vw 4vw;
|
padding: 7.6vw 4vw;
|
||||||
|
|
||||||
|
.van-radio {
|
||||||
|
margin-left: 1.2vw;
|
||||||
|
}
|
||||||
|
|
||||||
.shopinfo {
|
.shopinfo {
|
||||||
.box;
|
.box;
|
||||||
.box-align-center;
|
.box-align-center;
|
||||||
@ -5448,6 +5497,11 @@
|
|||||||
padding: 4vw 3.07vw;
|
padding: 4vw 3.07vw;
|
||||||
margin-top: 4vw;
|
margin-top: 4vw;
|
||||||
|
|
||||||
|
.van-cell {
|
||||||
|
padding: 2.67vw 0;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
.price {
|
.price {
|
||||||
.box;
|
.box;
|
||||||
.box-align-center;
|
.box-align-center;
|
||||||
|
|||||||
@ -1434,8 +1434,8 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.top {
|
.top {
|
||||||
height: 30.4vw;
|
height: 20.4vw;
|
||||||
padding: 19.067vw 0 0 2vw;
|
padding: 10.067vw 0 0 2vw;
|
||||||
.box;
|
.box;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@ -2289,3 +2289,123 @@ img {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.shareimgbox {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
.box-align-center;
|
||||||
|
padding: 6.8vw 9.2vw;
|
||||||
|
width: 80vw;
|
||||||
|
min-width: 80vw;
|
||||||
|
max-width: 80vw;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 2.67vw;
|
||||||
|
|
||||||
|
.share_box {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
.box-align-center;
|
||||||
|
width: 100%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 10.53vw;
|
||||||
|
margin-bottom: 4vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share_userinfo {
|
||||||
|
.box;
|
||||||
|
.box-align-center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 9.33vw;
|
||||||
|
border-radius: 50%;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
.box;
|
||||||
|
.box-center-center;
|
||||||
|
color: #222222;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #fde5eb;
|
||||||
|
border-radius: 3.33vw;
|
||||||
|
// padding: .667vw 0;
|
||||||
|
// padding: 1.2vw 4vw 6vw;
|
||||||
|
padding-left: 6vw;
|
||||||
|
padding-right: 4vw;
|
||||||
|
margin-left: -3.33vw;
|
||||||
|
height: 8vw;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
line-height: 8vw;
|
||||||
|
margin-bottom: 2.4vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods_info {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
.box-align-center;
|
||||||
|
margin-top: 4vw;
|
||||||
|
|
||||||
|
.goods_img {
|
||||||
|
width: 61.47vw;
|
||||||
|
height: 61.47vw;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 2.67vw;
|
||||||
|
border: solid 0.27vw #841e36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods_name {
|
||||||
|
width: 61.47vw;
|
||||||
|
margin-top: 3.33vw;
|
||||||
|
.text-hide(2);
|
||||||
|
line-height: 4vw;
|
||||||
|
height: 8vw;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.goods_price {
|
||||||
|
margin-top: 1.33vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode {
|
||||||
|
.box;
|
||||||
|
.box-tb;
|
||||||
|
.box-align-center;
|
||||||
|
margin-top: 3.33vw;
|
||||||
|
padding-bottom: 3vw;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 17.07vw;
|
||||||
|
height: 17.07vw;
|
||||||
|
margin-bottom: 1.2vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.share_result {
|
||||||
|
margin-top: 4vw;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 2.67vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tips {
|
||||||
|
margin-top: 2vw;
|
||||||
|
color: #999;
|
||||||
|
font-size: 3.2vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -118,19 +118,13 @@
|
|||||||
<!-- 用户协议弹窗 -->
|
<!-- 用户协议弹窗 -->
|
||||||
<van-action-sheet v-model:show="showContract" safe-area-inset-bottom title="用户协议" closeable
|
<van-action-sheet v-model:show="showContract" safe-area-inset-bottom title="用户协议" closeable
|
||||||
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
||||||
<div class="w100 html">
|
<div class="w100 html" v-html="$datadic.getContent('code_yhxy')"></div>
|
||||||
<p>用户协议内容...</p>
|
|
||||||
<p>这里是用户协议的详细条款...</p>
|
|
||||||
</div>
|
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
|
|
||||||
<!-- 隐私政策弹窗 -->
|
<!-- 隐私政策弹窗 -->
|
||||||
<van-action-sheet v-model:show="showPolicy" safe-area-inset-bottom title="隐私政策" closeable
|
<van-action-sheet v-model:show="showPolicy" safe-area-inset-bottom title="隐私政策" closeable
|
||||||
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
||||||
<div class="w100 html">
|
<div class="w100 html" v-html="$datadic.getContent('code_yszc')"></div>
|
||||||
<p>隐私政策内容...</p>
|
|
||||||
<p>这里是隐私政策的详细条款...</p>
|
|
||||||
</div>
|
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -247,6 +241,7 @@ export default {
|
|||||||
}
|
}
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
userStore.setToken(data.data.token)
|
userStore.setToken(data.data.token)
|
||||||
|
userStore.fetchUserInfo()
|
||||||
this.$showSuccessToast?.(data.message)
|
this.$showSuccessToast?.(data.message)
|
||||||
location.replace('#/My')
|
location.replace('#/My')
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
@ -273,6 +268,7 @@ export default {
|
|||||||
}
|
}
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
userStore.setToken(data.data.token)
|
userStore.setToken(data.data.token)
|
||||||
|
userStore.fetchUserInfo()
|
||||||
this.$showSuccessToast?.(data.message)
|
this.$showSuccessToast?.(data.message)
|
||||||
location.replace('#/My')
|
location.replace('#/My')
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|||||||
@ -229,20 +229,23 @@ export default {
|
|||||||
|
|
||||||
this.saving = true;
|
this.saving = true;
|
||||||
const params = {
|
const params = {
|
||||||
realname: this.tempData.realname,
|
"realname": this.tempData.realname,
|
||||||
certno: this.tempData.idnumber,
|
"idnumber": this.tempData.idnumber,
|
||||||
bankid: this.tempData.bankid || 0,
|
"bankid": this.tempData.bankid || 0,
|
||||||
bankname: this.tempData.bankname || '',
|
"bankname": this.tempData.bankname || '',
|
||||||
bankcardnumber: this.tempData.bankcardnumber,
|
"bankcardnumber": this.tempData.bankcardnumber,
|
||||||
bankcellphone: this.tempData.bankcellphone,
|
"bankcellphone": this.tempData.bankcellphone,
|
||||||
sort: 0,
|
"sort": 0,
|
||||||
certtype: '身份证',
|
"certtype": '00',
|
||||||
certvaliditytype: this.checked === 1 ? 1 : 0,
|
"certvaliditytype": this.checked === 1 ? "1" : "0",
|
||||||
certbegindate: this.tempData.certbegindate ? this.tempData.certbegindate.replaceAll('-', '') : '',
|
"certbegindate": this.tempData.certbegindate ? this.tempData.certbegindate.replaceAll('-', '') : '',
|
||||||
certenddate: this.checked === 1 ? '' : (this.tempData.certenddate ? this.tempData.certenddate.replaceAll('-', '') : ''),
|
"certenddate": this.checked === 1 ? '' : (this.tempData.certenddate ? this.tempData.certenddate.replaceAll('-', '') : ''),
|
||||||
cardtype: 1,
|
"cardtype": "1",
|
||||||
provid: this.tempData.provid || '',
|
"provid": this.tempData.provid || '',
|
||||||
areaid: this.tempData.areaid || ''
|
"areaid": this.tempData.areaid || '',
|
||||||
|
"isshopreceive": Boolean(this.$ls.get('isshop'))
|
||||||
|
// "isshopreceive": false
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$post('/v1/client/DUserbankcardsClient', params).then(res => {
|
this.$post('/v1/client/DUserbankcardsClient', params).then(res => {
|
||||||
|
|||||||
@ -66,17 +66,17 @@
|
|||||||
<div class="name">{{ item.name }}</div>
|
<div class="name">{{ item.name }}</div>
|
||||||
<div class="box box-pack-between">
|
<div class="box box-pack-between">
|
||||||
<s>¥{{ item.originalprice?.toFixed(2) }}</s>
|
<s>¥{{ item.originalprice?.toFixed(2) }}</s>
|
||||||
<div class="zeng_box">
|
<!-- <div class="zeng_box">
|
||||||
<span>赠</span>
|
<span>赠</span>
|
||||||
<div>
|
<div>
|
||||||
{{ item.gongxianzhi }}贡献值
|
{{ item.gongxianzhi }}贡献值
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<b><span>¥</span>{{ item.saleprice?.toFixed(2) }}</b>
|
<b><span>¥</span>{{ item.saleprice?.toFixed(2) }}</b>
|
||||||
<span class="r" style="color: #8a8a8a;font-size: 3.2vw;">销量{{ item.salenums
|
<span class="r" style="color: #8a8a8a;font-size: 3.2vw;">销量{{ item.salenums
|
||||||
}}</span>
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -138,6 +138,11 @@ export default {
|
|||||||
if (this.$route.query.id) {
|
if (this.$route.query.id) {
|
||||||
this.changeMainById(Number(this.$route.query.id));
|
this.changeMainById(Number(this.$route.query.id));
|
||||||
}
|
}
|
||||||
|
// 如果URL带有SortType=2(从热销入口进入),默认以销量排序
|
||||||
|
if (this.$route.query.SortType == 2) {
|
||||||
|
this.searchParams.SortType = 2;
|
||||||
|
this.searchParams.IsDesc = true;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async loadCategories() {
|
async loadCategories() {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -1,351 +1,286 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage>
|
<BasePage>
|
||||||
<div class="GoodsDetail">
|
<div class="goodsdetails">
|
||||||
|
<div class="t">
|
||||||
|
<img :src="$file(data.img)" alt="">
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 海报 -->
|
<div class="container">
|
||||||
<div
|
<div class="goodsshow">
|
||||||
style="position: fixed;left: 0;top: 0; z-index: 0;width: 0px;height: 0px;opacity: 0; overflow: hidden;">
|
<div class="t">
|
||||||
<div id="bsCard"
|
<div class="tit">
|
||||||
style="width: 260px; margin: 0 auto; overflow: hidden; border-radius: 10px;height: 450px;">
|
{{ data.name }}
|
||||||
<div class="b_l_w"
|
</div>
|
||||||
style="background-color: #f2f1f7;height: max-content;padding-bottom: 15px;font-family: 'PingFang SC';">
|
<div class="desc" v-if="data.description">
|
||||||
<div class="b_l_w" style="padding: 10px 20px">
|
{{ data.description }}
|
||||||
<img :src="$file(data.img)" style="width: 100%;height: 220px;" />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="b_l"
|
|
||||||
style="background: #daa366;margin-left: 10px;width: 240px;padding: 5px 10px;border-radius: 10px;">
|
<div class="price_box">
|
||||||
<div class="b_l">
|
<div class="price">
|
||||||
<img :src="$file($ls.get('userimg'))" width="40" height="40"
|
¥{{ data.saleprice?.toFixed(2) }}
|
||||||
style="border-radius: 100%; vertical-align: top" />
|
</div>
|
||||||
</div>
|
<div class="oprice">
|
||||||
<div class="b_l"
|
¥{{ data.originalprice?.toFixed(2) }}
|
||||||
style=" line-height: 40px;padding-left: 5px;font-size: 14px;font-weight: bold;color: #fff;">
|
</div>
|
||||||
{{ $ls.get('nickname')?.length > 8 ? $ls.get('nickname').substring(0, 6)
|
<div class="sales r">
|
||||||
+ "..." : $ls.get('nickname') }}
|
已售{{ data.salenums }}
|
||||||
友情推荐
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="b_l_w" style="padding: 5px 10px">
|
<div class="deduct_box">
|
||||||
<div class="b_l"
|
<div class="point">
|
||||||
style="width: 120px;font-size: 12px;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2;line-clamp: 2;">
|
<img src="/img/de-i1.png" alt="">
|
||||||
{{ data.name }}
|
积分抵¥{{ data.deductjifen?.toFixed(2) || '0.00' }}
|
||||||
</div>
|
|
||||||
<div class="b_l" style="height: 30px;width: 1px;background: #d3d3d3;margin: 5px 7px;"></div>
|
|
||||||
<div class="b_r" style="width: 95px; line-height: 40px; font-size: 12px">
|
|
||||||
价格 <span style="color: #fd3c2b">¥{{ data.saleprice }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="b_l_w" style="padding: 0 10px">
|
|
||||||
<div class="b_r" style="margin-top: 0px; margin-right: 10px">
|
|
||||||
<img :src="$file($ls.get('shareLogo'))" width="100" />
|
|
||||||
</div>
|
|
||||||
<div class="b_l"
|
|
||||||
style="width: 78px;text-align: center;padding-top: 5px;height: 95px;font-size: 12px;">
|
|
||||||
<vue-qr :text="shareLink" backgroundColor="rgb(255,255,255,0)" style="width: 100%;"
|
|
||||||
colorLight="rgb(255,255,255,0)"></vue-qr>
|
|
||||||
长按扫码购买
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<van-popup v-model:show="showShareImg" style="width: 66.667vw;border-radius: 3.333vw;">
|
<div class="vip">
|
||||||
<img class="w" :src="ShareImg">
|
<img src="/img/de-i2.png" alt="">
|
||||||
</van-popup>
|
会员卡额度抵¥{{ data.deducthuiyuanka?.toFixed(2) || '0.00' }}
|
||||||
|
|
||||||
<van-swipe class="banner" :autoplay="3000" indicator-color="white">
|
|
||||||
<van-swipe-item v-for="item in bannerImages"><img class="w" :src="$file(item)"></van-swipe-item>
|
|
||||||
<template #indicator="{ active, total }">
|
|
||||||
<div class="custom-indicator">{{ active + 1 }}/{{ total }}</div>
|
|
||||||
</template>
|
|
||||||
</van-swipe>
|
|
||||||
|
|
||||||
<div class="mx-auto">
|
|
||||||
<div class="top">
|
|
||||||
<div class="c">
|
|
||||||
<div class="name">
|
|
||||||
{{ data.name }}
|
|
||||||
</div>
|
|
||||||
<div class="remark">
|
|
||||||
{{ data.description }}
|
|
||||||
</div>
|
|
||||||
<div class="price" v-if="data.saleprice">
|
|
||||||
<b><span>¥</span>{{ data.saleprice?.toFixed(2) }}</b>
|
|
||||||
<s>¥{{ data.originalprice?.toFixed(2) }}</s>
|
|
||||||
<p>已售 {{ data.salenums }}</p>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="give">
|
|
||||||
<div>
|
|
||||||
<img src="/img/coin.png">
|
|
||||||
果实可抵¥{{ $trunc(data.saleprice * data.FruitRate / 100, 2).toFixed(2) }}
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
<div class="label">
|
|
||||||
<span><img src="/img/GroupShopDetail-i2.png">品质保障</span>
|
|
||||||
<span><img src="/img/GroupShopDetail-i2.png">正品包邮</span>
|
|
||||||
<span><img src="/img/GroupShopDetail-i2.png">售后无忧</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="_sku" v-if="data.ForbiddenRule && data.ForbiddenRule.length > 0">
|
|
||||||
<van-cell icon="/img/notShip-i1.png" is-link @click="showNotShip = true">
|
|
||||||
<template #title>
|
|
||||||
不支持发货区域:
|
|
||||||
<span class="span" v-for="list in data.ForbiddenRule">
|
|
||||||
<span v-for="(item, index) in list.Region">
|
|
||||||
{{ item.RegionName }}<font v-if="index < list.Region.length - 1">;</font>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</van-cell>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="_sku">
|
|
||||||
<van-cell icon="bars" @click="showSpecs = true" :title="selectedSku" is-link />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="_video" v-if="videoList.length > 0" @click="showVideoList = true">
|
|
||||||
<img src="/img/GoodsDetail-video.png">
|
|
||||||
<p>视频介绍</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="html">
|
|
||||||
<div class="title">
|
|
||||||
<div class="t">
|
|
||||||
<img src="/img/GroupShopDetail-tit-i3.png">
|
|
||||||
<b>产品详情</b>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w100" v-html="data.contents"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<van-share-sheet v-model:show="showShare" title="立即分享给好友" v-bind:options="options" @select="onSelect">
|
<hr>
|
||||||
</van-share-sheet>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showTip" style="background: transparent;">
|
|
||||||
<img src="/img/fenxiangtishi2.png" class="w" @click="showTip = false" style="height: 100vh;">
|
|
||||||
</van-popup>
|
|
||||||
|
|
||||||
<van-action-bar class="b_l_w" safe-area-inset-bottom placeholder>
|
|
||||||
<van-action-bar-icon @click="$goService()" icon="/img/GroupShopDetail-footer-i1.png" text="客服" />
|
|
||||||
<van-action-bar-icon @click="beforeShare" icon="/img/GroupShopDetail-footer-i2.png" text="分享" />
|
|
||||||
<van-action-bar-button @click="showSpecs = true" color="#d0241c" text="立即购买" />
|
|
||||||
</van-action-bar>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showSpecs" position="bottom" closeable round>
|
|
||||||
<div class="showSpecs">
|
|
||||||
<div class="_product">
|
|
||||||
<img :src="$file(tempSku.img || data.img)">
|
|
||||||
<div class="_c">
|
|
||||||
<div class="price">
|
|
||||||
<span>¥</span>{{ (tempSku.saleprice * tempSku.Qty).toFixed(2) }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d">
|
|
||||||
<div class="selected box box-pack-between">
|
|
||||||
已选:{{ tempSku.skuname }}
|
|
||||||
<span>库存:{{ tempSku.saleleft }}</Span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div v-for="(spec, index) in specSelect">
|
|
||||||
<div class="specs">
|
|
||||||
{{ spec.name }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="label">
|
|
||||||
<a v-for="(child, childIndex) in spec.children"
|
|
||||||
:class="selectedSpecs[spec.name] === child.name ? 'a' : ''"
|
|
||||||
@click="selectSpec(spec.name, child.name)">
|
|
||||||
{{ child.name }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="number" v-if="data.SpuArea != 'gift'">
|
|
||||||
购买数量
|
|
||||||
<van-stepper v-model="tempSku.Qty" min="1" max="99" input-width="8vw" allow-empty="true"
|
|
||||||
theme="round" button-size="5vw" disable-input />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<van-action-bar class="b_l_w" safe-area-inset-bottom placeholder>
|
|
||||||
<van-action-bar-button @click="submit" color="linear-gradient(to right, #ff6034, #ee0a24)"
|
|
||||||
text="立即购买" />
|
|
||||||
</van-action-bar>
|
|
||||||
</div>
|
|
||||||
</van-popup>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showNotShip" class="showNotShip">
|
|
||||||
<img src="/img/notShip-i2.png">
|
|
||||||
<div class="c">
|
|
||||||
<div class="text">
|
|
||||||
不支持发货区域:
|
|
||||||
<span class="span" v-for="list in data.ForbiddenRule">
|
|
||||||
<span v-for="(item, index) in list.Region">
|
|
||||||
{{ item.RegionName }}<font v-if="index < list.Region.length - 1">;</font>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<a class="btn" @click="showNotShip = false">
|
|
||||||
好的,知道了
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</van-popup>
|
|
||||||
|
|
||||||
<van-action-sheet v-model:show="showVideoList" class="popup-GoodsDetail-videoList" safe-area-inset-bottom
|
|
||||||
title="视频介绍列表" closeable style="padding: 0 0 0; min-height: 60%">
|
|
||||||
<van-cell v-for="item in videoList" :icon="$file(item.Poster)" center :title="item.Name"
|
|
||||||
:label="formatTime(item.Duration)" @click="video = item; showVideo = true" />
|
|
||||||
</van-action-sheet>
|
|
||||||
|
|
||||||
<van-popup v-model:show="showVideo" closeable @click-overlay="video = {}" @click-close-icon="video = {}">
|
|
||||||
<video v-if="video.Video" :poster="$file(video.Poster)" controls="" style="width: 100%;height: auto;">
|
|
||||||
<source :src="$file(video.Video)" type="video/mp4" />
|
|
||||||
</video>
|
|
||||||
</van-popup>
|
|
||||||
|
|
||||||
|
<div class="gt">
|
||||||
|
<div>
|
||||||
|
<img src="/img/gt-i1.png" alt="">
|
||||||
|
正品保障
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/img/gt-i1.png" alt="">
|
||||||
|
快速发货
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<img src="/img/gt-i1.png" alt="">
|
||||||
|
售后无忧
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
|
||||||
|
<div class="spec_box" @click="showSpecs = true">
|
||||||
|
<img src="/img/spec.png" alt="">
|
||||||
|
<span>{{ selectedSku }}</span>
|
||||||
|
<van-icon class="r" name="arrow"></van-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="prodetail">
|
||||||
|
<div class="tit">
|
||||||
|
<img src="/img/pro.png" alt="">
|
||||||
|
<span>产品详情</span>
|
||||||
|
</div>
|
||||||
|
<div class="vhtml" v-html="data.contents"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-action-bar safe-area-inset-bottom placeholder>
|
||||||
|
<van-action-bar-icon icon="/img/vb-home.png" text="首页" @click="$navigate('Home')" />
|
||||||
|
<van-action-bar-icon icon="/img/vb-service.png" text="客服" @click="$goService()" />
|
||||||
|
<van-action-bar-icon icon="/img/vb-share.png" text="分享" @click="beforeShare" />
|
||||||
|
<van-action-bar-button color="#ca2904" type="danger" text="立即购买" @click="showSpecs = true" />
|
||||||
|
</van-action-bar>
|
||||||
|
|
||||||
|
<van-share-sheet v-model:show="showShare" title="立即分享给好友" :options="options" @select="onSelect" />
|
||||||
|
|
||||||
|
<van-popup v-model:show="showSpecs" position="bottom" closeable round>
|
||||||
|
<div class="showspec">
|
||||||
|
<div class="goods">
|
||||||
|
<img :src="$file(tempSku.img || data.img)" alt="">
|
||||||
|
<div>
|
||||||
|
<div class="s_price">¥{{ (tempSku.saleprice * tempSku.Qty).toFixed(2) }}</div>
|
||||||
|
<div class="s_stock">剩余:{{ tempSku.saleleft }}</div>
|
||||||
|
<div class="s_spec">已选:{{ tempSku.skuname }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spec_box" v-for="spec in specSelect">
|
||||||
|
<span class="title">
|
||||||
|
{{ spec.name }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="speccc">
|
||||||
|
<div v-for="child in spec.children" class="spec_de"
|
||||||
|
:class="selectedSpecs[spec.name] === child.name ? 'active' : 'inactive'"
|
||||||
|
@click="selectSpec(spec.name, child.name)">
|
||||||
|
{{ child.name }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buynums box">
|
||||||
|
<span class="title">
|
||||||
|
购买数量
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<van-stepper class="r" integer v-model="tempSku.Qty" min="1" max="99" theme="round" button-size="22"
|
||||||
|
disable-input />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<van-action-bar safe-area-inset-bottom placeholder>
|
||||||
|
<van-action-bar-button color="#ca2904" type="danger" text="立即购买" @click="submit" />
|
||||||
|
</van-action-bar>
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
<van-popup v-model:show="show" class="shareimgbox" style="max-width: 80vw;">
|
||||||
|
<div class="share_box" id="bsCard">
|
||||||
|
<img class="logo" src="/img/logo-lr.png" alt="">
|
||||||
|
|
||||||
|
<div class="share_userinfo">
|
||||||
|
<img :src="$file($userInfo.userimg)" alt="">
|
||||||
|
<div class="name"><span>{{ $userInfo.nickname }}友情推荐</span></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="goods_info">
|
||||||
|
<img class="goods_img" :src="$file(data.img)" alt="">
|
||||||
|
<div class="goods_name">{{ data.name }}</div>
|
||||||
|
<div class="goods_price">¥{{ data.saleprice?.toFixed(2) || '0.00' }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="qrcode">
|
||||||
|
<vue-qr :margin="0" :text="shareLink" backgroundColor="rgb(255,255,255)"
|
||||||
|
colorLight="rgb(255,255,255)"></vue-qr>
|
||||||
|
长按扫码购买
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="share_result" v-if="ShareImg">
|
||||||
|
<img :src="ShareImg" alt="分享海报">
|
||||||
|
<!-- <div class="tips">长按保存图片</div> -->
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</BasePage>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { html2canvas, canvasToDataURL } from '@/utils/html2image';
|
import { html2canvas, canvasToDataURL } from '@/utils/html2image';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'GoodsDetail',
|
name: 'GoodsDetail',
|
||||||
emits: ['updateShare'],
|
emits: ['updateShare'],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.init();
|
this.init();
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {},
|
||||||
},
|
specSelect: [],
|
||||||
specSelect: [],
|
show: false,
|
||||||
specCombinations: [],
|
specCombinations: [],
|
||||||
tempSku: {},
|
tempSku: {},
|
||||||
showSpecs: false,
|
showSpecs: false,
|
||||||
selectedSku: '请选择规格分类',
|
selectedSku: '请选择规格分类',
|
||||||
selectedSpecs: {},
|
selectedSpecs: {},
|
||||||
showNotShip: false,
|
showShare: false,
|
||||||
videoList: [],
|
options: [
|
||||||
video: {},
|
{ name: '分享海报', icon: '/img/share.png' },
|
||||||
showVideoList: false,
|
],
|
||||||
showVideo: false,
|
shareLink: '',
|
||||||
showShare: false,
|
ShareImg: '',
|
||||||
showTip: false,
|
loading: false
|
||||||
showShareImg: false,
|
|
||||||
ShareImg: '',
|
|
||||||
options: [
|
|
||||||
{ name: "分享海报", icon: "/img/ff3.png" }
|
|
||||||
],
|
|
||||||
shareLink: location.origin,
|
|
||||||
cartLoading: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
bannerImages() {
|
|
||||||
if (!this.data.imgs) return [this.data.img];
|
|
||||||
const imgs = this.data.imgs.split(';').filter(Boolean);
|
|
||||||
return imgs.length > 0 ? imgs : [this.data.img];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
this.$get(`/v1/client/EProsClient/${this.$route.query.id}`).then(res => {
|
|
||||||
this.data = res.data;
|
|
||||||
this.specSelect = this.data.specSelect || [];
|
|
||||||
this.specCombinations = this.data.specCombinations || [];
|
|
||||||
this.shareLink = `${location.origin}/GoodsDetail?id=${this.data.id}`;
|
|
||||||
this.$emit('updateShare', { title: this.data.name, imageUrl: this.data.img, link: this.shareLink });
|
|
||||||
this.initDefaultSku();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initDefaultSku() {
|
|
||||||
const mainSku = this.specCombinations.find(s => s.ismain) || this.specCombinations[0];
|
|
||||||
if (mainSku) {
|
|
||||||
this.tempSku = { ...mainSku, Qty: 1 };
|
|
||||||
this.selectedSku = "已选:" + mainSku.skuname;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectSpec(specName, specValue) {
|
|
||||||
this.selectedSpecs[specName] = specValue;
|
|
||||||
this.refreshSku();
|
|
||||||
},
|
|
||||||
refreshSku() {
|
|
||||||
const specKeys = Object.keys(this.selectedSpecs);
|
|
||||||
if (specKeys.length === 0) return;
|
|
||||||
|
|
||||||
let matchedSku = this.specCombinations.find(combo => {
|
|
||||||
return specKeys.every(key => {
|
|
||||||
const spec = this.specSelect.find(s => s.name === key);
|
|
||||||
if (!spec) return false;
|
|
||||||
const specValue = this.selectedSpecs[key];
|
|
||||||
return combo.skuname === specValue;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (matchedSku) {
|
|
||||||
this.tempSku = { ...matchedSku, Qty: this.tempSku.Qty || 1 };
|
|
||||||
this.selectedSku = "已选:" + matchedSku.skuname;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelect(option, index) {
|
|
||||||
this.showShare = false;
|
|
||||||
if (option.name === "分享海报") {
|
|
||||||
this.generateShareImg();
|
|
||||||
} else if (option.name == "复制链接") {
|
|
||||||
this.$copyText(location.href);
|
|
||||||
this.$showToast({ type: "success", message: "复制成功" });
|
|
||||||
} else if (option.name == "分享好友") {
|
|
||||||
this.showTip = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
submit() {
|
|
||||||
if (this.tempSku.saleleft < 1) {
|
|
||||||
this.$showFailToast("该规格库存不足,无法购买");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$navigate(`/TradeConfirm?id=${this.data.id}&skuid=${this.tempSku.skuid}`);
|
|
||||||
},
|
|
||||||
beforeShare() {
|
|
||||||
this.showShare = true;
|
|
||||||
},
|
|
||||||
async generateShareImg() {
|
|
||||||
var shareContent = document.querySelector('#bsCard');
|
|
||||||
var width = shareContent.offsetWidth;
|
|
||||||
var height = shareContent.offsetHeight;
|
|
||||||
try {
|
|
||||||
var canvas = await html2canvas(shareContent, {
|
|
||||||
scale: 2,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
useCORS: true,
|
|
||||||
allowTaint: true,
|
|
||||||
});
|
|
||||||
this.ShareImg = canvasToDataURL(canvas, "image/png", 1.0);
|
|
||||||
this.showShareImg = true;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
formatTime(seconds) {
|
|
||||||
const hours = Math.floor(seconds / 3600);
|
|
||||||
const minutes = Math.floor((seconds % 3600) / 60);
|
|
||||||
const secs = seconds % 60;
|
|
||||||
return `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(secs)}`;
|
|
||||||
},
|
|
||||||
pad(num) {
|
|
||||||
return num.toString().padStart(2, '0');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.$get(`/v1/client/EProsClient/${this.$route.query.id}`).then(res => {
|
||||||
|
this.data = res.data;
|
||||||
|
this.specSelect = this.data.specSelect || [];
|
||||||
|
this.specCombinations = this.data.specCombinations || [];
|
||||||
|
const recommend = localStorage.getItem('member_username') || '';
|
||||||
|
this.shareLink = `${location.origin}/#/GoodsDetail?id=${this.data.id}${recommend ? '&RecommendCode=' + recommend : ''}`;
|
||||||
|
this.$emit('updateShare', { title: this.data.name, imageUrl: this.data.img, link: this.shareLink });
|
||||||
|
this.initDefaultSku();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
initDefaultSku() {
|
||||||
|
const mainSku = this.specCombinations.find(s => s.ismain) || this.specCombinations[0];
|
||||||
|
if (mainSku) {
|
||||||
|
this.tempSku = { ...mainSku, Qty: 1 };
|
||||||
|
this.selectedSku = "已选:" + mainSku.skuname;
|
||||||
|
// 根据skuname设置默认选中规格
|
||||||
|
this.specSelect.forEach(spec => {
|
||||||
|
const child = spec.children?.find(c => mainSku.skuname.includes(c.name));
|
||||||
|
if (child) {
|
||||||
|
this.selectedSpecs[spec.name] = child.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectSpec(specName, specValue) {
|
||||||
|
this.selectedSpecs[specName] = specValue;
|
||||||
|
this.refreshSku();
|
||||||
|
},
|
||||||
|
refreshSku() {
|
||||||
|
const specKeys = Object.keys(this.selectedSpecs);
|
||||||
|
if (specKeys.length === 0) return;
|
||||||
|
|
||||||
|
let matchedSku = this.specCombinations.find(combo => {
|
||||||
|
return specKeys.every(key => {
|
||||||
|
const spec = this.specSelect.find(s => s.name === key);
|
||||||
|
if (!spec) return false;
|
||||||
|
const specValue = this.selectedSpecs[key];
|
||||||
|
return combo.skuname === specValue;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchedSku) {
|
||||||
|
this.tempSku = { ...matchedSku, Qty: this.tempSku.Qty || 1 };
|
||||||
|
this.selectedSku = "已选:" + matchedSku.skuname;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelect(option) {
|
||||||
|
this.showShare = false;
|
||||||
|
if (option.name === "分享海报") {
|
||||||
|
this.show = true;
|
||||||
|
this.loading = true;
|
||||||
|
this.ShareImg = '';
|
||||||
|
// 等待 DOM 渲染后再生成
|
||||||
|
setTimeout(() => {
|
||||||
|
this.generateShareImg();
|
||||||
|
}, 200);
|
||||||
|
} else if (option.name == "复制链接") {
|
||||||
|
this.$copyText(location.href);
|
||||||
|
this.$showToast({ type: "success", message: "复制成功" });
|
||||||
|
} else if (option.name == "分享好友") {
|
||||||
|
this.showTip = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit() {
|
||||||
|
if (this.tempSku.saleleft < 1) {
|
||||||
|
this.$showFailToast("该规格库存不足,无法购买");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$navigate(`/TradeConfirm?id=${this.data.id}&buynums=${this.tempSku.Qty}`);
|
||||||
|
},
|
||||||
|
beforeShare() {
|
||||||
|
this.showShare = true;
|
||||||
|
},
|
||||||
|
async generateShareImg() {
|
||||||
|
var shareContent = document.querySelector('#bsCard');
|
||||||
|
if (!shareContent) return;
|
||||||
|
var width = shareContent.offsetWidth;
|
||||||
|
var height = shareContent.offsetHeight;
|
||||||
|
try {
|
||||||
|
var canvas = await html2canvas(shareContent, {
|
||||||
|
scale: 2,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
useCORS: true,
|
||||||
|
allowTaint: true,
|
||||||
|
});
|
||||||
|
this.ShareImg = canvasToDataURL(canvas, "image/png", 1.0);
|
||||||
|
this.loading = false;
|
||||||
|
document.querySelector('.share_box').style.display = 'none';
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -1,245 +0,0 @@
|
|||||||
<template>
|
|
||||||
<BasePage>
|
|
||||||
<div class="goodsdetails">
|
|
||||||
<div class="t">
|
|
||||||
<img :src="$file(data.img)" alt="">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="goodsshow">
|
|
||||||
<div class="t">
|
|
||||||
<div class="tit">
|
|
||||||
{{ data.name }}
|
|
||||||
</div>
|
|
||||||
<div class="desc" v-if="data.description">
|
|
||||||
{{ data.description }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="price_box">
|
|
||||||
<div class="price">
|
|
||||||
¥{{ data.saleprice?.toFixed(2) }}
|
|
||||||
</div>
|
|
||||||
<div class="oprice">
|
|
||||||
¥{{ data.originalprice?.toFixed(2) }}
|
|
||||||
</div>
|
|
||||||
<div class="sales r">
|
|
||||||
已售{{ data.salenums }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="deduct_box">
|
|
||||||
<div class="point">
|
|
||||||
<img src="/img/de-i1.png" alt="">
|
|
||||||
积分抵¥1999.00
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="vip">
|
|
||||||
<img src="/img/de-i2.png" alt="">
|
|
||||||
会员卡额度抵¥1999.00
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="gt">
|
|
||||||
<div>
|
|
||||||
<img src="/img/gt-i1.png" alt="">
|
|
||||||
正品保障
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img src="/img/gt-i1.png" alt="">
|
|
||||||
快速发货
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<img src="/img/gt-i1.png" alt="">
|
|
||||||
售后无忧
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="spec_box" @click="showSpecs = true">
|
|
||||||
<img src="/img/spec.png" alt="">
|
|
||||||
<span>{{ selectedSku }}</span>
|
|
||||||
<van-icon class="r" name="arrow"></van-icon>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="prodetail">
|
|
||||||
<div class="tit">
|
|
||||||
<img src="/img/pro.png" alt="">
|
|
||||||
<span>产品详情</span>
|
|
||||||
</div>
|
|
||||||
<div class="vhtml" v-html="data.contents"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<van-action-bar safe-area-inset-bottom placeholder>
|
|
||||||
<van-action-bar-icon icon="/img/vb-home.png" text="首页" @click="$navigate('Home')" />
|
|
||||||
<van-action-bar-icon icon="/img/vb-service.png" text="客服" @click="$goService()" />
|
|
||||||
<van-action-bar-icon icon="/img/vb-share.png" text="分享" @click="beforeShare" />
|
|
||||||
<van-action-bar-button color="#ca2904" type="danger" text="立即购买" @click="showSpecs = true" />
|
|
||||||
</van-action-bar>
|
|
||||||
|
|
||||||
<van-share-sheet v-model:show="showShare" title="立即分享给好友" :options="options" @select="onSelect" />
|
|
||||||
|
|
||||||
<van-popup v-model:show="showSpecs" position="bottom" closeable round>
|
|
||||||
<div class="showspec">
|
|
||||||
<div class="goods">
|
|
||||||
<img :src="$file(tempSku.img || data.img)" alt="">
|
|
||||||
<div>
|
|
||||||
<div class="s_price">¥{{ (tempSku.saleprice * tempSku.Qty).toFixed(2) }}</div>
|
|
||||||
<div class="s_stock">剩余:{{ tempSku.saleleft }}</div>
|
|
||||||
<div class="s_spec">已选:{{ tempSku.skuname }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="spec_box" v-for="spec in specSelect">
|
|
||||||
<span class="title">
|
|
||||||
{{ spec.name }}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="speccc">
|
|
||||||
<div v-for="child in spec.children" class="spec_de"
|
|
||||||
:class="selectedSpecs[spec.name] === child.name ? 'active' : 'inactive'"
|
|
||||||
@click="selectSpec(spec.name, child.name)">
|
|
||||||
{{ child.name }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buynums box">
|
|
||||||
<span class="title">
|
|
||||||
购买数量
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<van-stepper class="r" integer v-model="tempSku.Qty" min="1" max="99" theme="round" button-size="22"
|
|
||||||
disable-input />
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<van-action-bar safe-area-inset-bottom placeholder>
|
|
||||||
<van-action-bar-button color="#ca2904" type="danger" text="立即购买" @click="submit" />
|
|
||||||
</van-action-bar>
|
|
||||||
</div>
|
|
||||||
</van-popup>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</BasePage>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { html2canvas, canvasToDataURL } from '@/utils/html2image';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'GoodsDetail',
|
|
||||||
emits: ['updateShare'],
|
|
||||||
mounted() {
|
|
||||||
this.init();
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
data: {},
|
|
||||||
specSelect: [],
|
|
||||||
specCombinations: [],
|
|
||||||
tempSku: {},
|
|
||||||
showSpecs: false,
|
|
||||||
selectedSku: '请选择规格分类',
|
|
||||||
selectedSpecs: {},
|
|
||||||
showShare: false,
|
|
||||||
options: [
|
|
||||||
{ name: '分享海报', icon: '/img/share.png' },
|
|
||||||
],
|
|
||||||
shareLink: location.origin
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
init() {
|
|
||||||
this.$get(`/v1/client/EProsClient/${this.$route.query.id}`).then(res => {
|
|
||||||
this.data = res.data;
|
|
||||||
this.specSelect = this.data.specSelect || [];
|
|
||||||
this.specCombinations = this.data.specCombinations || [];
|
|
||||||
this.shareLink = `${location.origin}/GoodsDetail?id=${this.data.id}`;
|
|
||||||
this.$emit('updateShare', { title: this.data.name, imageUrl: this.data.img, link: this.shareLink });
|
|
||||||
this.initDefaultSku();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
initDefaultSku() {
|
|
||||||
const mainSku = this.specCombinations.find(s => s.ismain) || this.specCombinations[0];
|
|
||||||
if (mainSku) {
|
|
||||||
this.tempSku = { ...mainSku, Qty: 1 };
|
|
||||||
this.selectedSku = "已选:" + mainSku.skuname;
|
|
||||||
// 根据skuname设置默认选中规格
|
|
||||||
this.specSelect.forEach(spec => {
|
|
||||||
const child = spec.children?.find(c => mainSku.skuname.includes(c.name));
|
|
||||||
if (child) {
|
|
||||||
this.selectedSpecs[spec.name] = child.name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectSpec(specName, specValue) {
|
|
||||||
this.selectedSpecs[specName] = specValue;
|
|
||||||
this.refreshSku();
|
|
||||||
},
|
|
||||||
refreshSku() {
|
|
||||||
const specKeys = Object.keys(this.selectedSpecs);
|
|
||||||
if (specKeys.length === 0) return;
|
|
||||||
|
|
||||||
let matchedSku = this.specCombinations.find(combo => {
|
|
||||||
return specKeys.every(key => {
|
|
||||||
const spec = this.specSelect.find(s => s.name === key);
|
|
||||||
if (!spec) return false;
|
|
||||||
const specValue = this.selectedSpecs[key];
|
|
||||||
return combo.skuname === specValue;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (matchedSku) {
|
|
||||||
this.tempSku = { ...matchedSku, Qty: this.tempSku.Qty || 1 };
|
|
||||||
this.selectedSku = "已选:" + matchedSku.skuname;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onSelect(option) {
|
|
||||||
this.showShare = false;
|
|
||||||
if (option.name === "分享海报") {
|
|
||||||
this.generateShareImg();
|
|
||||||
} else if (option.name == "复制链接") {
|
|
||||||
this.$copyText(location.href);
|
|
||||||
this.$showToast({ type: "success", message: "复制成功" });
|
|
||||||
} else if (option.name == "分享好友") {
|
|
||||||
this.showTip = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
submit() {
|
|
||||||
if (this.tempSku.saleleft < 1) {
|
|
||||||
this.$showFailToast("该规格库存不足,无法购买");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.$navigate(`/TradeConfirm?id=${this.data.id}&buynums=${this.tempSku.Qty}`);
|
|
||||||
},
|
|
||||||
beforeShare() {
|
|
||||||
this.showShare = true;
|
|
||||||
},
|
|
||||||
async generateShareImg() {
|
|
||||||
var shareContent = document.querySelector('#bsCard');
|
|
||||||
if (!shareContent) return;
|
|
||||||
var width = shareContent.offsetWidth;
|
|
||||||
var height = shareContent.offsetHeight;
|
|
||||||
try {
|
|
||||||
var canvas = await html2canvas(shareContent, {
|
|
||||||
scale: 2,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
useCORS: true,
|
|
||||||
allowTaint: true,
|
|
||||||
});
|
|
||||||
this.ShareImg = canvasToDataURL(canvas, "image/png", 1.0);
|
|
||||||
this.showShareImg = true;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<div @click="$navigate('MerchantCashout')">
|
<div @click="$navigate('MerchantCashout')">
|
||||||
<span>提现中金额
|
<span>提现中金额
|
||||||
</span>
|
</span>
|
||||||
<p>¥1000.00</p>
|
<p>¥{{ data.withdrawing?.toFixed(2) }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -232,6 +232,8 @@ export default {
|
|||||||
this.$ls.set('merchant_shopname', res.data.shopname);
|
this.$ls.set('merchant_shopname', res.data.shopname);
|
||||||
this.$ls.set('merchant_shopimg', res.data.shopimg);
|
this.$ls.set('merchant_shopimg', res.data.shopimg);
|
||||||
this.$ls.set('merchant_cellphone', res.data.cellphone);
|
this.$ls.set('merchant_cellphone', res.data.cellphone);
|
||||||
|
|
||||||
|
this.link = `${location.origin}${location.pathname}#/Checkout?id=${res.data.userid}`
|
||||||
}),
|
}),
|
||||||
this.getCount()
|
this.getCount()
|
||||||
]
|
]
|
||||||
|
|||||||
@ -4,33 +4,34 @@
|
|||||||
<div class="top">
|
<div class="top">
|
||||||
<span>
|
<span>
|
||||||
提现中:
|
提现中:
|
||||||
<b class="red">¥960.00</b>
|
<b class="red">¥{{ statistics.withdrawing?.toFixed(2) || '0.00' }}</b>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="r">
|
<span class="r">
|
||||||
累计提现:
|
累计提现:
|
||||||
<b>¥5960.25</b>
|
<b>¥{{ statistics.withdrawtotal?.toFixed(2) || '0.00' }}</b>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="list">
|
<BaseList ref="listRef" class="list" url="/v1/client/DShopsClient/withdraw">
|
||||||
<div class="item">
|
<template #default="{ item }">
|
||||||
<div class="line">
|
<div class="item">
|
||||||
<b class="state">提现中</b>
|
<div class="line">
|
||||||
<b class="r money red">¥<span>960</span>
|
<b class="state">{{ item.statename }}</b>
|
||||||
</b>
|
<b class="r money red">¥<span>{{ item.wdnums?.toFixed(2) }}</span>
|
||||||
</div>
|
</b>
|
||||||
<div class="record">
|
|
||||||
<div class="left">
|
|
||||||
提现:2024.06.05 00:00:00
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="record">
|
||||||
<div class="right">
|
<div class="left">
|
||||||
发放:2024.06.05 05:25:35
|
提现:{{ $formatGMT(item.addtime, 'yyyy-MM-dd HH:ss') }}
|
||||||
|
</div>
|
||||||
|
<div class="right" v-if="item.trantime">
|
||||||
|
发放:{{ $formatGMT(item.trantime, 'yyyy-MM-dd HH:ss') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
</div>
|
</BaseList>
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
@ -38,7 +39,19 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {}
|
return {
|
||||||
|
statistics: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.$get('/v1/client/DShopsClient/withdrawstatistics').then(res => {
|
||||||
|
this.statistics = res.data || {}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -10,20 +10,20 @@
|
|||||||
<van-icon @click="onShowTerm" name="question-o"></van-icon>
|
<van-icon @click="onShowTerm" name="question-o"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<span class="perform">
|
<span class="perform">
|
||||||
¥{{ data.total?.Balance.toFixed(2) }}
|
¥{{ data.total.income?.toFixed(2) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="btm">
|
<div class="btm">
|
||||||
<div>
|
<div>
|
||||||
<span>昨日收入:</span>
|
<span>昨日收入:</span>
|
||||||
<span>
|
<span>
|
||||||
¥{{ data.total?.YesterdayAmount.toFixed(2) }}
|
¥{{ data.total.incomeyestoday?.toFixed(2) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="r" style="justify-content: end;" @click="$navigate('MerchantCashout')">
|
<div class="r" style="justify-content: end;" @click="$navigate('MerchantCashout')">
|
||||||
<span>提现中:</span>
|
<span>提现中:</span>
|
||||||
<span>
|
<span>
|
||||||
¥{{ data.total?.CashAmount.toFixed(2) }}
|
¥{{ data.total?.withdrawing?.toFixed(2) }}
|
||||||
<van-icon name="arrow"></van-icon>
|
<van-icon name="arrow"></van-icon>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -51,27 +51,30 @@
|
|||||||
<div class="income">
|
<div class="income">
|
||||||
<span>当月收款:</span>
|
<span>当月收款:</span>
|
||||||
<span>
|
<span>
|
||||||
¥{{ data.total?.MonthBalance?.toFixed(2) }}
|
¥{{ data.total?.incomemonth?.toFixed(2) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="details_box">
|
<div class="details_box">
|
||||||
<div class="item" v-for="item in records">
|
<van-empty v-if="records.length === 0" description="暂无记录" />
|
||||||
<div class="line1">
|
<template v-else>
|
||||||
<span class="type">{{ type[item.RecordSource] }}</span>
|
<div class="item" v-for="item in records">
|
||||||
<p>剩余:{{ item.CurValue }}</p>
|
<div class="line1">
|
||||||
<span :class="item.OpeType > 0 ? 'income' : 'expend'">{{ item.OpeType > 0 ?
|
<span class="type">{{ item.typename }}</span>
|
||||||
'+' : '-' }}{{ item.RecordValue?.toFixed(2) }}</span>
|
<p>剩余:{{ item.balance }}</p>
|
||||||
|
<span :class="item.nums > 0 ? 'income' : 'expend'">{{ item.nums > 0 ? '+' : '' }}
|
||||||
|
{{ item.nums?.toFixed(2) }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
操作时间:{{ item.addtime }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
订单编号:{{ item.ordernum }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
</template>
|
||||||
购买时间:{{ item.CTime }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
订单编号:{{ item.TradeCode }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -83,7 +86,7 @@
|
|||||||
</van-popup>
|
</van-popup>
|
||||||
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom title="营业收入说明" closeable
|
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom title="营业收入说明" closeable
|
||||||
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
||||||
<div class="w100 html" v-html="data.Term" />
|
<div class="w100 html" v-html="$datadic.getContent('code_yysrsm')" />
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -91,41 +94,57 @@
|
|||||||
export default {
|
export default {
|
||||||
name: 'MerchantIncome',
|
name: 'MerchantIncome',
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.init();
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
total: {
|
total: {
|
||||||
Balance: 12868.50,
|
balance: 0,
|
||||||
YesterdayAmount: 568.00,
|
incometoday: 0,
|
||||||
CashAmount: 2000.00,
|
incomeyestoday: 0,
|
||||||
MonthBalance: 8650.00
|
incomemonth: 0,
|
||||||
},
|
withdrawing: 0
|
||||||
Term: '营业收入说明:商家通过平台交易获得的收入,每日自动转入绑定银行账户。'
|
}
|
||||||
},
|
},
|
||||||
records: [
|
records: [],
|
||||||
{ RecordSource: 'sale', OpeType: 1, RecordValue: 128.00, CurValue: 12868.50, TradeCode: 'T20260418001', CTime: '2024-04-18 10:30:00' },
|
|
||||||
{ RecordSource: 'sale', OpeType: 1, RecordValue: 256.00, CurValue: 12868.50, TradeCode: 'T20260418002', CTime: '2024-04-18 11:20:00' },
|
|
||||||
{ RecordSource: 'cashout', OpeType: 0, RecordValue: 500.00, CurValue: 12868.50, TradeCode: 'T20260417001', CTime: '2024-04-17 18:00:00' },
|
|
||||||
{ RecordSource: 'sale', OpeType: 1, RecordValue: 89.00, CurValue: 12868.50, TradeCode: 'T20260417002', CTime: '2024-04-17 14:30:00' },
|
|
||||||
],
|
|
||||||
date: [`${new Date().getFullYear()}`, `${new Date().getMonth() + 1}`],
|
date: [`${new Date().getFullYear()}`, `${new Date().getMonth() + 1}`],
|
||||||
currentDate: [`${new Date().getFullYear()}`, `${new Date().getMonth() + 1}`],
|
currentDate: [`${new Date().getFullYear()}`, `${new Date().getMonth() + 1}`],
|
||||||
show: false,
|
show: false,
|
||||||
showDate: false,
|
showDate: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
showTerm: false,
|
showTerm: false,
|
||||||
type: { sale: '收入', cashout: '提现', manual: "其他" }
|
param: {
|
||||||
|
year: new Date().getFullYear(),
|
||||||
|
month: new Date().getMonth() + 1,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
init() {
|
||||||
|
Promise.all([
|
||||||
|
this.$get('/v1/client/DShopsClient/moneystatistics', this.param),
|
||||||
|
this.$get('/v1/client/DShopsClient/money', this.param)
|
||||||
|
]).then(([total, recordsRes]) => {
|
||||||
|
this.data.total = total.data;
|
||||||
|
this.records = recordsRes.data;
|
||||||
|
}).catch(err => {
|
||||||
|
this.$showFailToast(err.message || '加载失败');
|
||||||
|
})
|
||||||
|
},
|
||||||
onconfirm(value) {
|
onconfirm(value) {
|
||||||
this.date = this.currentDate;
|
this.date = this.currentDate;
|
||||||
|
this.param = {
|
||||||
|
year: parseInt(this.currentDate[0]),
|
||||||
|
month: parseInt(this.currentDate[1]),
|
||||||
|
}
|
||||||
this.showDate = false;
|
this.showDate = false;
|
||||||
|
this.init();
|
||||||
},
|
},
|
||||||
onShowTerm() {
|
onShowTerm() {
|
||||||
this.showTerm = true;
|
this.showTerm = true;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -4,8 +4,7 @@
|
|||||||
<div class="intro-header">
|
<div class="intro-header">
|
||||||
<div class="shop-avatar">
|
<div class="shop-avatar">
|
||||||
<van-uploader v-model="formData.AvatarUploader" :after-read="uploadShopImg" :max-count="1" upload-icon="plus">
|
<van-uploader v-model="formData.AvatarUploader" :after-read="uploadShopImg" :max-count="1" upload-icon="plus">
|
||||||
<img v-if="formData.shopimg" :src="$file(formData.shopimg)" class="avatar-img" />
|
<div class="avatar-placeholder">
|
||||||
<div v-else class="avatar-placeholder">
|
|
||||||
<van-icon name="photograph" size="20" />
|
<van-icon name="photograph" size="20" />
|
||||||
</div>
|
</div>
|
||||||
</van-uploader>
|
</van-uploader>
|
||||||
@ -23,10 +22,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<van-cell-group inset class="info-group">
|
<van-cell-group inset class="info-group">
|
||||||
<van-field v-model="formData.shopname" label="店铺名称" placeholder="请输入店铺名称" required />
|
<van-field v-model="formData.shopname" label="店铺名称" placeholder="请输入店铺名称" required />
|
||||||
<van-field v-model="formData.huili" label="惠利比例" placeholder="请输入惠利比例" type="number" required>
|
|
||||||
<template #append>%</template>
|
|
||||||
</van-field>
|
|
||||||
<van-field v-model="formData.cellphone" label="联系电话" placeholder="请输入联系电话" type="tel" required />
|
<van-field v-model="formData.cellphone" label="联系电话" placeholder="请输入联系电话" type="tel" required />
|
||||||
|
<van-field v-model="formData.huili" label="惠利比例" placeholder="请输入惠利比例" type="number">
|
||||||
|
<template #extra><span style="color:#666">%</span></template>
|
||||||
|
</van-field>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -36,11 +35,12 @@
|
|||||||
<span class="readonly-tag">仅展示</span>
|
<span class="readonly-tag">仅展示</span>
|
||||||
</div>
|
</div>
|
||||||
<van-cell-group inset class="info-group">
|
<van-cell-group inset class="info-group">
|
||||||
<van-field v-model="formData.legalname" label="法人姓名" readonly />
|
<van-field v-model="formData.legalpersonname" label="法人姓名" readonly />
|
||||||
<van-field v-model="formData.legalphone" label="法人手机号" readonly />
|
<van-field v-model="formData.legalpersonphone" label="法人手机号" readonly />
|
||||||
<van-field label="法人身份证照片" readonly>
|
<van-field label="法人身份证照片" readonly>
|
||||||
<template #input>
|
<template #input>
|
||||||
<div v-if="formData.legalidimg && formData.legalidimg.length" class="img-thumb" @click="previewImage(formData.legalidimg[0].url)">
|
<div v-if="formData.legalidimg && formData.legalidimg.length" class="img-thumb"
|
||||||
|
@click="previewImage(formData.legalidimg[0].url)">
|
||||||
<img :src="formData.legalidimg[0].url" />
|
<img :src="formData.legalidimg[0].url" />
|
||||||
</div>
|
</div>
|
||||||
<span v-else class="empty">暂无</span>
|
<span v-else class="empty">暂无</span>
|
||||||
@ -48,7 +48,8 @@
|
|||||||
</van-field>
|
</van-field>
|
||||||
<van-field label="营业执照照片" readonly>
|
<van-field label="营业执照照片" readonly>
|
||||||
<template #input>
|
<template #input>
|
||||||
<div v-if="formData.licenseimg && formData.licenseimg.length" class="img-thumb" @click="previewImage(formData.licenseimg[0].url)">
|
<div v-if="formData.licenseimg && formData.licenseimg.length" class="img-thumb"
|
||||||
|
@click="previewImage(formData.licenseimg[0].url)">
|
||||||
<img :src="formData.licenseimg[0].url" />
|
<img :src="formData.licenseimg[0].url" />
|
||||||
</div>
|
</div>
|
||||||
<span v-else class="empty">暂无</span>
|
<span v-else class="empty">暂无</span>
|
||||||
@ -64,10 +65,10 @@
|
|||||||
<span class="readonly-tag">仅展示</span>
|
<span class="readonly-tag">仅展示</span>
|
||||||
</div>
|
</div>
|
||||||
<van-cell-group inset class="info-group">
|
<van-cell-group inset class="info-group">
|
||||||
<van-field v-model="formData.bankname" label="账户名称" readonly />
|
<van-field v-model="formData.bankrealname" label="账户名称" readonly />
|
||||||
<van-field v-model="formData.bankcard" label="银行卡号" readonly />
|
<van-field v-model="formData.bankcardnumber" label="银行卡号" readonly />
|
||||||
<van-field v-model="formData.subbank" label="支行名称" readonly />
|
<!-- <van-field v-model="formData.subbank" label="支行名称" readonly /> -->
|
||||||
<van-field v-model="formData.bankphone" label="银行预留手机号" readonly />
|
<van-field v-model="formData.bankcellphone" label="银行预留手机号" readonly />
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -95,15 +96,15 @@ export default {
|
|||||||
AvatarUploader: [],
|
AvatarUploader: [],
|
||||||
huili: 20,
|
huili: 20,
|
||||||
cellphone: '',
|
cellphone: '',
|
||||||
legalname: '',
|
legalpersonname: '',
|
||||||
legalphone: '',
|
legalpersonphone: '',
|
||||||
legalidimg: [],
|
legalidimg: [],
|
||||||
licenseimg: [],
|
licenseimg: [],
|
||||||
province: '',
|
province: '',
|
||||||
bankname: '',
|
bankname: '',
|
||||||
bankcard: '',
|
bankcardnumber: '',
|
||||||
subbank: '',
|
subbank: '',
|
||||||
bankphone: '',
|
bankcellphone: '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -112,32 +113,37 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
this.$get('/v1/client/DShopsClient/my').then(res => {
|
this.$get('/v1/client/DShopsClient').then(res => {
|
||||||
const data = res.data
|
const data = res.data
|
||||||
this.formData.shopname = data.shopname
|
this.formData.shopname = data.shopname
|
||||||
this.formData.shopimg = data.shopimg
|
this.formData.shopimg = data.shopimg
|
||||||
this.formData.huili = data.huili || 20
|
this.formData.huili = data.feeratio || 20
|
||||||
this.formData.cellphone = data.cellphone
|
this.formData.cellphone = data.cellphone
|
||||||
this.formData.legalname = data.legalname
|
this.formData.legalpersonname = data.legalpersonname
|
||||||
this.formData.legalphone = data.legalphone
|
this.formData.legalpersonphone = data.legalpersonphone
|
||||||
this.formData.province = data.province
|
this.formData.province = data.shopprovince + data.shopcity + data.shopcounty
|
||||||
this.formData.bankname = data.bankname
|
this.formData.bankrealname = data.bankrealname
|
||||||
this.formData.bankcard = data.bankcard
|
this.formData.bankcardnumber = data.bankcardnumber
|
||||||
this.formData.subbank = data.subbank
|
this.formData.subbank = data.subbank
|
||||||
this.formData.bankphone = data.bankphone
|
this.formData.bankcellphone = data.bankcellphone
|
||||||
|
|
||||||
if (data.shopimg) {
|
if (data.shopimg) {
|
||||||
this.formData.AvatarUploader = [{ url: this.$file(data.shopimg), isImage: true }]
|
this.formData.AvatarUploader = [{ url: this.$file(data.shopimg), isImage: true }]
|
||||||
}
|
}
|
||||||
if (data.legalidimg) {
|
if (data.legalpersonidimg) {
|
||||||
this.formData.legalidimg = [{ url: this.$file(data.legalidimg), isImage: true }]
|
this.formData.legalidimg = [{ url: this.$file(data.legalpersonidimg), isImage: true }]
|
||||||
}
|
}
|
||||||
if (data.licenseimg) {
|
if (data.businesslicenseimg) {
|
||||||
this.formData.licenseimg = [{ url: this.$file(data.licenseimg), isImage: true }]
|
this.formData.licenseimg = [{ url: this.$file(data.businesslicenseimg), isImage: true }]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
uploadShopImg(file) {
|
uploadShopImg(file) {
|
||||||
|
if (!file || !file.file) {
|
||||||
|
this.formData.shopimg = ''
|
||||||
|
this.formData.AvatarUploader = []
|
||||||
|
return
|
||||||
|
}
|
||||||
this.formData.shopimg = file.file
|
this.formData.shopimg = file.file
|
||||||
},
|
},
|
||||||
previewImage(url) {
|
previewImage(url) {
|
||||||
@ -146,16 +152,13 @@ export default {
|
|||||||
async save() {
|
async save() {
|
||||||
this.saving = true
|
this.saving = true
|
||||||
try {
|
try {
|
||||||
|
const fd = new FormData()
|
||||||
|
fd.append('shopname', this.formData.shopname)
|
||||||
|
fd.append('shopphone', this.formData.cellphone)
|
||||||
if (this.formData.shopimg instanceof File) {
|
if (this.formData.shopimg instanceof File) {
|
||||||
const url = await this.uploadFile('/v1/client/DShopsClient/shopimg', this.formData.shopimg)
|
fd.append('file', this.formData.shopimg)
|
||||||
this.formData.shopimg = url
|
|
||||||
}
|
}
|
||||||
|
await this.$postForm('/v1/client/DShopsClient/shopinfo', fd)
|
||||||
await this.$put('/v1/client/DShopsClient', {
|
|
||||||
shopname: this.formData.shopname,
|
|
||||||
huili: this.formData.huili,
|
|
||||||
cellphone: this.formData.cellphone,
|
|
||||||
})
|
|
||||||
this.$showSuccessToast('保存成功')
|
this.$showSuccessToast('保存成功')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.$showFailToast(err.message || '保存失败')
|
this.$showFailToast(err.message || '保存失败')
|
||||||
@ -213,7 +216,8 @@ export default {
|
|||||||
border: 3px solid rgba(255, 255, 255, 0.4);
|
border: 3px solid rgba(255, 255, 255, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-placeholder {
|
.avatar-placeholder,
|
||||||
|
.van-uploader__preview-image {
|
||||||
width: 18vw;
|
width: 18vw;
|
||||||
height: 18vw;
|
height: 18vw;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -287,6 +291,7 @@ export default {
|
|||||||
width: 26vw;
|
width: 26vw;
|
||||||
font-size: 3.73vw;
|
font-size: 3.73vw;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.van-field__control) {
|
:deep(.van-field__control) {
|
||||||
@ -299,6 +304,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.van-field__append) {
|
||||||
|
color: #666;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.van-field__extra) {
|
||||||
|
color: #666;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
}
|
||||||
|
|
||||||
:deep(.van-field__control:disabled) {
|
:deep(.van-field__control:disabled) {
|
||||||
color: #999;
|
color: #999;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage>
|
<BasePage>
|
||||||
<div class="merchanttradedetail">
|
<div class="merchanttradedetail">
|
||||||
<div class="state" :class="getStateClass(data.state)">
|
<div class="state" :class="getStateClass(data.state)" v-if="type !== 'user'">
|
||||||
<img :src="data.state >= 3 ? '/img/checked.png' : '/img/loading.png'" alt="">
|
<img :src="data.state >= 3 ? '/img/checked.png' : '/img/loading.png'" alt="">
|
||||||
<b>{{ data.statename }}</b>
|
<b>{{ data.statename }}</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="containar">
|
<div class="state box-tb box-align-center" v-else>
|
||||||
|
<img :src="data.state >= 3 ? '/img/checked.png' : '/img/loading.png'" alt="">
|
||||||
|
<b style="margin:2.4vw 0 0;">交易完成</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="containar" v-if="type !== 'user'">
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<div class="details_box">
|
<div class="details_box">
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
@ -21,39 +26,43 @@
|
|||||||
<span>付款时间:</span>
|
<span>付款时间:</span>
|
||||||
<p>{{ $formatGMT(data.paytime, 'yyyy-MM-dd HH:mm:ss') }}</p>
|
<p>{{ $formatGMT(data.paytime, 'yyyy-MM-dd HH:mm:ss') }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="detail" v-if="data.payway">
|
||||||
|
<span>支付方式:</span>
|
||||||
|
<p>{{ data.payway }}</p>
|
||||||
|
</div>
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span>交易单号:</span>
|
<span>交易单号:</span>
|
||||||
<p>{{ data.ordernum }} <van-icon name="copy" @click="copyOrdernum" /></p>
|
<p>{{ data.ordernum }}<span @click.stop="copyOrdernum">|复制</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span>买单商品总额:</span>
|
<span>买单商品总额:</span>
|
||||||
<p>¥{{ data.ordermoney }}</p>
|
<p>¥{{ data.ordermoney?.toFixed(2) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail" v-if="data.payjifen">
|
<div class="detail" v-if="data.payjifen > 0">
|
||||||
<span>用户积分抵扣:</span>
|
<span>用户积分抵扣:</span>
|
||||||
<p>{{ data.payjifen }}积分</p>
|
<p>-{{ data.payjifen?.toFixed(2) }}积分</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail" v-if="data.payquan">
|
<div class="detail" v-if="data.payquan > 0">
|
||||||
<span>会员卡余额抵扣:</span>
|
<span>会员卡余额抵扣:</span>
|
||||||
<p>¥{{ data.payquan }}</p>
|
<p>-¥{{ data.payquan?.toFixed(2) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span>用户实付金额:</span>
|
<span>用户实付金额:</span>
|
||||||
<p>¥{{ data.paymoney }}</p>
|
<p>¥{{ data.paymoney?.toFixed(2) }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
|
||||||
|
|
||||||
<div class="detail" v-if="data.discountratio">
|
<div class="detail" v-if="data.discountratio">
|
||||||
<span>商家让利比例:</span>
|
<span>商家让利比例:</span>
|
||||||
<p>{{ data.discountratio }}%</p>
|
<p>{{ data.discountratio }}%</p>
|
||||||
</div>
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span>商家让利金额:</span>
|
<span>商家让利金额:</span>
|
||||||
<p>¥{{ data.discount }}</p>
|
<p>-¥{{ data.discount }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<span>商家应收金额:</span>
|
<span>商家应收金额:</span>
|
||||||
@ -61,6 +70,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="containar" v-else>
|
||||||
|
<div class="line"></div>
|
||||||
|
<div class="details_box">
|
||||||
|
<div class="detail">
|
||||||
|
<span>商户名称:</span>
|
||||||
|
<p>{{ data.shopname }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail" v-if="type === '2'">
|
||||||
|
<span>用户账号:</span>
|
||||||
|
<p>{{ $formatCellphone(data.usercellphone) }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span>下单时间:</span>
|
||||||
|
<p>{{ $formatGMT(data.addtime, 'yyyy-MM-dd HH:mm:ss') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span>付款时间:</span>
|
||||||
|
<p>{{ $formatGMT(data.paytime, 'yyyy-MM-dd HH:mm:ss') }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail" v-if="data.payway">
|
||||||
|
<span>支付方式:</span>
|
||||||
|
<p>{{ data.payway }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span>交易单号:</span>
|
||||||
|
<p>{{ data.ordernum }}<span @click.stop="copyOrdernum">|复制</span></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="detail">
|
||||||
|
<span>商品总额:</span>
|
||||||
|
<p>¥{{ data.ordermoney?.toFixed(2) }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail" v-if="data.payjifen">
|
||||||
|
<span>积分抵扣:</span>
|
||||||
|
<p>-{{ data.payjifen?.toFixed(2) }}积分</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail" v-if="data.payquan">
|
||||||
|
<span>会员卡余额抵扣:</span>
|
||||||
|
<p>-{{ data.payquan?.toFixed(2) }}积分</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail">
|
||||||
|
<span>实付金额:</span>
|
||||||
|
<p class="red">¥{{ data.paymoney?.toFixed(2) }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="detail" v-if="data.discountratio">
|
||||||
|
<span>让利比例:</span>
|
||||||
|
<p>{{ data.discountratio }}%</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
</template>
|
</template>
|
||||||
@ -70,7 +132,8 @@ export default {
|
|||||||
name: 'MerchantTradeDetail',
|
name: 'MerchantTradeDetail',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data: {}
|
data: {},
|
||||||
|
type: this.$route.query.type,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -79,7 +142,12 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
init() {
|
init() {
|
||||||
const ordernum = this.$route.query.id;
|
const ordernum = this.$route.query.id;
|
||||||
this.$get(`/v1/client/DShopsClient/order/${ordernum}`).then(res => {
|
const typeParam = this.$route.query.type;
|
||||||
|
const type = typeParam === 'user' ? '2' : (typeParam || '1');
|
||||||
|
const api = type === '2'
|
||||||
|
? `/v1/client/FOrdersshopClient/${ordernum}`
|
||||||
|
: `/v1/client/DShopsClient/order/${ordernum}`;
|
||||||
|
this.$get(api).then(res => {
|
||||||
this.data = res.data || {};
|
this.data = res.data || {};
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.$showFailToast(err.message || '加载失败');
|
this.$showFailToast(err.message || '加载失败');
|
||||||
|
|||||||
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="info_box">
|
<div class="info_box">
|
||||||
<img class="icon" src="" alt="">
|
<img class="icon" :src="$file(userimg || '/img/default-avatar.png')" alt="">
|
||||||
<div class="inf">
|
<div class="inf">
|
||||||
<b>奖励一个挖野菜</b>
|
<b>{{ nickname || '未登录' }}</b>
|
||||||
<div>
|
<div>
|
||||||
<img src="/img/phone.png" alt="">
|
<img src="/img/phone.png" alt="">
|
||||||
12568951256
|
{{ cellphone || '暂无手机号' }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +32,7 @@
|
|||||||
<van-icon name="arrow"></van-icon>
|
<van-icon name="arrow"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<b>
|
<b>
|
||||||
2565.00
|
{{ zijin?.toFixed(2) || '0.00' }}
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -43,13 +43,13 @@
|
|||||||
<van-icon name="arrow"></van-icon>
|
<van-icon name="arrow"></van-icon>
|
||||||
</div>
|
</div>
|
||||||
<b>
|
<b>
|
||||||
2565.00
|
{{ xiaofeiquan?.toFixed(2) || '0.00' }}
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="fun_box">
|
<div class="fun_box">
|
||||||
<div class="item">
|
<div class="item" @click="$navigate('QrReader')">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<b>
|
<b>
|
||||||
扫一扫
|
扫一扫
|
||||||
@ -94,10 +94,16 @@ export default {
|
|||||||
components: { ManagerPopup },
|
components: { ManagerPopup },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
managerPopupVisible: false
|
managerPopupVisible: false,
|
||||||
|
userimg: this.$ls.get('userimg') || '',
|
||||||
|
nickname: this.$ls.get('nickname') || '',
|
||||||
|
cellphone: this.$ls.get('cellphone') || '',
|
||||||
|
zijin: 0,
|
||||||
|
xiaofeiquan: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.init()
|
||||||
window.addEventListener('showManagerPopup', this.onShowManagerPopup)
|
window.addEventListener('showManagerPopup', this.onShowManagerPopup)
|
||||||
window.addEventListener('closeManagerPopup', this.onCloseManagerPopup)
|
window.addEventListener('closeManagerPopup', this.onCloseManagerPopup)
|
||||||
},
|
},
|
||||||
@ -106,6 +112,19 @@ export default {
|
|||||||
window.removeEventListener('closeManagerPopup', this.onCloseManagerPopup)
|
window.removeEventListener('closeManagerPopup', this.onCloseManagerPopup)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.$get('/v1/client/DUsersClient').then(res => {
|
||||||
|
this.userimg = res.data.userimg
|
||||||
|
this.nickname = res.data.nickname
|
||||||
|
this.cellphone = res.data.cellphone
|
||||||
|
this.zijin = res.data.zijin
|
||||||
|
this.xiaofeiquan = res.data.xiaofeiquan
|
||||||
|
// 更新localStorage
|
||||||
|
this.$ls.set('userimg', res.data.userimg)
|
||||||
|
this.$ls.set('nickname', res.data.nickname)
|
||||||
|
this.$ls.set('cellphone', res.data.cellphone)
|
||||||
|
})
|
||||||
|
},
|
||||||
onShowManagerPopup() {
|
onShowManagerPopup() {
|
||||||
this.managerPopupVisible = true
|
this.managerPopupVisible = true
|
||||||
},
|
},
|
||||||
|
|||||||
357
src/views/Operations/QrReader.vue
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
<template>
|
||||||
|
<div class="qr-scanner">
|
||||||
|
<video ref="videoRef" class="video" playsinline autoplay></video>
|
||||||
|
|
||||||
|
<!-- 遮罩层 -->
|
||||||
|
<div class="mask">
|
||||||
|
<!-- 中间扫码区域 -->
|
||||||
|
<div class="scan-area">
|
||||||
|
<div class="corner left-top"></div>
|
||||||
|
<div class="corner left-bottom"></div>
|
||||||
|
<div class="corner right-top"></div>
|
||||||
|
<div class="corner right-bottom"></div>
|
||||||
|
<!-- 扫描线动画 -->
|
||||||
|
<div class="scan-line" v-if="isScanning"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 顶部提示 -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="back" @click="$router.back()">
|
||||||
|
<van-icon name="arrow-left" />
|
||||||
|
</div>
|
||||||
|
<div class="title">扫一扫</div>
|
||||||
|
<div class="placeholder"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<div class="footer">
|
||||||
|
<div class="tip" v-if="!isScanning && !result && !error">将二维码放入框内即可自动扫描</div>
|
||||||
|
<div class="error" v-if="error">{{ error }}</div>
|
||||||
|
<div class="result" v-if="result">
|
||||||
|
<div class="label">扫描结果:</div>
|
||||||
|
<div class="value">{{ result }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 开始扫描提示 -->
|
||||||
|
<div class="start-tip" v-if="!isScanning && !result" @click="startScan">
|
||||||
|
<van-icon name="scan" size="32" />
|
||||||
|
<span>点击开始扫描</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 核销确认弹框 -->
|
||||||
|
<van-dialog v-model:show="showConfirm" title="确认核销" show-cancel-button @confirm="confirmVerify"
|
||||||
|
@cancel="cancelVerify">
|
||||||
|
<div style="padding: 20px; text-align: center;">
|
||||||
|
是否确认核销此礼品券?<br>
|
||||||
|
券码:{{ pendingSysid }}
|
||||||
|
</div>
|
||||||
|
</van-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'QrReader',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
videoRef: null,
|
||||||
|
result: '',
|
||||||
|
isScanning: false,
|
||||||
|
error: '',
|
||||||
|
codeReader: null,
|
||||||
|
stream: null,
|
||||||
|
showConfirm: false,
|
||||||
|
pendingSysid: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.videoRef = this.$refs.videoRef;
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
this.stopScan();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async startScan() {
|
||||||
|
this.error = '';
|
||||||
|
this.result = '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.codeReader = new BrowserMultiFormatReader();
|
||||||
|
|
||||||
|
await this.codeReader.decodeFromVideoDevice(
|
||||||
|
null,
|
||||||
|
this.videoRef,
|
||||||
|
(decodedText, err) => {
|
||||||
|
if (decodedText) {
|
||||||
|
this.result = decodedText;
|
||||||
|
this.handleScanResult(decodedText);
|
||||||
|
this.stopScan();
|
||||||
|
}
|
||||||
|
if (err && !(err instanceof NotFoundException)) {
|
||||||
|
console.error('扫码错误:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.isScanning = true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (e.name === 'NotAllowedError' || e.name === 'PermissionDeniedError') {
|
||||||
|
this.error = '摄像头权限被拒绝,请在设置中允许访问摄像头';
|
||||||
|
} else if (e.name === 'NotFoundError' || e.name === 'DevicesNotFoundError') {
|
||||||
|
this.error = '未找到摄像头设备';
|
||||||
|
} else {
|
||||||
|
this.error = e.message || '无法访问摄像头,请确保已授予摄像头权限';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stopScan() {
|
||||||
|
if (this.codeReader) {
|
||||||
|
this.codeReader.reset();
|
||||||
|
}
|
||||||
|
this.isScanning = false;
|
||||||
|
},
|
||||||
|
handleScanResult(text) {
|
||||||
|
const str = String(text);
|
||||||
|
// 如果是商家收款码链接,直接跳转
|
||||||
|
if (str.includes('/Checkout?id=')) {
|
||||||
|
const id = str.split('/Checkout?id=')[1];
|
||||||
|
window.location.href = `#/Checkout?id=${id}`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 如果是礼品券核销链接
|
||||||
|
const match = str.match(/DUserlipinquansClient\/([^/]+)\/state/);
|
||||||
|
if (match) {
|
||||||
|
this.pendingSysid = match[1];
|
||||||
|
this.showConfirm = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 如果是http链接,直接跳转
|
||||||
|
if (str.startsWith('http://') || str.startsWith('https://')) {
|
||||||
|
window.location.href = str;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 其他内容显示结果
|
||||||
|
this.result = str;
|
||||||
|
},
|
||||||
|
confirmVerify() {
|
||||||
|
this.showConfirm = false;
|
||||||
|
this.$put(`/v1/client/DUserlipinquansClient/${this.pendingSysid}/state`).then(res => {
|
||||||
|
if (res.status === 200) {
|
||||||
|
this.$showSuccessToast('核销成功');
|
||||||
|
this.result = '核销成功';
|
||||||
|
this.$navigate('CertificateRecord?type=verif')
|
||||||
|
// setTimeout(() => {
|
||||||
|
// this.$router.back();
|
||||||
|
// }, 1500);
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
this.$showFailToast(err.message || '核销失败');
|
||||||
|
this.error = err.message || '核销失败';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancelVerify() {
|
||||||
|
this.showConfirm = false;
|
||||||
|
this.pendingSysid = '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.qr-scanner {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: #000;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-area {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 60vw;
|
||||||
|
height: 60vw;
|
||||||
|
max-width: 250px;
|
||||||
|
max-height: 250px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-area::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.corner {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-color: #fff;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-top {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
border-width: 3px 0 0 3px;
|
||||||
|
border-radius: 4px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
border-width: 0 0 3px 3px;
|
||||||
|
border-radius: 0 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-top {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
border-width: 3px 3px 0 0;
|
||||||
|
border-radius: 0 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
border-width: 0 3px 3px 0;
|
||||||
|
border-radius: 0 0 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scan-line {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 10%;
|
||||||
|
right: 10%;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(90deg, transparent, #07c160, transparent);
|
||||||
|
animation: scanMove 2s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes scanMove {
|
||||||
|
0% {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
top: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 16px;
|
||||||
|
padding-top: calc(12px + env(safe-area-inset-top));
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 20px;
|
||||||
|
padding-bottom: calc(20px + env(safe-area-inset-bottom));
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result {
|
||||||
|
background: rgba(255, 255, 255, 0.9);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result .label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result .value {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-tip {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 120px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -152,9 +152,6 @@ export default {
|
|||||||
this.$get('/v1/client/CNewsClient', { page: 1, pageSize: 3, pid: 3 }).then(data => {
|
this.$get('/v1/client/CNewsClient', { page: 1, pageSize: 3, pid: 3 }).then(data => {
|
||||||
this.data.News = data.data.items;
|
this.data.News = data.data.items;
|
||||||
}),
|
}),
|
||||||
this.$get('/v1/client/CDatadicsClient/code_sp').then(data => {
|
|
||||||
this.data.Video = data.data;
|
|
||||||
}),
|
|
||||||
this.$get('/v1/client/CNewsClient?pid=2').then(data => {
|
this.$get('/v1/client/CNewsClient?pid=2').then(data => {
|
||||||
this.data.Trends = data.data.items;
|
this.data.Trends = data.data.items;
|
||||||
}),
|
}),
|
||||||
@ -164,6 +161,9 @@ export default {
|
|||||||
]).catch(err => {
|
]).catch(err => {
|
||||||
this.$showFailToast(err.message || '数据加载失败');
|
this.$showFailToast(err.message || '数据加载失败');
|
||||||
});
|
});
|
||||||
|
// 视频和背景图从数据字典获取
|
||||||
|
this.data.Video = this.$datadic.getContent('code_sp')
|
||||||
|
this.data.slideBg = this.$datadic.getContent('code_yqmbj')
|
||||||
},
|
},
|
||||||
create() {
|
create() {
|
||||||
// this.showcreate = true;
|
// this.showcreate = true;
|
||||||
|
|||||||
@ -40,8 +40,7 @@
|
|||||||
<div class="deduction">
|
<div class="deduction">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<span>商品金额</span>
|
<span>商品金额</span>
|
||||||
<b class="r"><span>¥</span>{{ ((product.saleprice || 0) * (product.buynums || 1))?.toFixed(2)
|
<b class="r"><span>¥</span>{{ totalPrice }}</b>
|
||||||
}}</b>
|
|
||||||
</div>
|
</div>
|
||||||
<van-radio-group v-model="checked" checked-color="#ca2904">
|
<van-radio-group v-model="checked" checked-color="#ca2904">
|
||||||
<van-radio name="1" label-position="left">
|
<van-radio name="1" label-position="left">
|
||||||
@ -52,7 +51,8 @@
|
|||||||
<span>使用积分抵扣</span>
|
<span>使用积分抵扣</span>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
(当前可用:10.00)
|
(当前可用:{{ (userInfo.xiaofeijifen || 0)?.toFixed(2) }},本次可抵:{{
|
||||||
|
actualJifenDeduct?.toFixed(2) }})
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -65,24 +65,26 @@
|
|||||||
<span>使用会员卡抵扣</span>
|
<span>使用会员卡抵扣</span>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
(当前可用:10.00)
|
(当前可用:{{ (userInfo.xiaofeiquan || 0)?.toFixed(2) }},本次可抵:{{
|
||||||
|
actualQuanDeduct?.toFixed(2) }})
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</van-radio>
|
</van-radio>
|
||||||
</van-radio-group>
|
</van-radio-group>
|
||||||
<div class="count">
|
<div class="count">
|
||||||
<div>
|
<div v-if="freight > 0">
|
||||||
<span>运费</span>
|
<span>运费</span>
|
||||||
<span class="price">
|
<span class="price">¥{{ freight.toFixed(2) }}</span>
|
||||||
{{ product.expressprice ? '¥' + product.expressprice.toFixed(2) : '¥0.00' }}
|
</div>
|
||||||
</span>
|
<div v-if="checked">
|
||||||
|
<span>抵扣金额</span>
|
||||||
|
<span class="price">-¥{{ actualDeduct?.toFixed(2) || '0.00' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>实付金额</span>
|
<span>实付金额</span>
|
||||||
<span class="price">
|
<span class="price">
|
||||||
{{ product.saleprice ? '¥' + (product.saleprice * product.buynums).toFixed(2) : '¥0.00'
|
¥{{ actualPay?.toFixed(2) || '0.00' }}
|
||||||
}}
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -94,7 +96,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<van-submit-bar class="b_l_w" placeholder :price="useFruitPrice * 100" :tip="`商品总数:${totalQuantity}件`"
|
<van-submit-bar class="b_l_w" placeholder :price="actualPay * 100" :tip="`商品总数:${totalQuantity}件`"
|
||||||
tip-icon="info-o" safe-area-inset-bottom>
|
tip-icon="info-o" safe-area-inset-bottom>
|
||||||
<template #button>
|
<template #button>
|
||||||
<van-button round color="rgb(227, 83, 33)" :loading="isloading" @click="submitOrder"
|
<van-button round color="rgb(227, 83, 33)" :loading="isloading" @click="submitOrder"
|
||||||
@ -114,6 +116,7 @@ export default {
|
|||||||
name: 'TradeConfirm',
|
name: 'TradeConfirm',
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadProduct();
|
this.loadProduct();
|
||||||
|
this.loadUserInfo();
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -124,9 +127,9 @@ export default {
|
|||||||
useCoupon: 0,
|
useCoupon: 0,
|
||||||
fruit: 0,
|
fruit: 0,
|
||||||
fruitData: {},
|
fruitData: {},
|
||||||
isFruit: false,
|
|
||||||
isloading: false,
|
isloading: false,
|
||||||
checked: 1,
|
checked: '',
|
||||||
|
userInfo: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -136,8 +139,45 @@ export default {
|
|||||||
totalPrice() {
|
totalPrice() {
|
||||||
return ((this.product.saleprice || 0) * (this.product.buynums || 1)).toFixed(2);
|
return ((this.product.saleprice || 0) * (this.product.buynums || 1)).toFixed(2);
|
||||||
},
|
},
|
||||||
|
// 商品金额(不含运费)
|
||||||
|
goodsAmount() {
|
||||||
|
return (this.product.saleprice || 0) * (this.product.buynums || 1);
|
||||||
|
},
|
||||||
|
// 运费
|
||||||
|
freight() {
|
||||||
|
return this.product.expressprice || 0;
|
||||||
|
},
|
||||||
|
// 积分可抵扣金额(接口返回的最高抵扣金额,乘以数量)
|
||||||
|
maxJifenDeduct() {
|
||||||
|
return (this.product.deductjifen || 0) * (this.product.buynums || 1);
|
||||||
|
},
|
||||||
|
// 会员卡可抵扣金额(接口返回的最高抵扣金额,乘以数量)
|
||||||
|
maxQuanDeduct() {
|
||||||
|
return (this.product.deducthuiyuanka || 0) * (this.product.buynums || 1);
|
||||||
|
},
|
||||||
|
// 实际积分可抵扣金额(余额够时抵接口返回金额,不够时抵余额)
|
||||||
|
actualJifenDeduct() {
|
||||||
|
const max = this.maxJifenDeduct;
|
||||||
|
const available = this.userInfo.xiaofeijifen || 0;
|
||||||
|
return Math.min(max, available, this.goodsAmount);
|
||||||
|
},
|
||||||
|
// 实际会员卡可抵扣金额(余额够时抵接口返回金额,不够时抵余额)
|
||||||
|
actualQuanDeduct() {
|
||||||
|
const max = this.maxQuanDeduct;
|
||||||
|
const available = this.userInfo.xiaofeiquan || 0;
|
||||||
|
return Math.min(max, available, this.goodsAmount);
|
||||||
|
},
|
||||||
|
// 当前选中的抵扣方式实际可抵扣金额
|
||||||
|
actualDeduct() {
|
||||||
|
if (!this.checked) return 0;
|
||||||
|
return this.checked === '1' ? this.actualJifenDeduct : this.actualQuanDeduct;
|
||||||
|
},
|
||||||
|
// 实付金额 = 商品金额 + 运费 - 抵扣金额
|
||||||
|
actualPay() {
|
||||||
|
return this.goodsAmount + this.freight - this.actualDeduct;
|
||||||
|
},
|
||||||
useFruitPrice() {
|
useFruitPrice() {
|
||||||
return this.totalPrice;
|
return this.actualPay;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -164,10 +204,17 @@ export default {
|
|||||||
skuname: sku?.skuname || '默认规格',
|
skuname: sku?.skuname || '默认规格',
|
||||||
buynums: parseInt(this.$route.query.buynums) || 1,
|
buynums: parseInt(this.$route.query.buynums) || 1,
|
||||||
typename: data.typename || '商品',
|
typename: data.typename || '商品',
|
||||||
expressprice: data.expressprice || 0
|
expressprice: data.expressprice || 0,
|
||||||
|
deductjifen: data.deductjifen || 0,
|
||||||
|
deducthuiyuanka: data.deducthuiyuanka || 0
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
loadUserInfo() {
|
||||||
|
this.$get('/v1/client/DUsersClient').then(res => {
|
||||||
|
this.userInfo = res.data;
|
||||||
|
}).catch(() => { });
|
||||||
|
},
|
||||||
onAddressConfirm(addr) {
|
onAddressConfirm(addr) {
|
||||||
this.address = addr;
|
this.address = addr;
|
||||||
},
|
},
|
||||||
@ -191,7 +238,8 @@ export default {
|
|||||||
city: this.address.city,
|
city: this.address.city,
|
||||||
county: this.address.county,
|
county: this.address.county,
|
||||||
address: this.address.ReceiveAddress,
|
address: this.address.ReceiveAddress,
|
||||||
isquan: this.isFruit
|
ishuiyuanka: this.checked === '2',
|
||||||
|
isjifen: this.checked === '1'
|
||||||
};
|
};
|
||||||
this.$post('/v1/client/FOrdersClient', form).then(data => {
|
this.$post('/v1/client/FOrdersClient', form).then(data => {
|
||||||
this.$showSuccessToast('提交成功');
|
this.$showSuccessToast('提交成功');
|
||||||
@ -202,10 +250,6 @@ export default {
|
|||||||
this.isloading = false;
|
this.isloading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleClick() {
|
|
||||||
if (!this.exchangePoint)
|
|
||||||
this.isFruit = !this.isFruit;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,67 +1,63 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage :back="back" title="订单详情">
|
<BasePage :back="back" title="订单详情">
|
||||||
<div class="tradelist-details" v-if="data.ordernum"
|
<div class="tradelist-details" v-if="data.ordernum"
|
||||||
:style="`background: url(/img/mallDetail-bg.png) no-repeat;background-size: 100% auto;`">
|
:style="`background: url(/img/mallDetail-bg.jpg) no-repeat;background-size: 100% auto;`">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<img :src="`/img/mallDetail-i${data.state}.png`">
|
<img :src="`/img/mallDetail-i${data.state}.png` || '/img/mallDetail-i0.png'">
|
||||||
<b style="#d2220d">{{ data.statename }}</b>
|
<b style="#d2220d">{{ data.statename }}</b>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="_address">
|
<div class="_goods">
|
||||||
<img src="/img/tradelistDetail-i5.png">
|
<img :src="$file(data.proimg)">
|
||||||
<div class="c">
|
|
||||||
<div>
|
|
||||||
{{ data.receiptrealname }}
|
|
||||||
<span>{{ data.receiptcellphone }}</span>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
{{ data.receiptprovince }}{{ data.receiptcity }}{{ data.receiptcounty }}{{ data.receiptaddress
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="_goods" v-for="item in data.orderdetails" :key="item.id">
|
|
||||||
<img :src="$file(item.proimg)">
|
|
||||||
<div class="c">
|
<div class="c">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<span>{{ item.proname }}</span>
|
<span>{{ data.proname }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="s">
|
<div class="s">
|
||||||
<p>{{ item.proskuname?.split(';').join('/') }}</p>
|
<p>{{ data.proskuname?.split(';').join('/') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<b>
|
<b>
|
||||||
<span>¥</span>{{ item.saleprice?.toFixed(2) }}
|
<span>¥</span>{{ data.proskusaleprice?.toFixed(2) }}
|
||||||
</b>
|
</b>
|
||||||
<p>x{{ item.buynums }}</p>
|
<p>x{{ data.buynums }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="_detail">
|
<div class="_detail">
|
||||||
<div class="p">
|
<div class="p">
|
||||||
<p>
|
|
||||||
订单号:
|
|
||||||
<span>{{ data.ordernum }} <img @click="$copyText(data.ordernum); $showSuccessToast('复制成功')"
|
|
||||||
src="/img/copy.png"></span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
商品总数
|
|
||||||
<span>{{data.orderdetails?.reduce((sum, sku) => sum + sku.buynums, 0)}}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
商品总价
|
商品总价
|
||||||
<span>¥{{ data.orderoriginalmoney?.toFixed(2) }}</span>
|
<span>¥{{ data.ordermoney?.toFixed(2) }}</span>
|
||||||
|
</p>
|
||||||
|
<p v-if="data.payjifen > 0">
|
||||||
|
积分抵扣
|
||||||
|
<span>-¥{{ data.payjifen?.toFixed(2) }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="data.payquan > 0">
|
<p v-if="data.payquan > 0">
|
||||||
优惠券抵扣
|
会员卡额度抵扣
|
||||||
<span>-¥{{ data.payquan?.toFixed(2) }}</span>
|
<span>-¥{{ data.payquan?.toFixed(2) }}</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
实付金额
|
实付金额
|
||||||
<b style="color: #f00;">¥{{ data.needpay?.toFixed(2) }}</b>
|
<b style="color: #f00;">¥{{ data.realmoney?.toFixed(2) }}</b>
|
||||||
</p>
|
</p>
|
||||||
|
<p v-if="data.zongsongjifen">
|
||||||
|
赠送积分
|
||||||
|
<span>{{ data.zongsongjifen }}</span>
|
||||||
|
</p>
|
||||||
|
<hr style="margin:1.67vw 0;height: 1px;border: none;background: #f5f5f580;">
|
||||||
|
<p>
|
||||||
|
订单号:
|
||||||
|
<span>{{ data.ordernum }} <img @click="$copyText(data.ordernum); $showSuccessToast('复制成功')"
|
||||||
|
src="/img/copy.png"></span>
|
||||||
|
</p>
|
||||||
|
<!-- <p>
|
||||||
|
商品总数
|
||||||
|
<span>{{ data.buynums }}</span>
|
||||||
|
</p> -->
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
下单时间
|
下单时间
|
||||||
<span>{{ $formatGMT(data.addtime, 'yyyy-MM-dd HH:mm:ss') }}</span>
|
<span>{{ $formatGMT(data.addtime, 'yyyy-MM-dd HH:mm:ss') }}</span>
|
||||||
@ -117,6 +113,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const res = await this.$get(`/v1/client/FOrdersClient/${this.ordernum}`);
|
const res = await this.$get(`/v1/client/FOrdersClient/${this.ordernum}`);
|
||||||
this.data = res.data;
|
this.data = res.data;
|
||||||
|
this.data.orderdetails = res.data.items;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.$showFailToast(err.message || '加载失败');
|
this.$showFailToast(err.message || '加载失败');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,14 +41,14 @@
|
|||||||
<p>x{{ item.buynums }}</p>
|
<p>x{{ item.buynums }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="concession">
|
<div class="concession">
|
||||||
<span>¥{{ item.realmoney?.toFixed(2) }}</span>
|
<span>¥{{ item.proskusaleprice?.toFixed(2) }}</span>
|
||||||
<p v-if="item.discountratio">{{ item.discountratio }}%让利</p>
|
<p v-if="item.discountratio">{{ item.discountratio }}%让利</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="price">
|
<div class="price">
|
||||||
实付:<span>¥<b>9999.05</b></span>
|
实付:<span>¥<b>{{ item.realmoney?.toFixed(2) }}</b></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="state_box">
|
<div class="state_box">
|
||||||
@ -57,10 +57,11 @@
|
|||||||
</b>
|
</b>
|
||||||
|
|
||||||
<div class="btn_box">
|
<div class="btn_box">
|
||||||
<button v-if="item.state === 0">取消订单</button>
|
<button v-if="item.state === 0" @click="cancelTrade(item)">取消订单</button>
|
||||||
<button v-if="item.state === 3">查看物流</button>
|
<!-- <button v-if="item.state === 3">查看物流</button> -->
|
||||||
<button @click="$navigate(`TradeDetail?ordernum=${item.ordernum}`)">查看详情</button>
|
<button @click="$navigate(`TradeDetail?ordernum=${item.ordernum}`)">查看详情</button>
|
||||||
<button v-if="item.state === 0">立即支付</button>
|
<button v-if="item.state === 3" @click="confirmReceipt(item)">确认收货</button>
|
||||||
|
<button v-if="item.state === 0" @click="$navigate(`Pay?ordernum=${item.ordernum}`)">立即支付</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -85,7 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="price">
|
<div class="price">
|
||||||
实付:<span>¥<b>{{ item.ordermoney?.toFixed(2) }}</b></span>
|
实付:<span>¥<b>{{ item.realmoney?.toFixed(2) }}</b></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="detail_box">
|
<div class="detail_box">
|
||||||
@ -111,7 +112,7 @@
|
|||||||
</b>
|
</b>
|
||||||
|
|
||||||
<div class="btn_box">
|
<div class="btn_box">
|
||||||
<button @click="$navigate(`CheckoutTrade?ordernum=${item.ordernum}&type=user`)">查看详情</button>
|
<button @click="$navigate(`MerchantTradeDetail?id=${item.ordernum}&type=user`)">查看详情</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -198,6 +199,18 @@ export default {
|
|||||||
},
|
},
|
||||||
onRefresh() {
|
onRefresh() {
|
||||||
},
|
},
|
||||||
|
confirmReceipt(item) {
|
||||||
|
this.$showConfirmDialog({
|
||||||
|
title: "是否确认收货",
|
||||||
|
}).then(() => {
|
||||||
|
this.$put(`/v1/client/FOrdersClient/${item.ordernum}/receipt`).then(() => {
|
||||||
|
this.$showSuccessToast('确认收货成功');
|
||||||
|
this.$refs.baseList?.refresh();
|
||||||
|
}).catch(err => {
|
||||||
|
this.$showFailToast(err.message || '操作失败');
|
||||||
|
});
|
||||||
|
}).catch(() => { });
|
||||||
|
},
|
||||||
cancelTrade(item) {
|
cancelTrade(item) {
|
||||||
this.$showConfirmDialog({
|
this.$showConfirmDialog({
|
||||||
title: "是否确认取消订单",
|
title: "是否确认取消订单",
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<BasePage>
|
<BasePage>
|
||||||
<div class="checkout">
|
<div class="checkout" v-if="data.shop && data.shop.shopname">
|
||||||
<div class="shopinfo">
|
<div class="shopinfo">
|
||||||
<img class="icon" :src="$file()" alt="">
|
<img class="icon" :src="$file(data.shop.shopimg)" alt="">
|
||||||
|
|
||||||
<div class="inf">
|
<div class="inf">
|
||||||
<b>完美日记旗舰店</b>
|
<b>{{ data.shop.shopname }}</b>
|
||||||
<div class="hl">
|
<div class="hl">
|
||||||
<img src="/img/buybill.png" alt="">
|
<img src="/img/buybill.png" alt="">
|
||||||
<span>20%</span>
|
<span>{{ data.shop.feeratio }}%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -19,27 +19,29 @@
|
|||||||
</b>
|
</b>
|
||||||
|
|
||||||
<div class="input_box">
|
<div class="input_box">
|
||||||
¥<input type="number" placeholder="请输入买单金额">
|
¥<input type="number" v-model="req.ordermoney" placeholder="请输入买单金额" @input="calcDeduction">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="deduction_box">
|
<div class="deduction_box">
|
||||||
<van-radio-group v-model="checked">
|
<van-radio-group v-model="checked">
|
||||||
<van-cell-group inset center>
|
<van-cell-group inset center>
|
||||||
<van-cell center title="积分抵扣" icon="/img/point_icon.png" clickable @click="checked = '1'">
|
<van-cell center title="积分抵扣" icon="/img/point_icon.png">
|
||||||
<template #right-icon>
|
<template #right-icon>
|
||||||
<span class="canuse">25000.00可用</span>
|
<span class="cantuse" v-if="!data.user.xiaofeijifen || data.user.xiaofeijifen <= 0">暂无可用</span>
|
||||||
<span class="cantuse">暂无可用</span>
|
<span class="canuse" v-else-if="checked !== '1'">{{ data.user.xiaofeijifen?.toFixed(2) }}可用</span>
|
||||||
<span v-if="checked === '1'" class="use">-500.00</span>
|
<span class="use" v-else>-{{ jifenDeduction.toFixed(2) }}</span>
|
||||||
<van-radio name="1" />
|
<van-radio name="1" @click="toggleDeduction('jifen')"
|
||||||
|
:disabled="!data.user.xiaofeijifen || data.user.xiaofeijifen <= 0" />
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<van-cell title="会员卡抵扣" icon="/img/vip_icon.png" clickable @click="checked = '2'">
|
<van-cell title="会员卡抵扣" icon="/img/vip_icon.png">
|
||||||
<template #right-icon>
|
<template #right-icon>
|
||||||
<span class="canuse">25000.00可用</span>
|
<span class="cantuse" v-if="!data.user.xiaofeiquan || data.user.xiaofeiquan <= 0">暂无可用</span>
|
||||||
<span class="cantuse">暂无可用</span>
|
<span class="canuse" v-else-if="checked !== '2'">{{ data.user.xiaofeiquan?.toFixed(2) }}可用</span>
|
||||||
<span v-if="checked === '2'" class="use">-500.00</span>
|
<span class="use" v-else>-{{ quanDeduction.toFixed(2) }}</span>
|
||||||
<van-radio name="2" />
|
<van-radio name="2" @click="toggleDeduction('quan')"
|
||||||
|
:disabled="!data.user.xiaofeiquan || data.user.xiaofeiquan <= 0" />
|
||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
@ -50,11 +52,11 @@
|
|||||||
<p>
|
<p>
|
||||||
实付
|
实付
|
||||||
</p>
|
</p>
|
||||||
<span>¥<b>500.00</b></span>
|
<span>¥<b>{{ actualPay.toFixed(2) }}</b></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="payfor">
|
<button class="payfor" @click="toPay">
|
||||||
去支付
|
去支付
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -65,7 +67,74 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
checked: '1',
|
checked: '',
|
||||||
|
id: this.$route.query.id,
|
||||||
|
data: {
|
||||||
|
user: {},
|
||||||
|
shop: {}
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
ordermoney: '',
|
||||||
|
"isjifen": false,
|
||||||
|
"ishuiyuanka": false,
|
||||||
|
"shopuserid": ''
|
||||||
|
},
|
||||||
|
jifenDeduction: 0,
|
||||||
|
quanDeduction: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
actualPay() {
|
||||||
|
let pay = this.req.ordermoney || 0;
|
||||||
|
if (this.checked === '1') {
|
||||||
|
pay -= this.jifenDeduction;
|
||||||
|
} else if (this.checked === '2') {
|
||||||
|
pay -= this.quanDeduction;
|
||||||
|
}
|
||||||
|
return Math.max(0, pay);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getShopInfo();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getShopInfo() {
|
||||||
|
this.$get('/v1/client/DUsersClient').then(res => {
|
||||||
|
this.data.user = res.data;
|
||||||
|
})
|
||||||
|
if (this.id)
|
||||||
|
this.$get(`/v1/client/DShopsClient/${this.id}`).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
this.data.shop = res.data;
|
||||||
|
this.req.shopuserid = res.data.userid;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toggleDeduction(type) {
|
||||||
|
if (type === 'jifen') {
|
||||||
|
if (!this.data.user.xiaofeijifen || this.data.user.xiaofeijifen <= 0) return;
|
||||||
|
this.checked = '1'
|
||||||
|
this.req.isjifen = this.checked === '1';
|
||||||
|
this.req.ishuiyuanka = false;
|
||||||
|
} else if (type === 'quan') {
|
||||||
|
if (!this.data.user.xiaofeiquan || this.data.user.xiaofeiquan <= 0) return;
|
||||||
|
this.checked = '2';
|
||||||
|
this.req.ishuiyuanka = this.checked === '2';
|
||||||
|
this.req.isjifen = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calcDeduction() {
|
||||||
|
const money = this.req.ordermoney || 0;
|
||||||
|
// 积分可抵扣值最大为买单金额的20%的50% = 买单金额 * 10%
|
||||||
|
this.jifenDeduction = Math.min(money * 0.1, this.data.user.xiaofeijifen || 0);
|
||||||
|
// 会员卡余额最高是买单金额的20%的40% = 买单金额 * 8%
|
||||||
|
this.quanDeduction = Math.min(money * 0.08, this.data.user.xiaofeiquan || 0);
|
||||||
|
},
|
||||||
|
toPay() {
|
||||||
|
this.req.isjifen = this.checked === '1';
|
||||||
|
this.req.ishuiyuanka = this.checked === '2';
|
||||||
|
this.$post('/v1/client/FOrdersshopClient', this.req).then(res => {
|
||||||
|
this.$navigate(`Pay?ordernum=${res.data}`)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
<div class="ewm_bg" style="font-family: 'PingFang SC'">
|
<div class="ewm_bg" style="font-family: 'PingFang SC'">
|
||||||
<div class="d1">
|
<div class="d1">
|
||||||
<div class="w100">
|
<div class="w100">
|
||||||
<!-- <img id="invite_bg" :src="$file(data.Icon)" /> -->
|
<img id="invite_bg" :src="$file($datadic.getContent('code_yqmbj'))" crossorigin="anonymous" />
|
||||||
<img id="invite_bg" src="/img/invite_bg.jpg" crossorigin="anonymous">
|
<!-- <img id="invite_bg" src="/img/invite_bg.jpg" crossorigin="anonymous"> -->
|
||||||
</div>
|
</div>
|
||||||
<img class="icon" :src="$file(data.Avatar) + '?t=1'" crossorigin="anonymous">
|
<img class="icon" :src="$file(data.Avatar) + '?t=1'" crossorigin="anonymous">
|
||||||
<div class="name">
|
<div class="name">
|
||||||
|
|||||||
@ -269,7 +269,10 @@ export default {
|
|||||||
this.$ls.set('isshop', data.data.isshop);
|
this.$ls.set('isshop', data.data.isshop);
|
||||||
this.$ls.set('iscenter', data.data.col2);
|
this.$ls.set('iscenter', data.data.col2);
|
||||||
this.$ls.set('user_id', data.data.id);
|
this.$ls.set('user_id', data.data.id);
|
||||||
this.$ls.set('huiyuankaid', data.data.huiyuankaid)
|
this.$ls.set('huiyuankaid', data.data.huiyuankaid);
|
||||||
|
this.$ls.set('user_cv', data.data.xiaofeiquan);
|
||||||
|
this.$ls.set('user_point', data.data.xiaofeijifen);
|
||||||
|
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -317,40 +320,19 @@ export default {
|
|||||||
this.tempData.userimg = file.file;
|
this.tempData.userimg = file.file;
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
|
const fd = new FormData();
|
||||||
|
fd.append('nickname', this.tempData.nickname);
|
||||||
|
fd.append('cellphone', this.tempData.cellphone);
|
||||||
if (this.tempData.userimg instanceof File) {
|
if (this.tempData.userimg instanceof File) {
|
||||||
const fd = new FormData();
|
|
||||||
fd.append('file', this.tempData.userimg);
|
fd.append('file', this.tempData.userimg);
|
||||||
fetch(`${import.meta.env.VITE_API_URL}/v1/client/DUsersClient/userimg`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` },
|
|
||||||
body: fd,
|
|
||||||
}).then(res => res.json()).then(res => {
|
|
||||||
if (res.status !== 200) throw new Error(res.message);
|
|
||||||
this.tempData.userimg = res.data;
|
|
||||||
}).then(() => {
|
|
||||||
return this.$put('/v1/client/DUsersClient', {
|
|
||||||
nickname: this.tempData.nickname,
|
|
||||||
cellphone: this.tempData.cellphone,
|
|
||||||
});
|
|
||||||
}).then(() => {
|
|
||||||
this.$showSuccessToast('保存成功');
|
|
||||||
this.showInfo = false;
|
|
||||||
window.location.reload();
|
|
||||||
}).catch(err => {
|
|
||||||
this.$showFailToast(err.message || err.message || '保存失败');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.$put('/v1/client/DUsersClient', {
|
|
||||||
nickname: this.tempData.nickname,
|
|
||||||
cellphone: this.tempData.cellphone,
|
|
||||||
}).then(() => {
|
|
||||||
this.$showSuccessToast('保存成功');
|
|
||||||
this.showInfo = false;
|
|
||||||
window.location.reload();
|
|
||||||
}).catch(err => {
|
|
||||||
this.$showFailToast(err.message || '保存失败');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
this.$postForm('/v1/client/DUsersClient/userinfo', fd).then(() => {
|
||||||
|
this.$showSuccessToast('保存成功');
|
||||||
|
this.showInfo = false;
|
||||||
|
window.location.reload();
|
||||||
|
}).catch(err => {
|
||||||
|
this.$showFailToast(err.message || '保存失败');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
valid(field, msg) {
|
valid(field, msg) {
|
||||||
if (!field) {
|
if (!field) {
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom :title="`礼包业绩说明`" closeable
|
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom :title="`礼包业绩说明`" closeable
|
||||||
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
style="min-height: 50%; padding: 0px 10px 10px 10px">
|
||||||
<div class="w100 html" v-html="data.Term" />
|
<div class="w100 html" v-html="$datadic.getContent('code_lbyjsm')" />
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
</div>
|
</div>
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|||||||
@ -282,7 +282,7 @@
|
|||||||
</van-popup>
|
</van-popup>
|
||||||
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom :title="`${this.$route.meta.title}说明`"
|
<van-action-sheet v-model:show="showTerm" safe-area-inset-bottom :title="`${this.$route.meta.title}说明`"
|
||||||
closeable style="min-height: 50%; padding: 0px 10px 10px 10px">
|
closeable style="min-height: 50%; padding: 0px 10px 10px 10px">
|
||||||
<div class="w100 html" v-html="data.Term" />
|
<div class="w100 html" v-html="$datadic.getContent('code_yesm')" />
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
|
|
||||||
</BasePage>
|
</BasePage>
|
||||||
|
|||||||