提交 5d5d76fa 作者: Hao

修改全球购下单

父级 f80d52cf
......@@ -16,6 +16,7 @@ declare module 'vue' {
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElImage: typeof import('element-plus/es')['ElImage']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
......@@ -32,4 +33,7 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
ShopList: typeof import('./src/components/ShopList.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}
......@@ -9,12 +9,30 @@
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script>
window.onresize = () => {
let targetWidth = 1920;
// 2.拿到当前设备(浏览器)的宽度
// document.documentElement 获取html的宽度
let currentWidth =
document.documentElement.clientWidth || document.body.clientWidth;
console.log(currentWidth)
// 3.计算缩放比率(屏幕过宽,根据高度计算缩放比例)
let scaleRatio = currentWidth / targetWidth;
let fontSize = Math.floor((currentWidth / targetWidth) * 16);
// 4.开始缩放网页
console.log(scaleRatio, fontSize, 'scaleRatio')
document.body.style = `font-size:${fontSize}px`;
console.log(document.body, ' document.body')
}
</script>
</body>
</html>
\ No newline at end of file
......@@ -37,7 +37,7 @@
ref="elAutocomplete"
placeholder="输入信息"
contenteditable="true"
style="outline: none; "
style="outline: none;"
@paste.prevent="handlePaste"
@focus="removeDefaultContent"
@input="handleSelect"
......@@ -53,10 +53,17 @@
<input
ref="file"
style="display: none;"
accept="image/bmp,image/jpeg,image/jpg,image/png"
type="file"
@change="fileChange"
@change="fileImgChange"
/>
<!-- accept="image/*" -->
<!-- <input
ref="file"
style="display: none;"
type="file"
accept="image/*"
@change="fileImgChange"
/> -->
</div>
</template>
......@@ -81,20 +88,37 @@ const upfile = () => {
file.value.click()
}
//上传的数据
const fileChange = () => {
const fileImgChange = async () => {
var e: any = window.event || event
var oFile = e.target.files[0]
upLoadFilesHander(oFile).then((ress) => {
const { success, result }: any = ress
})
const loading:any = ElLoading?.service({
await setfileEvent(oFile)
const loading: any = ElLoading?.service({
lock: true,
text: '上传中...',
spinner: 'el-icon-loading',
})
loading.close()
}
const setfileEvent = async (file: any) => {
var html = ''
const { success, result }: any = await upLoadFilesHander(file)
const uploadRes = result
if (!uploadRes) return
console.log(file.type)
if (file.type.includes('image')) {
html = await getImageObject(
uploadRes,
imgShowWidth.value,
imgShowHeight.value,
)
} else {
html = await getFileObject(uploadRes, file)
}
elAutocomplete.value.innerHTML += html.outerHTML
inputVal.value += html.outerHTML
elAutocomplete.value.focus()
}
const handleSelect = (value: any) => {
inputVal.value = value.target.innerHTML
}
......@@ -135,13 +159,9 @@ const cursorInsert = (node: any) => {
//粘贴图片
const handlePasteImageFile = async (clipboardData: any) => {
const img = getPasteImageFile(clipboardData.files)
if (!img) {
return
}
if (!img) return
const uploadRes = await fileToBase64(img)
if (!uploadRes) {
return
}
if (!uploadRes) return
const oImage = await getImageObject(
uploadRes,
imgShowWidth.value,
......@@ -154,7 +174,6 @@ const handlePasteImageFile = async (clipboardData: any) => {
// 获取一个 image object
const getImageObject = (uploadRes: any, showWidth: any, showHeight: any) => {
const oImage = new Image(showWidth, showHeight)
const datasetFields = ['width', 'height']
const datasetSizes: any = {
width: '200',
......@@ -166,10 +185,19 @@ const getImageObject = (uploadRes: any, showWidth: any, showHeight: any) => {
oImage.src = uploadRes
return oImage
}
const getFileObject = (url: any, oFile: any) => {
var aTag = document.createElement('a')
aTag.href = url
aTag.download = oFile.name
// aTag.setAttribute('href', url)
aTag.textContent = oFile.name
// aTag.setAttribute('download', oFile.name)
console.log(aTag, 'aTag')
return aTag
}
const getPasteImageFile = (clipboardDataFiles: any) => {
if (!clipboardDataFiles.length) {
return null
}
if (!clipboardDataFiles.length) return null
// 剪切版中选择的(用户第一个点的在尾)第一张图片
const clipboardDataFileList = Array.from(clipboardDataFiles || [])
let firstSelectedImage = null
......@@ -246,7 +274,7 @@ defineExpose({
}
.el-autocomplete {
width: 100%;
height: calc(100vh - 732px);
height: calc(100vh - 732px);
max-width: 100%;
overflow: auto;
}
......
......@@ -172,18 +172,21 @@ export const upLoadHander = async (obj: any) => {
async: false,
}
);
if (uploadRes.success && uploadRes.message) {
let data = uploadRes.data;
console.log(data,'uploadRes')
if (data.success && data.message) {
//保存绝对路径,不然小程序会有问题
let url = uploadRes.message;
url = uploadRes.message.replaceAll("//", "/");
const pre = url.startsWith("/") ? "" : "/";
url = `http://${VUE_APP_API_URL}/sys/common/static` + pre + url;
console.log(url, "图片上传失败");
let url = data.message;
// console.log(url,'url')
// url = data.message.replaceAll("//", "/");
// const pre = url.startsWith("/") ? "" : "/";
// url = `http://${VUE_APP_API_URL}/sys/common/static` + pre + url;
// console.log(url, "图片上传成功");
obj.onSuccess({ success: true, message: url });
} else {
obj.onError({
success: false,
message: uploadRes.message || "图片上传失败",
message: data.message || "图片上传失败",
});
}
}
......
......@@ -3,7 +3,7 @@ import router from "../src/router";
import { useUserStore } from "./store/modules/user";
router.beforeEach((to: any, from: any, next: any) => {
const store = useUserStore();
const whiteList = ["/login", "/register"];
const whiteList = ["/login", "/register","/loging",'/home'];
if (store.userInfo.token) {
next();
} else {
......
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
import HomeView from "../views/HomeView.vue";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "home",
component: HomeView,
component: () =>
import(/* webpackChunkName: "about" */ "../views/HomeView.vue"),
},
{
path: "/login",
......
export type appType = {
sidebar:{
opened:boolean;
withoutAnimation: boolean;
isClickCollapse: boolean;
}
}
export type setType ={
path:string,
name:string,
query?:object
}
\ No newline at end of file
sidebar: {
opened: boolean;
withoutAnimation: boolean;
isClickCollapse: boolean;
};
};
export type setType = {
fontSzie: string;
width: string | number;
height?: string | number;
};
export type multiType = {
path: string;
name: string;
meta: any;
query?: object;
params?: object;
};
export type userType = {
username?: string;
roles?: Array<string>;
verifyCode?: string;
currentPage?: number;
isRemmembered?: boolean;
loginDay?: number;
};
export type oderType = {
object?: string;
};
......@@ -32,7 +32,7 @@ export const useUserStore = defineStore("user", {
return new Promise((resolve, reject) => {
const query = {
code: this.userInfo.username,
name:res.nickame
name:res?.nickame
};
console.log(query)
getUserList(query).then(({ success, result, message }: any) => {
......
......@@ -3,7 +3,11 @@
<el-container>
<el-aside width="280px" class="el-aside-left">
<el-header class="el-header-left">
<el-input placeholder="搜索" v-model="queryParams.nickame" @input="handleInput" />
<el-input
placeholder="搜索"
v-model="queryParams.nickame"
@input="handleInput"
/>
</el-header>
<div
active-text-color="#000"
......@@ -50,7 +54,11 @@
</div>
</div>
</el-aside>
<el-container class="el-container-center" v-if="currentInfo.username">
<el-container
v-isShrink="{ isShrink }"
class="el-container-center"
v-if="currentInfo.username"
>
<el-header class="el-header-center">
<p class="name">{{ currentInfo.nick }}</p>
<p class="url">
......@@ -192,121 +200,134 @@
</el-footer>
</el-container>
<el-container class="el-container-center" v-else></el-container>
<el-aside width="400px">
<div>
<el-header class="el-header-right">
<img src="../assets/xunjia.svg" alt="Avatar" />
<div class="name">询价单</div>
</el-header>
<div class="customer-info user-wrapper">
<div class="customer-info-right">
<div
class="customer-info-box"
v-for="(item, index) in inquiryInfo"
:key="index"
>
<div class="avatar-box">
<img :src="item.productImg" alt="Avatar" />
</div>
<div class="avatar-right">
<div>
<div class="avatar-right-name">
{{ item.name }}
</div>
<div class="avatar-right-price">
<div>{{ item.productPrice }}</div>
<div>{{ item.unit }}</div>
</div>
<el-aside
class="shirnk-aside"
width="400px"
v-shrink="{ isShrink, width: '0px' }"
>
<div style="width: 400px;">
<div class="shrink-text" @click="changeiShrink">
<el-icon size="30">
<DArrowLeft v-if="isShrink" />
<DArrowRight v-if="!isShrink" />
</el-icon>
</div>
<div>
<el-header class="el-header-right">
<img src="../assets/xunjia.svg" alt="Avatar" />
<div class="name">询价单</div>
</el-header>
<div class="customer-info user-wrapper">
<div class="customer-info-right">
<div
class="customer-info-box"
v-for="(item, index) in inquiryInfo"
:key="index"
>
<div class="avatar-box">
<img :src="item.productImg" alt="Avatar" />
</div>
<div class="avatar-input-box">
<div class="avatar-right">
<div>
<el-input-number
class="avatar-number-input"
:min="1"
v-model="item.count"
:max="10"
/>
<div class="avatar-right-name">
{{ item.name }}
</div>
<div class="avatar-right-price">
<div>{{ item.productPrice }}</div>
<div>{{ item.unit }}</div>
</div>
</div>
<div class="avatar-input-right">
<div class="change" @click="handleChange(item, index)">
更换
<div class="avatar-input-box">
<div>
<el-input-number
class="avatar-number-input"
:min="1"
v-model="item.count"
:max="10"
/>
</div>
<div class="delete" @click="handleDelete(item, index)">
删除
<div class="avatar-input-right">
<div class="change" @click="handleChange(item, index)">
更换
</div>
<div class="delete" @click="handleDelete(item, index)">
删除
</div>
</div>
</div>
</div>
</div>
<div class="add">
<img src="../assets/add-line.png" />
<div @click="handlerAdd(shopListRef)">添加</div>
</div>
</div>
<div class="add">
<img src="../assets/add-line.png" />
<div @click="handlerAdd(shopListRef)">添加</div>
<div class="form">
<el-form
ref="ruleFormRef"
style="max-width: 600px;"
:model="ruleForm"
:rules="rules"
label-position="top"
label-width="auto"
>
<el-form-item label="客户名称" prop="customerName">
<el-input
v-model="ruleForm.customerName"
placeholder="默认展示"
/>
</el-form-item>
<el-form-item label="国家/地区" prop="countriesRegions">
<el-input
v-model="ruleForm.countriesRegions"
placeholder="默认展示"
/>
</el-form-item>
<el-form-item label="Email" prop="Email">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.Email"
/>
</el-form-item>
<el-form-item label="WatchApp" prop="WatchApp">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.WatchApp"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.remark"
/>
</el-form-item>
<el-form-item
label="备注"
prop="content"
style="margin-bottom: 3px;"
>
<el-input
placeholder="文本内容"
v-model="ruleForm.content"
type="textarea"
:rows="8"
/>
</el-form-item>
</el-form>
</div>
</div>
<div class="form">
<el-form
ref="ruleFormRef"
style="max-width: 600px;"
:model="ruleForm"
:rules="rules"
label-position="top"
label-width="auto"
<el-footer class="footer-view">
<el-button
type="primary"
plain
style="width: 50px;"
@click.stop="sumbitFuleForm(ruleFormRef)"
>
<el-form-item label="客户名称" prop="customerName">
<el-input
v-model="ruleForm.customerName"
placeholder="默认展示"
/>
</el-form-item>
<el-form-item label="国家/地区" prop="countriesRegions">
<el-input
v-model="ruleForm.countriesRegions"
placeholder="默认展示"
/>
</el-form-item>
<el-form-item label="Email" prop="Email">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.Email"
/>
</el-form-item>
<el-form-item label="WatchApp" prop="WatchApp">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.WatchApp"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
placeholder="默认展示"
v-model.number="ruleForm.remark"
/>
</el-form-item>
<el-form-item
label="备注"
prop="content"
style="margin-bottom: 3px;"
>
<el-input
placeholder="文本内容"
v-model="ruleForm.content"
type="textarea"
:rows="8"
/>
</el-form-item>
</el-form>
</div>
发送
</el-button>
</el-footer>
</div>
<el-footer class="footer-view">
<el-button
type="primary"
plain
style="width: 50px;"
@click.stop="sumbitFuleForm(ruleFormRef)"
>
发送
</el-button>
</el-footer>
</div>
</el-aside>
</el-container>
......@@ -388,6 +409,12 @@ let currentInfo = ref({
messages: [],
username: '',
})
let isShrink = ref('')
const defaultStyle: {
transition?: string
} = {
transition: 'all 0.6s linear',
}
let queryParams = ref({})
const connectMsg = () => {
// const useUser = useUserStore()
......@@ -401,7 +428,8 @@ const connectMsg = () => {
onMounted(() => {
connectMsg()
})
const getUserList = (queryParams:any) => {
const getUserList = (queryParams: any) => {
getUseUserStore.setUserListMessages(queryParams).then((res: any) => {
list.value = getUseUserStore.userList
})
......@@ -415,6 +443,9 @@ const isSelf = computed(() => {
return getUseUserStore.userInfo.username == e.fromCode
}
})
const changeiShrink = () => {
isShrink.value = !isShrink.value
}
//获取子组件中state的值,这个好像是写多余了,可以直接使用automaticPromptRef.value.setState('');获取state值
const getState = (v: string) => {
msg = v
......@@ -541,7 +572,6 @@ const handleDelete = (item, index) => {
//提交询价单
const sumbitFuleForm = (formEl: FormInstance | undefined) => {
console.log('sumbitFuleForm', formEl)
if (!formEl) return
formEl.validate(async (valid: boolean) => {
if (valid) {
......@@ -575,6 +605,50 @@ const getMessageClass = (message: any) => {
const getMenuItem = (item: any) => {
return item.username == currentInfo.value?.username ? 'is-active' : ''
}
//收缩
const vShrink: Directive<HTMLElement, boolean | Props> = {
mounted(el, binding) {
console.log(el, binding, '打印')
let { option } = formatCOlorOption(binding.value)
option.isUpdate && renderStyle(el, option)
},
updated(el: HTMLElement, binding, vnode) {
//修改之后
let { option } = formatCOlorOption(binding.value)
if (option.isShrink) {
renderStyle(el, option)
//此时此刻还需要添加一个p对象
// renderAddNodes(el, option)
} else {
let obj = {
...option,
width: '400px',
}
// for (let key in option) obj[key] = ''
renderStyle(el, obj)
//此时此刻需要清空对象p
// renderAddNodes(el, option)
}
},
}
//设置style的属性值
function renderStyle(el, option) {
for (let key in option) el.style[key] = option[key]
}
//合并指令传递的数据和默认配置的数据
function formatCOlorOption(val: string | Props) {
const option =
typeof val !== 'string'
? Object.assign(defaultStyle, val)
: {
val,
...defaultStyle,
}
return {
option,
}
}
//点击消息框中的文字或者图片
const handleMessageClick = (event: any) => {
const target = event.target
if (target.tagName === 'A') {
......@@ -602,6 +676,7 @@ const handleMessageClick = (event: any) => {
const handleLinkClick = (msg: string) => {
messages.value.push({ content: msg, isSent: true })
}
//选择商品确认之后的数据
const selectionChange = (arr: any) => {
inquiryInfo.value = arr.map((item) => {
item.count = 1
......@@ -610,6 +685,21 @@ const selectionChange = (arr: any) => {
}
</script>
<style lang="scss" scoped>
.shirnk-aside {
position: relative;
overflow: hidden;
overflow: initial;
.shrink-text {
position: absolute;
top: 50%;
transform: translate(-50%);
width: 20px;
height: 20px;
left: -20px;
font-size: 10px;
}
}
.inquiry-list {
background: #fff;
display: flex;
......@@ -962,8 +1052,7 @@ const selectionChange = (arr: any) => {
.el-input__wrapper {
width: 48px;
}
.query{
.query {
}
.avatar-input-box {
:deep(.el-input-number__increase),
......
......@@ -25,7 +25,7 @@
placeholder="请输入密码"
/>
</el-form-item>
<el-form-item style="margin: 0px;">
<el-form-item style="margin: 0px;justify-content: space-between;">
<el-button
class="login-submit"
type="primary"
......@@ -33,7 +33,7 @@
>
登录
</el-button>
<el-button class="login-reset" @click="resetForm(ruleFormRef)">
<el-button class="login-reset" type="primary" @click="resetForm(ruleFormRef)">
重置
</el-button>
</el-form-item>
......@@ -140,22 +140,39 @@ export default {
background: url('../assets/login.jpg') no-repeat;
background-size: 100%;
.form-box {
background: #fff;
.el-input__inner {
color: #fff;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(16px);
.el-form-item{
display: flex;
align-items: center;
margin-bottom: 24px;
}
:deep(.el-form-item__label){
color: #fff;
}
:deep(.el-input__wrapper) {
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
:deep(.el-input__inner) {
height: 40px;
color: #fff;
border-bottom: 2px solid #fff;
}
h2 {
text-align: center;
margin-bottom: 40px;
margin-bottom: 20px;
font-weight: bolder;
font-size: 20px;
}
margin: 0px auto;
margin-top: 250px;
width: 500px;
width: 800px;
text-align: center;
border-radius: 20px;
padding: 40px;
padding:30px 40px 30px 40px;
box-shadow: 0px 1px 5px 0 rgba(0, 0, 0, 0.3);
.login-submit,
.login-reset {
......
<script setup lang="ts">
import { Directive, VNode, h, ref, render } from 'vue';
import Loading from '@/components/loging/logingComponent.vue';
const defaultOption: {msg?: string | false} = {
msg: '努力加载中'
}
interface Props {loading: boolean, msg?: string | false}
function formatOption (value: boolean | Props) {
const loading = typeof value === 'boolean'
? value
: value.loading
const option = typeof value !== 'boolean'
? Object.assign(defaultOption, value)
: {
loading,
...defaultOption
}
return { loading, option }
import { Directive, VNode, h, ref, render, functions } from 'vue'
import { appType, setType, multiType, userType, oderType } from '@/store/index'
const defaultStyle: {
fontSzie?: string
width?: string | number
height?: string | number
} = {
fontSzie: '24px',
width: '100px',
height: '100px',
}
function renderLoading (el: HTMLElement, option: Props) {
const vnode = h(
Loading,
{ id: 'loading', ...option}
)
el.removeChild(el.children[0])
render(vnode, el)
}
function renderVNode (el: HTMLElement, vnode: VNode) {
el.querySelector('#loading')?.remove()
render(vnode, el)
interface Props {
loading: boolean
msg?: string | false
}
const vLoading: Directive<HTMLElement, boolean | Props> = {
const isUpdate = ref(false)
console.log(isUpdate, '打印')
const vColor: Directive<HTMLElement, boolean | Props> = {
mounted(el, binding) {
const { loading, option } = formatOption(binding.value)
loading && renderLoading(el, option)
let { option } = formatCOlorOption(binding.value)
option.isUpdate && renderStyle(el, option)
},
updated(el: HTMLElement, binding, vnode) {
const { loading, option } = formatOption(binding.value)
if (loading) {
renderLoading(el, option)
//修改之后
let { option } = formatCOlorOption(binding.value)
if (option.isUpdate) {
renderStyle(el, option)
//此时此刻还需要添加一个p对象
renderAddNodes(el, option)
} else {
renderVNode(el, vnode)
let obj = {}
for (let key in option) obj[key] = ''
renderStyle(el, obj)
//此时此刻需要清空对象p
renderAddNodes(el, option)
}
},
}
const loading = ref(true)
setTimeout(() => loading.value = false, 2000)
function renderStyle(el, option) {
for (let key in option) el.style[key] = option[key]
}
function renderAddNodes(el, option) {
if (option.isUpdate) {
var node = h(
'p',
{ id: 'p1', style: option, class: 'my-p' },
'我是添加进来的p',
)
render(node, el)
} else {
el.removeChild(el.children[1])
}
}
function formatCOlorOption(val: string | Props) {
const option =
typeof val !== 'string'
? Object.assign(defaultStyle, val)
: {
val,
...defaultStyle,
}
return {
option,
}
}
function changeColor() {
isUpdate.value = isUpdate.value ? false : true
}
</script>
<template>
<div style="width: 300px" v-loading="{ loading, msg: '一大波僵尸来袭' }">
<h1>加载成功</h1>
<div>
<div
style="width: 300px;"
v-color="{ isUpdate, color: 'blue', background: 'red' }"
>
<h1>这是一段考验direactive的描述</h1>
</div>
<el-button @click="changeColor">点击修改颜色</el-button>
</div>
</template>
\ No newline at end of file
</template>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论