提交 9ce4221f 作者: Hao

拉取最新代码

父级 cc9b12b0
NODE_ENV=development
VITE_USER_APP_API_URL=192.168.31.135
\ No newline at end of file
NODE_ENV=production
VITE_USER_APP_API_URL=192.168.31.101
\ No newline at end of file
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
"type": "module", "type": "module",
"license":"MIT", "license":"MIT",
"scripts": { "scripts": {
"build": "vue-tsc --noEmit && vite build", "build": "vue-tsc --noEmit && vite build --mode production",
"serve": "vite", "serve": "vite --mode development",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
......
No preview for this file type
// axios.js // axios.js
import axios from "axios"; import axios from "axios";
let VUE_APP_API_URL = import.meta.env.VITE_USER_APP_API_URL;
const instance = axios.create({ const instance = axios.create({
baseURL: "http://192.168.31.123:8080", // 设置基础 URL baseURL: `http://${VUE_APP_API_URL}:8080`, // 设置基础 URL
// baseURL:'/api', // baseURL:'/api',
timeout: 1000, // 设置请求超时时间 timeout: 1000, // 设置请求超时时间
}); });
console.log(import.meta.env, "import.meta.env");
instance.interceptors.request.use( instance.interceptors.request.use(
(config: any) => { (config: any) => {
// 在发送请求之前做些什么,例如添加 token // 在发送请求之前做些什么,例如添加 token
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
if (token) { if (token) {
config.headers['X-Access-Token'] = `Bearer ${token}`; config.headers["X-Access-Token"] = `Bearer ${token}`;
} }
return config; return config;
}, },
...@@ -27,6 +28,7 @@ instance.interceptors.response.use( ...@@ -27,6 +28,7 @@ instance.interceptors.response.use(
}, },
(error: any) => { (error: any) => {
// 对响应错误做点什么 // 对响应错误做点什么
console.log(error);
return Promise.reject(error); return Promise.reject(error);
} }
); );
......
...@@ -44,7 +44,7 @@ const checkMesssages = (query: any) => { ...@@ -44,7 +44,7 @@ const checkMesssages = (query: any) => {
const getUploadConfigInfo = (query: any) => { const getUploadConfigInfo = (query: any) => {
return http({ return http({
url: "/getUploadConfigInfo", url: "/upload/getUploadConfigInfo",
method: "get", method: "get",
data: query, data: query,
}); });
...@@ -53,7 +53,7 @@ const getUploadConfigInfo = (query: any) => { ...@@ -53,7 +53,7 @@ const getUploadConfigInfo = (query: any) => {
const upload = (query: any) => { const upload = (query: any) => {
return http({ return http({
url: "/sys/common/upload", url: "/sys/common/upload",
method: "get", method: "post",
data: query, data: query,
}); });
}; };
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
ref="elAutocomplete" ref="elAutocomplete"
placeholder="输入信息" placeholder="输入信息"
contenteditable="true" contenteditable="true"
style="outline: none; height: 100%;" style="outline: none; "
@paste.prevent="handlePaste" @paste.prevent="handlePaste"
@focus="removeDefaultContent" @focus="removeDefaultContent"
@input="handleSelect" @input="handleSelect"
...@@ -59,7 +59,6 @@ ...@@ -59,7 +59,6 @@
/> />
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import emotion from './IndexComponent.vue' import emotion from './IndexComponent.vue'
import { ElLoading } from 'element-plus' import { ElLoading } from 'element-plus'
...@@ -97,6 +96,7 @@ const fileChange = () => { ...@@ -97,6 +96,7 @@ const fileChange = () => {
const handleSelect = (value: any) => { const handleSelect = (value: any) => {
inputVal.value = value.target.innerHTML inputVal.value = value.target.innerHTML
console.log(inputVal.value,'打印一下')
} }
const emit = defineEmits(['updateState']) const emit = defineEmits(['updateState'])
...@@ -223,7 +223,7 @@ defineExpose({ ...@@ -223,7 +223,7 @@ defineExpose({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.auto-prompt { .auto-prompt {
padding: 20px; padding: 12px 28px;
} }
.textarea { .textarea {
&:after { &:after {
...@@ -236,8 +236,8 @@ defineExpose({ ...@@ -236,8 +236,8 @@ defineExpose({
} }
} }
.icon { .icon {
width: 24px; width: 20px;
height: 24px; height: 20px;
margin-right: 32px; margin-right: 32px;
} }
.chat-bar { .chat-bar {
...@@ -249,7 +249,7 @@ defineExpose({ ...@@ -249,7 +249,7 @@ defineExpose({
.el-autocomplete { .el-autocomplete {
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
max-height: 150px; height: calc(100vh - 732px);
overflow: auto; overflow: auto;
} }
.el-autocomplete img { .el-autocomplete img {
......
...@@ -7,7 +7,7 @@ import "./assets/css/reset.css"; ...@@ -7,7 +7,7 @@ import "./assets/css/reset.css";
import * as ElementPlusIconsVue from "@element-plus/icons-vue"; import * as ElementPlusIconsVue from "@element-plus/icons-vue";
import translate from "i18n-jsautotranslate"; import translate from "i18n-jsautotranslate";
import UUID from "vue3-uuid"; import UUID from "vue3-uuid";
import "@/permission"; // permission control import "@/permission";
import "element-plus/dist/index.css"; import "element-plus/dist/index.css";
import "./mocks/mock"; import "./mocks/mock";
const app = createApp(App); const app = createApp(App);
......
import { reactive, watch, ref, defineEmits, defineExpose } from "vue"; import { reactive, watch, ref, defineEmits, defineExpose } from "vue";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { upload, getUploadConfigInfo } from "../axios/model/user"; import { upload, getUploadConfigInfo } from "../axios/model/user";
import axios from "axios";
import COS from "cos-js-sdk-v5"; import COS from "cos-js-sdk-v5";
interface UploadMixin { interface UploadMixin {
uploadMixinPath: string; uploadMixinPath: string;
uploadMixinType: string; uploadMixinType: string;
uploadMixinCredentials: any; uploadMixinCredentials: any;
uploadMixinTimeStamp: number; uploadMixinTimeStamp: number;
upLoadMixinResult: object;
} }
const uploadMixin: UploadMixin = { const uploadMixin: UploadMixin = {
uploadMixinPath: "", uploadMixinPath: "",
uploadMixinType: "", uploadMixinType: "",
uploadMixinCredentials: {}, uploadMixinCredentials: {},
uploadMixinTimeStamp: 0, uploadMixinTimeStamp: 0,
upLoadMixinResult: {},
}; };
interface CustomAxiosResponse { interface CustomAxiosResponse {
code: number; code: number;
...@@ -89,23 +92,28 @@ export const upLoadHander = async (obj: any) => { ...@@ -89,23 +92,28 @@ export const upLoadHander = async (obj: any) => {
//noCredentials变量控制是否走对象存储 //noCredentials变量控制是否走对象存储
if (noCredentials) { if (noCredentials) {
const query = {}; const query = {};
const res:any = await getUploadConfigInfo(query); const res: any = await getUploadConfigInfo(query);
// console.log(res1,'res')
// console.log(res);
if (res.code === 200 && res.result) { if (res.code === 200 && res.result) {
const result = res.result; const result = res.result;
uploadMixin.uploadMixinPath = result.upLoadPath; uploadMixin.uploadMixinPath = result.upLoadPath;
uploadMixin.uploadMixinType = result.uploadType; uploadMixin.uploadMixinType = result.uploadType;
staticDomain = result.staticDomain || "https://cdn.tikcos.cn"; staticDomain = result.staticDomain || "https://cdn.tikcos.cn";
if (uploadMixin.uploadMixinType === "txcos") { if (uploadMixin.uploadMixinType === "txcos") {
const credentials = result.credentials; console.log(result.response, " result.response");
const ress = res.result.response;
const credentials = ress.credentials;
uploadMixin.uploadMixinCredentials = { uploadMixin.uploadMixinCredentials = {
TmpSecretId: credentials?.tmpSecretId, TmpSecretId: credentials?.tmpSecretId,
TmpSecretKey: credentials?.tmpSecretKey, TmpSecretKey: credentials?.tmpSecretKey,
SecurityToken: credentials?.sessionToken, SecurityToken: credentials?.sessionToken,
StartTime: result.startTime, StartTime: ress?.startTime,
ExpiredTime: result.expiredTime, ExpiredTime: ress?.expiredTime,
}; };
console.log(result, "result");
console.log(
uploadMixin.uploadMixinCredentials,
" uploadMixin.uploadMixinCredentials"
);
} }
} else { } else {
resResult = false; resResult = false;
...@@ -114,51 +122,84 @@ export const upLoadHander = async (obj: any) => { ...@@ -114,51 +122,84 @@ export const upLoadHander = async (obj: any) => {
//resResult判断接口是否正常 //resResult判断接口是否正常
if (resResult) { if (resResult) {
const query = {}; const query = {};
const res:any = await getUploadConfigInfo(query); // const res: any = await getUploadConfigInfo(query);
if (uploadMixin.uploadMixinType == "txcos") { console.log(
uploadMixin.uploadMixinCredentials,
" console.log(uploadMixin.uploadMixinCredentials)"
);
const result: any = uploadMixin.upLoadMixinResult;
if (uploadMixin.uploadMixinType === "txcos") {
//走对象存储 //走对象存储
const cos = new COS({ const cos = new COS({
getAuthorization: (options: any, callback: any) => { getAuthorization: (options, callback) => {
callback(uploadMixin.uploadMixinCredentials); callback(uploadMixin.uploadMixinCredentials);
}, },
}); });
const tempFolder = fileInfo.biz === "temp" ? "" : `${fileInfo.biz}/`; const tempFolder = fileInfo.biz === "temp" ? "" : `${fileInfo.biz}/`;
const folder = `${fileInfo.fileName}_${new Date().getTime()}.${ const folder = `${fileInfo.fileName}_${new Date().getTime()}.${
fileInfo.fileTyle fileInfo.fileTyle
}`; }`;
const result = res.result || {};
cos.putObject( cos.putObject(
{ {
// FilePath: fileInfo.file,
Bucket: result.bucketName || "tikcos-1257774783", Bucket: result.bucketName || "tikcos-1257774783",
Region: result.regionid || "ap-guangzhou", Region: result.regionid || "ap-guangzhou",
Key: uploadMixin.uploadMixinPath + tempFolder + folder, Key: uploadMixin.uploadMixinPath + tempFolder + folder,
Body: fileInfo.file, Body: fileInfo.file,
onProgress: function (progressData: any) { onProgress: function (progressData) {
obj.onProgress && obj.onProgress(progressData); console.log(progressData, "ada");
obj.onProgress(progressData);
}, },
}, },
async (err: any, data: any) => { (err, data) => {
console.log(err, data, "打印一下");
console.log({ success: true });
console.log(
`${staticDomain}/${uploadMixin.uploadMixinPath}${tempFolder}${folder}`,
"打印一下,数据"
);
if (!err && data.statusCode === 200) { if (!err && data.statusCode === 200) {
const imgurl = `${staticDomain}/${uploadMixin.uploadMixinPath}${tempFolder}${folder}`; const imgurl = `${staticDomain}/${uploadMixin.uploadMixinPath}${tempFolder}${folder}`;
obj.onSuccess({
success: true, obj.onSuccess({ success: true, message: imgurl });
message: imgurl,
});
} else { } else {
obj.onError({ obj.onError({ success: false, message: err || "图片上传失败" });
success: false,
message: data.message || "图片上传失败",
});
} }
} }
); );
} else { } else {
// 其他存储类型暂不支持 //走系统上传
obj.onError({ let VUE_APP_API_URL = import.meta.env.VITE_USER_APP_API_URL;
success: false, let newFile = fileInfo.file;
message: "服务接口报错", if (/[\u4e00-\u9fa5]/.test(newFile.name)) {
}); const folder = newFile.name.replace(/[\u4e00-\u9fa5]{1,}/g, "_");
newFile = new File([newFile], folder, { type: newFile.type });
}
let formData = new FormData();
formData.append("biz", fileInfo.biz);
formData.append("file", newFile);
const uploadRes = await axios.post(`http://${VUE_APP_API_URL}:8080/sys/common/upload`,
formData,
{
headers: { ...obj.headers },
processData: false,
contentType: false,
async: false,
}
);
if (uploadRes.success && uploadRes.message) {
//保存绝对路径,不然小程序会有问题
let url = uploadRes.message;
url = uploadRes.message.replaceAll("//", "/");
const pre = url.startsWith("/") ? "" : "/";
url = `http://${VUE_APP_API_URL}/sys/common/static` + pre + url;
obj.onSuccess({ success: true, message: url });
} else {
obj.onError({
success: false,
message: uploadRes.message || "图片上传失败",
});
}
} }
} else { } else {
obj.onError({ obj.onError({
......
...@@ -14,7 +14,6 @@ export const useUserStore = defineStore("user", { ...@@ -14,7 +14,6 @@ export const useUserStore = defineStore("user", {
password: "", password: "",
token: "", token: "",
}, },
// userList: [],
}; };
}, },
actions: { actions: {
...@@ -37,9 +36,8 @@ export const useUserStore = defineStore("user", { ...@@ -37,9 +36,8 @@ export const useUserStore = defineStore("user", {
to: res.to, to: res.to,
id: res.id, id: res.id,
form: res.from, form: res.from,
userImg: userImg:"https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png",
"https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png", time: moment(res.createTime).format("HH:mm:ss"),
time: moment(res.createTime).format("YYYY-DD-MM HH:mm:ss"),
}; };
messages.push(obj); messages.push(obj);
this.customerInfo.messages = messages; this.customerInfo.messages = messages;
...@@ -51,7 +49,7 @@ export const useUserStore = defineStore("user", { ...@@ -51,7 +49,7 @@ export const useUserStore = defineStore("user", {
chatDatas.forEach((item: any) => { chatDatas.forEach((item: any) => {
item.userImg = item.userImg =
"https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png"; "https://cdn.lirimall.com//lirigo/filetempImage/新鲜水果_1661668973048.png";
item.time = moment(res.createTime).format("YYYY-DD-MM HH:mm:ss"); item.time = moment(res.createTime).format("HH:mm:ss");
}); });
for (const index in chatDatas) { for (const index in chatDatas) {
const userId = chatDatas[index].from; const userId = chatDatas[index].from;
......
...@@ -11,13 +11,21 @@ ...@@ -11,13 +11,21 @@
id="srollId" id="srollId"
ref="srollId" ref="srollId"
:style="{ :style="{
padding: '24px', padding: '0px 24px',
height: '60vh', height: '60vh',
width: '100%', width: '100%',
}" }"
> >
<div class="title-message">You have no history messages</div> <div class="title-message">You have no history messages</div>
<div class="message-container message-container-right"> <div class="we-connecting">
We are connecting you to online customer service
</div>
<!-- 推荐商品 -->
<div
class="message-container message-container-right"
v-if="productInfo.isShow"
>
<div class="classSendLink"> <div class="classSendLink">
<div class="classSendDiv"> <div class="classSendDiv">
<div class="classSend-img"> <div class="classSend-img">
...@@ -35,13 +43,39 @@ ...@@ -35,13 +43,39 @@
</div> </div>
</div> </div>
</div> </div>
<div class="sendlinkbox" @click="toSendLink(productInfo)"> <div class="sendlinkbox">
<div class="box-send">send link</div> <div class="box-send" @click="toSendLink(productInfo)">
<div class="box-close">Close</div> send link
</div>
<div class="box-close" @click="toCloseLink(productInfo)">
Close
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- -->
<div class="message-container message-container-left">
<div class="avatar">
<img
:src="require('../assets/camera.png')"
class="avatar-image"
/>
</div>
<div class="bubble official-box">
<div class="bubble-title">You may want to know</div>
<a class="bubble-h1">
How to open the product multi-picture function ?
</a>
<a class="bubble-h1">
How to release more products and get traffic ?
</a>
</div>
</div>
<div v-for="(message, index) in messages" :key="index"> <div v-for="(message, index) in messages" :key="index">
<div class="message-time" v-if="message.time == 1">
{{ message.time }}
</div>
<!-- 发送的推荐商品 -->
<div <div
class="message-container message-container-right" class="message-container message-container-right"
v-if="message.msgType == 3" v-if="message.msgType == 3"
...@@ -70,12 +104,12 @@ ...@@ -70,12 +104,12 @@
</div> --> </div> -->
</div> </div>
</div> </div>
<!-- 普通聊天 -->
<div <div
v-else v-if="message?.msgType == 0"
class="message-container" class="message-container"
:class="getMessageClass(message?.isSent)" :class="getMessageClass(message?.isSent)"
> >
<div class="time">{{ message.time }}</div>
<div v-if="message.isSent" class="message-container"> <div v-if="message.isSent" class="message-container">
<div class="bubble"> <div class="bubble">
<!--文字 --> <!--文字 -->
...@@ -92,18 +126,18 @@ ...@@ -92,18 +126,18 @@
/> />
</div> </div>
</div> </div>
<div class="avatar"> <!-- <div class="avatar">
<img <img
src="../assets/shop.jpg" src="../assets/shop.jpg"
alt="Avatar" alt="Avatar"
class="avatar-image" class="avatar-image"
/> /> -->
</div> <!-- </div> -->
</div> </div>
<div v-if="!message.isSent" class="message-container"> <div v-if="!message.isSent" class="message-container">
<div class="avatar"> <!-- <div class="avatar">
<img :src="message?.userImg" class="avatar-image" /> <img :src="message?.userImg" class="avatar-image" />
</div> </div> -->
<div class="bubble"> <div class="bubble">
<div <div
v-if="message?.msgType == 0" v-if="message?.msgType == 0"
...@@ -120,10 +154,45 @@ ...@@ -120,10 +154,45 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 询价单 -->
<div
class="message-container message-container-right"
v-if="message.msgType == 4"
>
<div class="inquiry-list">
<div class="inquiry-top">
<div class="product-left">
<div class="product-category">
{{ message.content.purchaseQuantity }}
</div>
<div class="product-name">
{{ message.content.ProductName }}
</div>
</div>
<div>
<div class="product-count">
{{ message.content.price }}
</div>
<div class="from-china">
{{ message.content.EmailAddress }}
</div>
</div>
</div>
<div class="product-info">
{{ message.content.otherRequirements }}
</div>
<div class="design-requirements">
<div>{{ message.content.flieName }}</div>
<div class="img">
<img :src="require('../assets/icon_download.png')" />
</div>
</div>
</div>
</div>
</div> </div>
</el-main> </el-main>
<el-footer class="el-footer" :style="{ border: '1px solid #E9ECF1' }"> <el-footer class="el-footer" :style="{ border: '1px solid #E9ECF1' }">
<div class="static-box"> <!-- <div class="static-box">
<div <div
v-for="(item, index) in staticList" v-for="(item, index) in staticList"
:key="index" :key="index"
...@@ -131,7 +200,7 @@ ...@@ -131,7 +200,7 @@
> >
<div>{{ item }}</div> <div>{{ item }}</div>
</div> </div>
</div> </div> -->
<AutomaticPrompt <AutomaticPrompt
@keydown.enter="handleButtonClick" @keydown.enter="handleButtonClick"
@updateState="getState" @updateState="getState"
...@@ -141,31 +210,32 @@ ...@@ -141,31 +210,32 @@
<div>[ Send shortcut key: Enter ]</div> <div>[ Send shortcut key: Enter ]</div>
<div> <div>
<el-button <el-button
plain style="
style="width: 50px; background: #f8f8fa; color: #000;" width: 80px;
@click.stop="handleButtonClick" height: 32px;
> color: #fff;
Finish font-family: 'PingFang SC';
</el-button> font-size: 16px;
<el-button background: #000;
style="width: 50px; color: #fff; background: #000;" "
plain plain
@click.stop="handleButtonClick" @click.stop="handleButtonClick"
> >
send Send
</el-button> </el-button>
</div> </div>
</div> </div>
</el-footer> </el-footer>
</el-container> </el-container>
<el-aside <el-aside
v-if="num == 1" v-if="pageType == 1"
width="292px" width="292px"
:style="{ :style="{
height: 'calc(100vh - 60px)', height: 'calc(100vh - 60px)',
}" }"
> >
<div class="recentlyViewd">最近浏览</div> <div class="recentlyViewd">Browsing history</div>
<div class="Recommended">Recommended products</div>
<div <div
v-for="(item, index) in productList" v-for="(item, index) in productList"
:key="index" :key="index"
...@@ -185,7 +255,7 @@ ...@@ -185,7 +255,7 @@
</el-aside> </el-aside>
<el-aside <el-aside
width="292px" width="292px"
v-if="num == 2" v-if="pageType == 2"
:style="{ :style="{
height: 'calc(100vh - 60px)', height: 'calc(100vh - 60px)',
}" }"
...@@ -209,7 +279,7 @@ ...@@ -209,7 +279,7 @@
prop="Email" prop="Email"
/> />
</el-form-item> </el-form-item>
<el-form-item prop="Email" label="Purchase Quantity"> <el-form-item prop="Email" label="Product Category">
<el-select <el-select
placeholder="Select" placeholder="Select"
prop="Email" prop="Email"
...@@ -221,14 +291,11 @@ ...@@ -221,14 +291,11 @@
<el-option label="Tel" value="3" /> <el-option label="Tel" value="3" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item <el-form-item prop="purchaseQuantity" label="Purchase Quantity">
prop="explanation"
label="Other requirements explanation"
>
<el-input <el-input
style="max-width: 600px; height: 36px;" style="max-width: 600px; height: 36px;"
placeholder="Please enter" placeholder="Please enter"
v-model="ruleForm.explanation" v-model="ruleForm.purchaseQuantity"
class="input-with-select" class="input-with-select"
prop="Email" prop="Email"
> >
...@@ -248,10 +315,10 @@ ...@@ -248,10 +315,10 @@
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="Other requirements explanation" label="Other requirements explanation"
prop="explanation" prop="otherRequirements"
> >
<el-input <el-input
v-model="ruleForm.explanation" v-model="ruleForm.otherRequirements"
:autosize="{ minRows: 3, maxRows: 10 }" :autosize="{ minRows: 3, maxRows: 10 }"
type="textarea" type="textarea"
placeholder="Please enter" placeholder="Please enter"
...@@ -267,7 +334,7 @@ ...@@ -267,7 +334,7 @@
</div> </div>
<div class="requirements-box1" v-if="isUpload"> <div class="requirements-box1" v-if="isUpload">
<div class="box"> <div class="box">
<div class="upload-name">Tech design requirements.pdf</div> <div class="upload-name">{{ ruleForm.flieName }}</div>
<div class="upload-info"> <div class="upload-info">
<el-icon color="green"><CircleCheck /></el-icon> <el-icon color="green"><CircleCheck /></el-icon>
<span>200KB</span> <span>200KB</span>
...@@ -277,9 +344,15 @@ ...@@ -277,9 +344,15 @@
</div> </div>
</el-form-item> </el-form-item>
<el-form-item prop="EmailAddress" label="Email Address"> <el-form-item prop="EmailAddress" label="Email Address">
<el-input style="height: 44px;" placeholder="Please enter" v-model="ruleForm.EmailAddress" /> <el-input
style="height: 36px;"
placeholder="Please enter"
v-model="ruleForm.EmailAddress"
/>
</el-form-item> </el-form-item>
<div class="footerSubmit">Submit</div> <div class="footerSubmit" @click="submitForm(ruleForm)">
Submit
</div>
</el-form> </el-form>
</div> </div>
</el-aside> </el-aside>
...@@ -290,16 +363,9 @@ ...@@ -290,16 +363,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import '../assets/font/iconfont.css' import '../assets/font/iconfont.css'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import moment from 'moment'
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { import { ref, onMounted, watch, nextTick, reactive } from 'vue'
ref,
onMounted,
watch,
nextTick,
getCurrentInstance,
reactive,
} from 'vue'
import { getShortDate } from '../utils/index'
import { useUserStore } from '../store/modules/user' import { useUserStore } from '../store/modules/user'
import AutomaticPrompt from '../components/AutomaticPrompt.vue' import AutomaticPrompt from '../components/AutomaticPrompt.vue'
import ImageViewer from '@luohc92/vue3-image-viewer' import ImageViewer from '@luohc92/vue3-image-viewer'
...@@ -308,10 +374,22 @@ import { initWebSocket } from '../utils/websocket' ...@@ -308,10 +374,22 @@ import { initWebSocket } from '../utils/websocket'
import '@luohc92/vue3-image-viewer/dist/style.css' import '@luohc92/vue3-image-viewer/dist/style.css'
import { checkMesssages } from '../axios/model/user' import { checkMesssages } from '../axios/model/user'
import { require } from '@/utils/index' import { require } from '@/utils/index'
import { useRoute } from 'vue-router'
const route = useRoute()
const routeParams = route.query
const pageType = routeParams.type || 1
const ruleForm = ref({ const ruleForm = ref({
count: 1, ProductName: 'Product Name',
Email: '1143572217@qq.com',
purchaseQuantity: 'Product Category',
China: '',
price: 5000,
flieName: 'Tech design requirements.pdf',
otherRequirements:
'Other requirements explanation Other requirements explanation Other requirements explanation Other requirements explanation Other requirements explanation',
EmailAddress: 'from china',
}) })
const rules = reactive({ const rules = reactive({
ProductName: [ ProductName: [
{ {
...@@ -352,21 +430,23 @@ const rules = reactive({ ...@@ -352,21 +430,23 @@ const rules = reactive({
const ruleFormRef = ref<FormInstance>() const ruleFormRef = ref<FormInstance>()
const customerInfo = ref({}) const customerInfo = ref({})
const messages = ref([]) const messages = ref([])
const num = 2
const isUpload = true const isUpload = true
const staticList = ref([ // const staticList = ref([
'Login account', // 'Login account',
'Forgot password', // 'Forgot password',
'Free entry', // 'Free entry',
'Add/manage products', // 'Add/manage products',
'improve', // 'improve',
]) // ])
const productInfo = ref({ const productInfo = ref({
productImg: require('../assets/shop.jpg'), productImg: require('../assets/shop.jpg'),
productName: 'The secret to looking glowup nowadays', productName: 'The secret to looking glowup nowadays',
price: '$1.40 - 2.50', price: '$1.40 - 2.50',
link: 'send', link: 'send',
isShow: true,
}) })
const productList = ref([ const productList = ref([
{ {
productImg: require('../assets/camera.png'), productImg: require('../assets/camera.png'),
...@@ -399,11 +479,13 @@ onMounted(async () => { ...@@ -399,11 +479,13 @@ onMounted(async () => {
}) })
const connectMsg = () => { const connectMsg = () => {
return new Promise((resolve: any, reject: any) => { return new Promise((resolve: any, reject: any) => {
// console.log(import)
const useUser = useUserStore() const useUser = useUserStore()
useUser.setUserInfo({ useUser.setUserInfo({
username: Date.now(), username: Date.now(),
}) })
const toIp = `ws://192.168.31.123:8081?type=yk&code=${useUser.userInfo.username}&kf=${store.customerInfo.username}` let VUE_APP_API_URL = import.meta.env.VITE_USER_APP_API_URL
const toIp = `ws://${VUE_APP_API_URL}:8081?type=yk&code=${useUser.userInfo.username}&kf=${store.customerInfo.username}`
useUser.connect() useUser.connect()
initWebSocket(toIp) initWebSocket(toIp)
setTimeout(() => { setTimeout(() => {
...@@ -450,7 +532,7 @@ const setSrollHeight = () => { ...@@ -450,7 +532,7 @@ const setSrollHeight = () => {
//发送按钮 //发送按钮
const handleButtonClick = () => { const handleButtonClick = () => {
if (!msg) { if (!msg.trim()) {
return ElMessage({ return ElMessage({
message: '请输入内容', message: '请输入内容',
type: 'error', type: 'error',
...@@ -465,7 +547,7 @@ const handleButtonClick = () => { ...@@ -465,7 +547,7 @@ const handleButtonClick = () => {
fromLang: 'cn', fromLang: 'cn',
toLang: 'en', toLang: 'en',
group_id: '', group_id: '',
time: getShortDate(), time: moment(new Date()).format('HH:mm:ss'),
to: customerInfo.value.username, to: customerInfo.value.username,
form: store.userInfo.username, form: store.userInfo.username,
} }
...@@ -473,7 +555,29 @@ const handleButtonClick = () => { ...@@ -473,7 +555,29 @@ const handleButtonClick = () => {
sendWebSocket(data) sendWebSocket(data)
automaticPromptRef.value.setState('') automaticPromptRef.value.setState('')
} }
//关闭商品弹窗
const toCloseLink = () => {
productInfo.value.isShow = false
}
//发布询价单
const submitForm = (e) => {
const data = {
content: e,
isSent: true,
cmd: '11',
msgType: 4,
chatType: '2',
fromLang: 'cn',
toLang: 'en',
group_id: '',
time: moment(new Date()).format('HH:mm:ss'),
to: customerInfo.value.username,
form: store.userInfo.username,
}
messages.value?.push(data)
sendWebSocket(data)
}
const handleMessageClick = (event: any) => { const handleMessageClick = (event: any) => {
const target = event.target const target = event.target
if (target.tagName === 'A') { if (target.tagName === 'A') {
...@@ -517,6 +621,7 @@ const handleLinkClick = (msg: string) => { ...@@ -517,6 +621,7 @@ const handleLinkClick = (msg: string) => {
const getMessageClass = (isSent: boolean) => { const getMessageClass = (isSent: boolean) => {
return isSent ? 'message-container-right' : 'message-container-left' return isSent ? 'message-container-right' : 'message-container-left'
} }
//发送商品信息
const toSendLink = (e: any) => { const toSendLink = (e: any) => {
const data = { const data = {
content: e, content: e,
...@@ -527,7 +632,7 @@ const toSendLink = (e: any) => { ...@@ -527,7 +632,7 @@ const toSendLink = (e: any) => {
fromLang: 'cn', fromLang: 'cn',
toLang: 'en', toLang: 'en',
group_id: '', group_id: '',
time: getShortDate(), time: moment(new Date()).format('HH:mm:ss'),
to: customerInfo.value.username, to: customerInfo.value.username,
form: store.userInfo.username, form: store.userInfo.username,
} }
...@@ -537,15 +642,129 @@ const toSendLink = (e: any) => { ...@@ -537,15 +642,129 @@ const toSendLink = (e: any) => {
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.inquiry-list {
display: flex;
width: 360px;
padding: 12px 12px 8px 12px;
flex-direction: column;
justify-content: center;
align-items: flex-start;
border-radius: 8px 0 8px 8px;
border: 1px solid #e9ecf1;
.inquiry-top {
margin-bottom: 8px;
width: 100%;
display: flex;
justify-content: space-between;
.product-left {
display: flex;
flex-direction: column;
justify-content: space-between;
.product-category {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
color: #0c203d;
text-overflow: ellipsis;
font-family: 'Inter';
font-size: 14px;
font-style: normal;
font-weight: 500;
margin-bottom: 6px;
}
.product-name {
font-family: 'Inter';
font-size: 14px;
font-style: normal;
font-weight: 500;
}
}
}
.design-requirements {
width: 336px;
height: 36px;
justify-content: space-between;
line-height: 36px;
margin-top: 8px;
padding: 0px 8px;
display: flex;
align-items: center;
background: #f6f9fc;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
align-self: stretch;
overflow: hidden;
border-radius: 4px;
color: #475263;
text-overflow: ellipsis;
font-family: 'Inter';
font-size: 12px;
font-style: normal;
font-weight: 400;
.img {
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
.we-connecting {
display: flex;
padding: 8px;
font-size: 12px;
justify-content: center;
align-items: center;
border-radius: 4px;
width: max-content;
background: #f8f8fa;
margin: 0px auto;
margin-bottom: 16px;
color: #798494;
}
.title-message { .title-message {
color: #798494; color: #798494;
height: 56px;
line-height: 56px;
text-align: center; text-align: center;
font-feature-settings: 'clig' off, 'liga' off; font-feature-settings: 'clig' off, 'liga' off;
font-family: 'Helvetica Neue'; font-family: 'Helvetica Neue';
font-size: 14px; font-size: 12px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 16px; }
.message-time {
color: #798494;
text-align: center;
font-feature-settings: 'clig' off, 'liga' off;
font-family: 'Inter';
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 20px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
&::after,
&::before {
display: flex;
content: ' ';
height: 0.5px;
background: #e6e8ed;
flex: 1;
justify-content: space-between;
align-items: center;
}
&::after {
margin-left: 8px;
}
&::before {
margin-right: 8px;
}
} }
.class-send-box { .class-send-box {
display: flex; display: flex;
...@@ -968,10 +1187,11 @@ const toSendLink = (e: any) => { ...@@ -968,10 +1187,11 @@ const toSendLink = (e: any) => {
} }
.avatar-image { .avatar-image {
width: 40px; width: 32px;
height: 40px; height: 32px;
border-radius: 50%; border-radius: 50%;
object-fit: cover; object-fit: cover;
margin-right: 12px;
} }
.bubble { .bubble {
...@@ -979,7 +1199,6 @@ const toSendLink = (e: any) => { ...@@ -979,7 +1199,6 @@ const toSendLink = (e: any) => {
color: #000; color: #000;
padding: 10px 14px; padding: 10px 14px;
border-radius: 5px; border-radius: 5px;
max-width: 320px;
background: #f5f5f5; background: #f5f5f5;
border-radius: 10px; border-radius: 10px;
color: #000; color: #000;
...@@ -992,6 +1211,30 @@ const toSendLink = (e: any) => { ...@@ -992,6 +1211,30 @@ const toSendLink = (e: any) => {
height: auto; height: auto;
display: block; display: block;
} }
.bubble-title {
font-family: 'Helvetica Neue';
font-size: 14px;
font-style: normal;
font-weight: 500;
line-height: 20px;
margin-bottom: 4px;
}
.bubble-h1 {
color: #1a65d6;
cursor: pointer;
font-family: 'Helvetica Neue';
font-size: 14px;
font-style: normal;
display: block;
font-weight: 500;
line-height: 20px;
letter-spacing: 0.56px;
margin-bottom: 4px;
}
}
.official-box {
width: 464px;
} }
.message-container-right { .message-container-right {
...@@ -1065,12 +1308,22 @@ const toSendLink = (e: any) => { ...@@ -1065,12 +1308,22 @@ const toSendLink = (e: any) => {
} }
.browse-glance { .browse-glance {
display: flex; display: flex;
padding: 16px 12px 0px 12px; position: relative;
padding: 16px 12px 16px 12px;
.browse-img { .browse-img {
width: 64px; width: 64px;
height: 64px; height: 64px;
margin-right: 12px; margin-right: 12px;
} }
&::before {
position: absolute;
content: ' ';
height: 0.5px;
background: #e6e8ed;
width: 91%;
bottom: 0px;
}
.units { .units {
margin-top: 8px; margin-top: 8px;
...@@ -1092,7 +1345,6 @@ const toSendLink = (e: any) => { ...@@ -1092,7 +1345,6 @@ const toSendLink = (e: any) => {
line-height: 24px; line-height: 24px;
letter-spacing: 0.72px; letter-spacing: 0.72px;
} }
.send { .send {
display: flex; display: flex;
width: 56px; width: 56px;
...@@ -1219,6 +1471,7 @@ const toSendLink = (e: any) => { ...@@ -1219,6 +1471,7 @@ const toSendLink = (e: any) => {
color: #073a3dff; color: #073a3dff;
font-family: 'Inter'; font-family: 'Inter';
font-size: 14px; font-size: 14px;
margin-bottom: 4px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
line-height: 20px; line-height: 20px;
...@@ -1270,4 +1523,33 @@ const toSendLink = (e: any) => { ...@@ -1270,4 +1523,33 @@ const toSendLink = (e: any) => {
:deep(.el-select__wrapper) { :deep(.el-select__wrapper) {
height: 36px !important; height: 36px !important;
} }
.product-count {
color: #0c203dff;
font-feature-settings: 'clig' off, 'liga' off;
font-family: 'Helvetica Neue';
font-size: 18px;
font-style: normal;
font-weight: 700;
line-height: 24px;
letter-spacing: 0.72px;
}
.from-china {
color: #475263ff;
font-family: 'Inter';
font-size: 10px;
font-style: normal;
font-weight: 400;
line-height: 16px;
}
.product-info {
align-self: stretch;
color: #475263;
font-family: 'Inter';
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 20px;
padding-bottom: 8px;
border-bottom: 1px solid #e6e8ed;
}
</style> </style>
...@@ -46,7 +46,7 @@ export default defineConfig({ ...@@ -46,7 +46,7 @@ export default defineConfig({
], ],
server: { server: {
host: "0.0.0.0", host: "0.0.0.0",
port: 80, port: 8082,
open: false, open: false,
}, },
}); });
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论