mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-07 17:38:55 +08:00
refactor: 四端完成 Options API → script setup + vuex → pinia 迁移
- buyer(95) / seller(169) / im(53) / manager(280) 共 597 个组件全部从 Options API 转换为 <script setup> - 四端 vuex 全部移除,状态管理统一迁移至 pinia 4(stores/ 目录) - util.js 等基础设施去除 vm 首参依赖;全局属性($Message/$filters 等)在 script 内改为具名导入 - 被外部 ref 访问的公共组件均已补齐 defineExpose(清单见各端 MIGRATION-VUE3.md) - 各端 eslint 启用 vue/component-api-style 防止新代码回退 Options API - 四端 yarn build 全部通过;迁移约定与注意事项已更新至各端 MIGRATION-VUE3.md
This commit is contained in:
@@ -42,171 +42,175 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
import { PrismEditor } from "vue-prism-editor";
|
||||
import "vue-prism-editor/dist/prismeditor.min.css";
|
||||
import "prismjs/themes/prism-okaidia.css";
|
||||
export default {
|
||||
name: "TalkCodeBlock",
|
||||
components: {
|
||||
PrismEditor,
|
||||
},
|
||||
props: {
|
||||
loadCode: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
loadLang: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
language: "",
|
||||
code: "",
|
||||
options: [
|
||||
{
|
||||
value: "css",
|
||||
label: "css",
|
||||
},
|
||||
{
|
||||
value: "less",
|
||||
label: "less",
|
||||
},
|
||||
{
|
||||
value: "javascript",
|
||||
label: "javascript",
|
||||
},
|
||||
{
|
||||
value: "json",
|
||||
label: "json",
|
||||
},
|
||||
{
|
||||
value: "bash",
|
||||
label: "bash",
|
||||
},
|
||||
{
|
||||
value: "c",
|
||||
label: "c",
|
||||
},
|
||||
{
|
||||
value: "cil",
|
||||
label: "cil",
|
||||
},
|
||||
{
|
||||
value: "docker",
|
||||
label: "docker",
|
||||
},
|
||||
{
|
||||
value: "git",
|
||||
label: "git",
|
||||
},
|
||||
{
|
||||
value: "go",
|
||||
label: "go",
|
||||
},
|
||||
{
|
||||
value: "java",
|
||||
label: "java",
|
||||
},
|
||||
{
|
||||
value: "lua",
|
||||
label: "lua",
|
||||
},
|
||||
{
|
||||
value: "nginx",
|
||||
label: "nginx",
|
||||
},
|
||||
{
|
||||
value: "objectivec",
|
||||
label: "objectivec",
|
||||
},
|
||||
{
|
||||
value: "php",
|
||||
label: "php",
|
||||
},
|
||||
{
|
||||
value: "python",
|
||||
label: "python",
|
||||
},
|
||||
{
|
||||
value: "ruby",
|
||||
label: "ruby",
|
||||
},
|
||||
{
|
||||
value: "rust",
|
||||
label: "rust",
|
||||
},
|
||||
{
|
||||
value: "sql",
|
||||
label: "sql",
|
||||
},
|
||||
{
|
||||
value: "swift",
|
||||
label: "swift",
|
||||
},
|
||||
{
|
||||
value: "vim",
|
||||
label: "vim",
|
||||
},
|
||||
{
|
||||
value: "visual-basic",
|
||||
label: "visual-basic",
|
||||
},
|
||||
{
|
||||
value: "shell",
|
||||
label: "shell",
|
||||
},
|
||||
],
|
||||
isFullScreen: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
loadCode(value) {
|
||||
this.code = value;
|
||||
},
|
||||
loadLang(value) {
|
||||
this.language = value;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.code = this.loadCode;
|
||||
this.language = this.loadLang;
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
if (!this.code) {
|
||||
this.$message.error("代码块不能为空...");
|
||||
return false;
|
||||
}
|
||||
import { ElMessage } from "@/utils/message";
|
||||
|
||||
if (this.language == "") {
|
||||
this.$message.error("请选择语言");
|
||||
return false;
|
||||
}
|
||||
defineOptions({ name: "TalkCodeBlock" });
|
||||
|
||||
if (this.code.length > 10000) {
|
||||
this.$message.error("代码字数不能超过10000字!!!");
|
||||
return false;
|
||||
}
|
||||
this.$emit("confirm", {
|
||||
language: this.language,
|
||||
code: this.code,
|
||||
});
|
||||
},
|
||||
close() {
|
||||
this.$emit("close");
|
||||
},
|
||||
codeChanged(code) {
|
||||
this.code = code;
|
||||
},
|
||||
const props = defineProps({
|
||||
loadCode: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
};
|
||||
loadLang: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
editMode: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["confirm", "close"]);
|
||||
|
||||
const language = ref("");
|
||||
const code = ref("");
|
||||
const options = ref([
|
||||
{
|
||||
value: "css",
|
||||
label: "css",
|
||||
},
|
||||
{
|
||||
value: "less",
|
||||
label: "less",
|
||||
},
|
||||
{
|
||||
value: "javascript",
|
||||
label: "javascript",
|
||||
},
|
||||
{
|
||||
value: "json",
|
||||
label: "json",
|
||||
},
|
||||
{
|
||||
value: "bash",
|
||||
label: "bash",
|
||||
},
|
||||
{
|
||||
value: "c",
|
||||
label: "c",
|
||||
},
|
||||
{
|
||||
value: "cil",
|
||||
label: "cil",
|
||||
},
|
||||
{
|
||||
value: "docker",
|
||||
label: "docker",
|
||||
},
|
||||
{
|
||||
value: "git",
|
||||
label: "git",
|
||||
},
|
||||
{
|
||||
value: "go",
|
||||
label: "go",
|
||||
},
|
||||
{
|
||||
value: "java",
|
||||
label: "java",
|
||||
},
|
||||
{
|
||||
value: "lua",
|
||||
label: "lua",
|
||||
},
|
||||
{
|
||||
value: "nginx",
|
||||
label: "nginx",
|
||||
},
|
||||
{
|
||||
value: "objectivec",
|
||||
label: "objectivec",
|
||||
},
|
||||
{
|
||||
value: "php",
|
||||
label: "php",
|
||||
},
|
||||
{
|
||||
value: "python",
|
||||
label: "python",
|
||||
},
|
||||
{
|
||||
value: "ruby",
|
||||
label: "ruby",
|
||||
},
|
||||
{
|
||||
value: "rust",
|
||||
label: "rust",
|
||||
},
|
||||
{
|
||||
value: "sql",
|
||||
label: "sql",
|
||||
},
|
||||
{
|
||||
value: "swift",
|
||||
label: "swift",
|
||||
},
|
||||
{
|
||||
value: "vim",
|
||||
label: "vim",
|
||||
},
|
||||
{
|
||||
value: "visual-basic",
|
||||
label: "visual-basic",
|
||||
},
|
||||
{
|
||||
value: "shell",
|
||||
label: "shell",
|
||||
},
|
||||
]);
|
||||
const isFullScreen = ref(false);
|
||||
|
||||
watch(
|
||||
() => props.loadCode,
|
||||
(value) => {
|
||||
code.value = value;
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => props.loadLang,
|
||||
(value) => {
|
||||
language.value = value;
|
||||
}
|
||||
);
|
||||
|
||||
// created
|
||||
code.value = props.loadCode;
|
||||
language.value = props.loadLang;
|
||||
|
||||
function submit() {
|
||||
if (!code.value) {
|
||||
ElMessage.error("代码块不能为空...");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (language.value == "") {
|
||||
ElMessage.error("请选择语言");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (code.value.length > 10000) {
|
||||
ElMessage.error("代码字数不能超过10000字!!!");
|
||||
return false;
|
||||
}
|
||||
emit("confirm", {
|
||||
language: language.value,
|
||||
code: code.value,
|
||||
});
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit("close");
|
||||
}
|
||||
|
||||
function codeChanged(val) {
|
||||
code.value = val;
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
|
||||
@@ -77,48 +77,48 @@
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { ServeGetForwardRecords } from '@/api/chat'
|
||||
|
||||
export default {
|
||||
name: 'TalkForwardRecord',
|
||||
data() {
|
||||
return {
|
||||
record_id: 0,
|
||||
records: [],
|
||||
loading: false,
|
||||
isShow: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open(record_id) {
|
||||
if (record_id !== this.record_id) {
|
||||
this.record_id = record_id
|
||||
this.records = []
|
||||
this.loadRecords()
|
||||
}
|
||||
defineOptions({ name: 'TalkForwardRecord' })
|
||||
|
||||
this.isShow = true
|
||||
},
|
||||
close() {
|
||||
this.isShow = false
|
||||
},
|
||||
loadRecords() {
|
||||
this.loading = true
|
||||
ServeGetForwardRecords({
|
||||
record_id: this.record_id,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code == 200) {
|
||||
this.records = res.data.rows
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
const record_id = ref(0)
|
||||
const records = ref([])
|
||||
const loading = ref(false)
|
||||
const isShow = ref(false)
|
||||
|
||||
// 由父组件通过 ref 调用(如 ForwardMessage),必须暴露
|
||||
const open = id => {
|
||||
if (id !== record_id.value) {
|
||||
record_id.value = id
|
||||
records.value = []
|
||||
loadRecords()
|
||||
}
|
||||
|
||||
isShow.value = true
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
isShow.value = false
|
||||
}
|
||||
|
||||
const loadRecords = () => {
|
||||
loading.value = true
|
||||
ServeGetForwardRecords({
|
||||
record_id: record_id.value,
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code == 200) {
|
||||
records.value = res.data.rows
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.lum-dialog-mask {
|
||||
|
||||
@@ -211,190 +211,187 @@
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { ServeGetContacts } from "@/api/contacts";
|
||||
import { ServeFindTalkRecords } from "@/api/chat";
|
||||
import { formatSize as renderSize, download, imgZoom } from "@/utils/functions";
|
||||
import { ElNotification } from "@/utils/message";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
|
||||
export default {
|
||||
name: "TalkSearchRecord",
|
||||
props: {
|
||||
params: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
title: "",
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fullscreen: false,
|
||||
defineOptions({ name: "TalkSearchRecord" });
|
||||
|
||||
user_id: this.$store.state.user.id,
|
||||
title: "",
|
||||
|
||||
// 侧边栏相关信息
|
||||
broadside: false,
|
||||
contacts: {
|
||||
show: "friends",
|
||||
friends: [],
|
||||
groups: [],
|
||||
},
|
||||
|
||||
query: {
|
||||
const props = defineProps({
|
||||
params: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
msg_type: 0,
|
||||
},
|
||||
|
||||
// 用户聊天记录
|
||||
records: {
|
||||
record_id: 0,
|
||||
items: [],
|
||||
isEmpty: false,
|
||||
loadStatus: 0,
|
||||
},
|
||||
|
||||
showBox: 0,
|
||||
|
||||
tabType: [
|
||||
{ name: "全部", type: 0 },
|
||||
{ name: "文件", type: 2 },
|
||||
{ name: "会话记录", type: 3 },
|
||||
{ name: "代码块", type: 4 },
|
||||
{ name: "群投票", type: 5 },
|
||||
],
|
||||
|
||||
search: {
|
||||
keyword: "", // 关键字查询
|
||||
date: "", // 时间查询
|
||||
page: 1, // 当前分页
|
||||
totalPage: 50, // 总分页
|
||||
items: [], // 数据列表
|
||||
isShowDate: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.title = this.params.title;
|
||||
this.query = {
|
||||
talk_type: this.params.talk_type,
|
||||
receiver_id: this.params.receiver_id,
|
||||
msg_type: 0,
|
||||
};
|
||||
|
||||
this.loadChatRecord(0);
|
||||
},
|
||||
created() {
|
||||
this.loadFriends();
|
||||
},
|
||||
methods: {
|
||||
download,
|
||||
renderSize,
|
||||
|
||||
// 获取图片信息
|
||||
getImgStyle(url) {
|
||||
return imgZoom(url, 200);
|
||||
},
|
||||
|
||||
// 获取会话记录消息名称
|
||||
getForwardTitle(item) {
|
||||
let arr = [...new Set(item.map((v) => v.nickname))];
|
||||
return arr.join("、") + "的会话记录";
|
||||
},
|
||||
|
||||
// 获取好友列表
|
||||
loadFriends() {
|
||||
ServeGetContacts().then(({ code, data }) => {
|
||||
if (code == 200) {
|
||||
this.contacts.friends = data.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
type: 1,
|
||||
avatar: item.avatar,
|
||||
name: item.friend_remark ? item.friend_remark : item.nickname,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 左侧联系人菜单点击事件
|
||||
triggerMenuItem(item) {
|
||||
this.title = item.name;
|
||||
this.query.talk_type = item.type;
|
||||
this.query.receiver_id = item.id;
|
||||
this.showBox = 0;
|
||||
|
||||
this.triggerLoadType(0);
|
||||
},
|
||||
|
||||
// 加载历史记录
|
||||
loadChatRecord() {
|
||||
let data = {
|
||||
talk_type: this.query.talk_type,
|
||||
receiver_id: this.query.receiver_id,
|
||||
record_id: this.records.record_id,
|
||||
msg_type: this.query.msg_type,
|
||||
title: "",
|
||||
};
|
||||
|
||||
if (this.records.loadStatus == 1) return;
|
||||
|
||||
this.records.loadStatus = 1;
|
||||
ServeFindTalkRecords(data)
|
||||
.then((res) => {
|
||||
if (res.code != 200) return;
|
||||
|
||||
let records = data.record_id == 0 ? [] : this.records.items;
|
||||
|
||||
records.push(...res.data.rows);
|
||||
|
||||
this.records.items = records;
|
||||
this.records.loadStatus =
|
||||
res.data.rows.length < res.data.limit ? 2 : 0;
|
||||
|
||||
if (this.records.items.length == 0) {
|
||||
this.records.isEmpty = true;
|
||||
} else {
|
||||
this.records.record_id =
|
||||
this.records.items[this.records.items.length - 1].id;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.records.loadStatus = 0;
|
||||
});
|
||||
},
|
||||
|
||||
triggerLoadType(type) {
|
||||
this.records.record_id = 0;
|
||||
this.query.msg_type = type;
|
||||
this.records.isEmpty = false;
|
||||
this.records.items = [];
|
||||
|
||||
this.loadChatRecord();
|
||||
},
|
||||
|
||||
searchText() {
|
||||
if (this.search.keyword == "") {
|
||||
this.showBox = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$notify.info({
|
||||
title: "消息",
|
||||
message: "查询功能正在开发中...",
|
||||
});
|
||||
},
|
||||
|
||||
triggerBroadside() {
|
||||
this.broadside = !this.broadside;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const emit = defineEmits(["close"]);
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const fullscreen = ref(false);
|
||||
|
||||
const user_id = ref(userStore.id);
|
||||
const title = ref("");
|
||||
|
||||
// 侧边栏相关信息
|
||||
const broadside = ref(false);
|
||||
const contacts = reactive({
|
||||
show: "friends",
|
||||
friends: [],
|
||||
groups: [],
|
||||
});
|
||||
|
||||
const query = ref({
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
msg_type: 0,
|
||||
});
|
||||
|
||||
// 用户聊天记录
|
||||
const records = reactive({
|
||||
record_id: 0,
|
||||
items: [],
|
||||
isEmpty: false,
|
||||
loadStatus: 0,
|
||||
});
|
||||
|
||||
const showBox = ref(0);
|
||||
|
||||
const tabType = ref([
|
||||
{ name: "全部", type: 0 },
|
||||
{ name: "文件", type: 2 },
|
||||
{ name: "会话记录", type: 3 },
|
||||
{ name: "代码块", type: 4 },
|
||||
{ name: "群投票", type: 5 },
|
||||
]);
|
||||
|
||||
const search = reactive({
|
||||
keyword: "", // 关键字查询
|
||||
date: "", // 时间查询
|
||||
page: 1, // 当前分页
|
||||
totalPage: 50, // 总分页
|
||||
items: [], // 数据列表
|
||||
isShowDate: false,
|
||||
});
|
||||
|
||||
// 获取图片信息
|
||||
function getImgStyle(url) {
|
||||
return imgZoom(url, 200);
|
||||
}
|
||||
|
||||
// 获取会话记录消息名称
|
||||
function getForwardTitle(item) {
|
||||
let arr = [...new Set(item.map((v) => v.nickname))];
|
||||
return arr.join("、") + "的会话记录";
|
||||
}
|
||||
|
||||
// 获取好友列表
|
||||
function loadFriends() {
|
||||
ServeGetContacts().then(({ code, data }) => {
|
||||
if (code == 200) {
|
||||
contacts.friends = data.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
type: 1,
|
||||
avatar: item.avatar,
|
||||
name: item.friend_remark ? item.friend_remark : item.nickname,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 左侧联系人菜单点击事件
|
||||
function triggerMenuItem(item) {
|
||||
title.value = item.name;
|
||||
query.value.talk_type = item.type;
|
||||
query.value.receiver_id = item.id;
|
||||
showBox.value = 0;
|
||||
|
||||
triggerLoadType(0);
|
||||
}
|
||||
|
||||
// 加载历史记录
|
||||
function loadChatRecord() {
|
||||
let data = {
|
||||
talk_type: query.value.talk_type,
|
||||
receiver_id: query.value.receiver_id,
|
||||
record_id: records.record_id,
|
||||
msg_type: query.value.msg_type,
|
||||
};
|
||||
|
||||
if (records.loadStatus == 1) return;
|
||||
|
||||
records.loadStatus = 1;
|
||||
ServeFindTalkRecords(data)
|
||||
.then((res) => {
|
||||
if (res.code != 200) return;
|
||||
|
||||
let items = data.record_id == 0 ? [] : records.items;
|
||||
|
||||
items.push(...res.data.rows);
|
||||
|
||||
records.items = items;
|
||||
records.loadStatus = res.data.rows.length < res.data.limit ? 2 : 0;
|
||||
|
||||
if (records.items.length == 0) {
|
||||
records.isEmpty = true;
|
||||
} else {
|
||||
records.record_id = records.items[records.items.length - 1].id;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
records.loadStatus = 0;
|
||||
});
|
||||
}
|
||||
|
||||
function triggerLoadType(type) {
|
||||
records.record_id = 0;
|
||||
query.value.msg_type = type;
|
||||
records.isEmpty = false;
|
||||
records.items = [];
|
||||
|
||||
loadChatRecord();
|
||||
}
|
||||
|
||||
function searchText() {
|
||||
if (search.keyword == "") {
|
||||
showBox.value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
ElNotification.info({
|
||||
title: "消息",
|
||||
message: "查询功能正在开发中...",
|
||||
});
|
||||
}
|
||||
|
||||
function triggerBroadside() {
|
||||
broadside.value = !broadside.value;
|
||||
}
|
||||
|
||||
loadFriends();
|
||||
|
||||
onMounted(() => {
|
||||
title.value = props.params.title;
|
||||
query.value = {
|
||||
talk_type: props.params.talk_type,
|
||||
receiver_id: props.params.receiver_id,
|
||||
msg_type: 0,
|
||||
};
|
||||
|
||||
loadChatRecord(0);
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.el-scrollbar__wrap ) {
|
||||
|
||||
@@ -27,7 +27,18 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
defineOptions({ name: 'AudioMessage' });
|
||||
|
||||
defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
function formatSeconds(value) {
|
||||
var theTime = parseInt(value) // 秒
|
||||
var theTime1 = 0 // 分
|
||||
@@ -59,64 +70,47 @@ function formatSeconds(value) {
|
||||
return result
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'AudioMessage',
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
isPlay: false,
|
||||
duration: 0,
|
||||
currentTime: 0,
|
||||
progress: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getTotalDuration() {
|
||||
return formatSeconds(this.duration)
|
||||
},
|
||||
getCurrDuration() {
|
||||
return formatSeconds(this.currentTime)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toPlay() {
|
||||
if (this.loading) {
|
||||
return
|
||||
}
|
||||
const loading = ref(true)
|
||||
const isPlay = ref(false)
|
||||
const duration = ref(0)
|
||||
const currentTime = ref(0)
|
||||
const progress = ref(0)
|
||||
|
||||
let audio = this.$refs.audio
|
||||
if (this.isPlay) {
|
||||
audio.pause()
|
||||
} else {
|
||||
audio.play()
|
||||
}
|
||||
this.isPlay = !this.isPlay
|
||||
},
|
||||
const audio = ref(null)
|
||||
|
||||
// 当目前的播放位置已更改时
|
||||
timeupdate() {
|
||||
let audio = this.$refs.audio
|
||||
this.currentTime = audio.currentTime
|
||||
this.progress = (audio.currentTime / audio.duration) * 100
|
||||
},
|
||||
const getTotalDuration = computed(() => formatSeconds(duration.value))
|
||||
const getCurrDuration = computed(() => formatSeconds(currentTime.value))
|
||||
|
||||
// 当浏览器可以播放音频/视频时
|
||||
canplay() {
|
||||
this.duration = this.$refs.audio.duration
|
||||
this.loading = false
|
||||
},
|
||||
function toPlay() {
|
||||
if (loading.value) {
|
||||
return
|
||||
}
|
||||
|
||||
// 当目前的播放列表已结束时
|
||||
ended() {
|
||||
this.isPlay = false
|
||||
},
|
||||
},
|
||||
let audioEl = audio.value
|
||||
if (isPlay.value) {
|
||||
audioEl.pause()
|
||||
} else {
|
||||
audioEl.play()
|
||||
}
|
||||
isPlay.value = !isPlay.value
|
||||
}
|
||||
|
||||
// 当目前的播放位置已更改时
|
||||
function timeupdate() {
|
||||
let audioEl = audio.value
|
||||
currentTime.value = audioEl.currentTime
|
||||
progress.value = (audioEl.currentTime / audioEl.duration) * 100
|
||||
}
|
||||
|
||||
// 当浏览器可以播放音频/视频时
|
||||
function canplay() {
|
||||
duration.value = audio.value.duration
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
// 当目前的播放列表已结束时
|
||||
function ended() {
|
||||
isPlay.value = false
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
|
||||
@@ -20,44 +20,40 @@
|
||||
<pre class="lum-scrollbar" v-html="formatCode(code, lang)" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import Prism from 'prismjs'
|
||||
import 'prismjs/themes/prism-okaidia.css'
|
||||
|
||||
export default {
|
||||
name: 'CodeMessage',
|
||||
props: {
|
||||
code: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
maxwidth: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defineOptions({ name: 'CodeMessage' })
|
||||
|
||||
const props = defineProps({
|
||||
code: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fullscreen: false,
|
||||
lineNumber: 0,
|
||||
}
|
||||
lang: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
created() {
|
||||
this.lineNumber = this.code.split(/\n/).length
|
||||
},
|
||||
methods: {
|
||||
formatCode(code, lang) {
|
||||
try {
|
||||
return Prism.highlight(code, Prism.languages[lang], lang) + '<br/>'
|
||||
} catch (error) {
|
||||
return code
|
||||
}
|
||||
},
|
||||
maxwidth: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const fullscreen = ref(false)
|
||||
const lineNumber = ref(0)
|
||||
|
||||
// created
|
||||
lineNumber.value = props.code.split(/\n/).length
|
||||
|
||||
function formatCode(code, lang) {
|
||||
try {
|
||||
return Prism.highlight(code, Prism.languages[lang], lang) + '<br/>'
|
||||
} catch (error) {
|
||||
return code
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -16,39 +16,36 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { formatSize, download } from '@/utils/functions'
|
||||
export default {
|
||||
name: 'FileMessage',
|
||||
props: {
|
||||
file: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0,
|
||||
},
|
||||
|
||||
defineOptions({ name: 'FileMessage' })
|
||||
|
||||
const props = defineProps({
|
||||
file: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
file_id: 0,
|
||||
ext: '',
|
||||
fileName: '',
|
||||
fileSize: '',
|
||||
}
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0,
|
||||
},
|
||||
created() {
|
||||
this.file_id = this.file.id
|
||||
this.ext = this.file.file_suffix.toUpperCase()
|
||||
this.fileName = this.file.original_name
|
||||
this.fileSize = formatSize(this.file.file_size)
|
||||
},
|
||||
methods: {
|
||||
download,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const file_id = ref(0)
|
||||
const ext = ref('')
|
||||
const fileName = ref('')
|
||||
const fileSize = ref('')
|
||||
|
||||
// 原 created 钩子
|
||||
file_id.value = props.file.id
|
||||
ext.value = props.file.file_suffix.toUpperCase()
|
||||
fileName.value = props.file.original_name
|
||||
fileSize.value = formatSize(props.file.file_size)
|
||||
|
||||
// download 直接从 @/utils/functions 导入,模板中照用
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.file-message {
|
||||
|
||||
@@ -17,48 +17,44 @@
|
||||
<talk-forward-record ref="forwardRecordsRef" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import TalkForwardRecord from '@/components/chat/TalkForwardRecord'
|
||||
export default {
|
||||
name: 'ForwardMessage',
|
||||
components: {
|
||||
TalkForwardRecord,
|
||||
},
|
||||
props: {
|
||||
forward: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
records: [],
|
||||
num: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
catForwardRecords() {
|
||||
this.$refs.forwardRecordsRef.open(this.record_id)
|
||||
},
|
||||
getForwardTitle(list) {
|
||||
let arr = [...new Set(list.map(v => v.nickname))]
|
||||
return arr.join('、') + '的会话记录'
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let forward = this.forward
|
||||
|
||||
this.num = forward.num
|
||||
this.records = forward.list
|
||||
this.title = this.getForwardTitle(this.records)
|
||||
defineOptions({ name: 'ForwardMessage' })
|
||||
|
||||
const props = defineProps({
|
||||
forward: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0,
|
||||
},
|
||||
})
|
||||
|
||||
const forwardRecordsRef = ref(null)
|
||||
|
||||
const title = ref('')
|
||||
const records = ref([])
|
||||
const num = ref(0)
|
||||
|
||||
function catForwardRecords() {
|
||||
forwardRecordsRef.value.open(props.record_id)
|
||||
}
|
||||
|
||||
function getForwardTitle(list) {
|
||||
let arr = [...new Set(list.map(v => v.nickname))]
|
||||
return arr.join('、') + '的会话记录'
|
||||
}
|
||||
|
||||
let forward = props.forward
|
||||
|
||||
num.value = forward.num
|
||||
records.value = forward.list
|
||||
title.value = getForwardTitle(records.value)
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
/* 会话记录消息 */
|
||||
|
||||
@@ -18,33 +18,30 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FriendApplyMessage',
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
avatar:
|
||||
'http://im-img.gzydong.club/media/images/avatar/20210602/60b6f03598ed0104301.png',
|
||||
nickname: '独特态度',
|
||||
datetime: '05/09 12:13 分',
|
||||
remarks: '编辑个签,展示我的独特态度 展示我的独特态度。',
|
||||
apply_id: 0,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
handle(type) {
|
||||
alert(type)
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
defineOptions({ name: 'FriendApplyMessage' })
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const avatar = ref(
|
||||
'http://im-img.gzydong.club/media/images/avatar/20210602/60b6f03598ed0104301.png'
|
||||
)
|
||||
const nickname = ref('独特态度')
|
||||
const datetime = ref('05/09 12:13 分')
|
||||
const remarks = ref('编辑个签,展示我的独特态度 展示我的独特态度。')
|
||||
const apply_id = ref(0)
|
||||
|
||||
function handle(type) {
|
||||
alert(type)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -16,21 +16,20 @@
|
||||
</el-image>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { imgZoom } from '@/utils/functions'
|
||||
export default {
|
||||
name: 'ImageMessage',
|
||||
props: {
|
||||
src: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getImgStyle(url) {
|
||||
return imgZoom(url, 200)
|
||||
},
|
||||
|
||||
defineOptions({ name: 'ImageMessage' })
|
||||
|
||||
defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
function getImgStyle(url) {
|
||||
return imgZoom(url, 200)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -20,20 +20,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'InviteMessage',
|
||||
props: {
|
||||
invite: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
toUser(user_id) {
|
||||
this.$emit('cat', user_id)
|
||||
},
|
||||
<script setup>
|
||||
defineOptions({ name: 'InviteMessage' })
|
||||
|
||||
defineProps({
|
||||
invite: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['cat'])
|
||||
|
||||
function toUser(user_id) {
|
||||
emit('cat', user_id)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -10,76 +10,72 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { parseTime } from '@/utils/functions'
|
||||
|
||||
export default {
|
||||
name: 'LoginMessage',
|
||||
props: {
|
||||
detail: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
datetime: '',
|
||||
ip: '',
|
||||
address: '',
|
||||
platform: '',
|
||||
reason: '常用设备登录',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.ip = this.detail.ip
|
||||
this.datetime = parseTime(
|
||||
this.detail.created_at,
|
||||
'{y}年{m}月{d}日 {h}:{i}:{s}'
|
||||
)
|
||||
this.address = this.detail.address
|
||||
this.reason = this.detail.reason
|
||||
defineOptions({ name: 'LoginMessage' })
|
||||
|
||||
this.platform =
|
||||
this.getExploreName(this.detail.agent) +
|
||||
' / ' +
|
||||
this.getExploreOs(this.detail.agent)
|
||||
const props = defineProps({
|
||||
detail: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
methods: {
|
||||
getExploreName(userAgent = '') {
|
||||
if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) {
|
||||
return 'Opera'
|
||||
} else if (
|
||||
userAgent.indexOf('compatible') > -1 &&
|
||||
userAgent.indexOf('MSIE') > -1
|
||||
) {
|
||||
return 'IE'
|
||||
} else if (userAgent.indexOf('Edge') > -1) {
|
||||
return 'Edge'
|
||||
} else if (userAgent.indexOf('Firefox') > -1) {
|
||||
return 'Firefox'
|
||||
} else if (
|
||||
userAgent.indexOf('Safari') > -1 &&
|
||||
userAgent.indexOf('Chrome') == -1
|
||||
) {
|
||||
return 'Safari'
|
||||
} else if (
|
||||
userAgent.indexOf('Chrome') > -1 &&
|
||||
userAgent.indexOf('Safari') > -1
|
||||
) {
|
||||
return 'Chrome'
|
||||
} else {
|
||||
return 'Unkonwn'
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
getExploreOs(userAgent = '') {
|
||||
if (userAgent.indexOf('Mac OS') > -1) {
|
||||
return 'Mac OS'
|
||||
} else {
|
||||
return 'Windows'
|
||||
}
|
||||
},
|
||||
},
|
||||
const datetime = ref('')
|
||||
const ip = ref('')
|
||||
const address = ref('')
|
||||
const platform = ref('')
|
||||
const reason = ref('常用设备登录')
|
||||
|
||||
// 原 created 生命周期逻辑,setup 顶层直接执行
|
||||
ip.value = props.detail.ip
|
||||
datetime.value = parseTime(
|
||||
props.detail.created_at,
|
||||
'{y}年{m}月{d}日 {h}:{i}:{s}'
|
||||
)
|
||||
address.value = props.detail.address
|
||||
reason.value = props.detail.reason
|
||||
|
||||
platform.value =
|
||||
getExploreName(props.detail.agent) +
|
||||
' / ' +
|
||||
getExploreOs(props.detail.agent)
|
||||
|
||||
function getExploreName(userAgent = '') {
|
||||
if (userAgent.indexOf('Opera') > -1 || userAgent.indexOf('OPR') > -1) {
|
||||
return 'Opera'
|
||||
} else if (
|
||||
userAgent.indexOf('compatible') > -1 &&
|
||||
userAgent.indexOf('MSIE') > -1
|
||||
) {
|
||||
return 'IE'
|
||||
} else if (userAgent.indexOf('Edge') > -1) {
|
||||
return 'Edge'
|
||||
} else if (userAgent.indexOf('Firefox') > -1) {
|
||||
return 'Firefox'
|
||||
} else if (
|
||||
userAgent.indexOf('Safari') > -1 &&
|
||||
userAgent.indexOf('Chrome') == -1
|
||||
) {
|
||||
return 'Safari'
|
||||
} else if (
|
||||
userAgent.indexOf('Chrome') > -1 &&
|
||||
userAgent.indexOf('Safari') > -1
|
||||
) {
|
||||
return 'Chrome'
|
||||
} else {
|
||||
return 'Unkonwn'
|
||||
}
|
||||
}
|
||||
|
||||
function getExploreOs(userAgent = '') {
|
||||
if (userAgent.indexOf('Mac OS') > -1) {
|
||||
return 'Mac OS'
|
||||
} else {
|
||||
return 'Windows'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -2,15 +2,10 @@
|
||||
<div class="reply-message">这是回复的消息[预留]</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'ReplyMessage',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
created() {},
|
||||
methods: {},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.reply-message {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="revoke-message">
|
||||
<div class="content">
|
||||
<span v-if="$store.state.user.id == item.user_id">
|
||||
<span v-if="userStore.id == item.user_id">
|
||||
你撤回了一条消息 | {{ sendTime(item.created_at) }}
|
||||
</span>
|
||||
<span v-else-if="item.talk_type == 1">
|
||||
@@ -13,20 +13,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { formatTime as sendTime } from "@/utils/functions";
|
||||
|
||||
export default {
|
||||
defineOptions({
|
||||
name: "RevokeMessage",
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
});
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
methods: {
|
||||
sendTime,
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.revoke-message {
|
||||
|
||||
@@ -3,18 +3,14 @@
|
||||
<div class="content">{{ content }}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { formatTime as sendTime } from '@/utils/functions'
|
||||
|
||||
export default {
|
||||
name: 'SystemTextMessage',
|
||||
props: {
|
||||
content: String,
|
||||
},
|
||||
methods: {
|
||||
sendTime,
|
||||
},
|
||||
}
|
||||
defineOptions({ name: 'SystemTextMessage' })
|
||||
|
||||
defineProps({
|
||||
content: String,
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.system-text-message {
|
||||
|
||||
@@ -8,44 +8,42 @@
|
||||
<pre v-html="html" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { textReplaceLink } from "@/utils/functions";
|
||||
import { textReplaceEmoji } from "@/utils/emojis";
|
||||
|
||||
export default {
|
||||
defineOptions({
|
||||
name: "TextMessage",
|
||||
props: {
|
||||
content: {
|
||||
type: [String, Number],
|
||||
default: "",
|
||||
},
|
||||
float: {
|
||||
type: String,
|
||||
default: "left",
|
||||
},
|
||||
fullWidth: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
html: "",
|
||||
};
|
||||
},
|
||||
created () {
|
||||
const text = textReplaceLink(
|
||||
this.content,
|
||||
this.float == "right" ? "#ffffff" : "rgb(9 149 208)"
|
||||
);
|
||||
});
|
||||
|
||||
this.html = textReplaceEmoji(text);
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: [String, Number],
|
||||
default: "",
|
||||
},
|
||||
};
|
||||
float: {
|
||||
type: String,
|
||||
default: "left",
|
||||
},
|
||||
fullWidth: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
arrow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
|
||||
const html = ref("");
|
||||
|
||||
const text = textReplaceLink(
|
||||
props.content,
|
||||
props.float == "right" ? "#ffffff" : "rgb(9 149 208)"
|
||||
);
|
||||
|
||||
html.value = textReplaceEmoji(text);
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@bg-left-color: #f5f5f5;
|
||||
|
||||
@@ -2,18 +2,7 @@
|
||||
<!-- 用户卡片消息 - 预留 -->
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'UserCardMessage',
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
methods: {},
|
||||
created() {},
|
||||
}
|
||||
<script setup>
|
||||
defineOptions({ name: 'UserCardMessage' })
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -4,15 +4,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'VideoMessage',
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {},
|
||||
created() {},
|
||||
}
|
||||
<script setup>
|
||||
defineOptions({ name: 'VideoMessage' })
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -20,27 +20,27 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'VisitCardMessage',
|
||||
data() {
|
||||
return {
|
||||
userId: 0,
|
||||
friendId: 0,
|
||||
avatar:
|
||||
'http://im-serve0.gzydong.club/static/image/sys-head/2019012107542668696.jpg',
|
||||
sign:
|
||||
'这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。',
|
||||
nickname:
|
||||
'氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳',
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
methods: {
|
||||
openVisitCard(user_id) {
|
||||
this.$emit('openVisitCard', user_id)
|
||||
},
|
||||
},
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
defineOptions({ name: 'VisitCardMessage' });
|
||||
|
||||
const emit = defineEmits(['openVisitCard']);
|
||||
|
||||
const userId = ref(0);
|
||||
const friendId = ref(0);
|
||||
const avatar = ref(
|
||||
'http://im-serve0.gzydong.club/static/image/sys-head/2019012107542668696.jpg'
|
||||
);
|
||||
const sign = ref(
|
||||
'这个社会,是赢家通吃,输者一无所有,社会,永远都是只以成败论英雄。'
|
||||
);
|
||||
const nickname = ref(
|
||||
'氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳氨基酸纳'
|
||||
);
|
||||
|
||||
function openVisitCard(user_id) {
|
||||
emit('openVisitCard', user_id)
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
@@ -2,15 +2,9 @@
|
||||
<div class="voice-message"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: 'VoiceMessage',
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {},
|
||||
created() {},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -59,127 +59,128 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { ref, computed } from "vue";
|
||||
import { ServeConfirmVoteHandle } from "@/api/chat";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
|
||||
export default {
|
||||
name: "VoteMessage",
|
||||
props: {
|
||||
vote: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
answer_mode: 0,
|
||||
title: "啊谁叫你打开你卡沙发那,那就是看、卡收纳是你",
|
||||
radio_value: "",
|
||||
options: [],
|
||||
is_vote: false,
|
||||
answer_num: 0,
|
||||
answered_num: 0,
|
||||
refresh: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isUserVote() {
|
||||
return this.options.some((iten) => {
|
||||
return iten.is_checked;
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
let user_id = this.$store.state.user.id;
|
||||
let { detail, statistics, vote_users } = this.vote;
|
||||
defineOptions({ name: "VoteMessage" });
|
||||
|
||||
this.answer_mode = detail.answer_mode;
|
||||
this.answer_num = detail.answer_num;
|
||||
this.answered_num = detail.answered_num;
|
||||
const props = defineProps({
|
||||
vote: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
record_id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
detail.answer_option.forEach((item) => {
|
||||
this.options.push({
|
||||
value: item.key,
|
||||
text: item.value,
|
||||
is_checked: false,
|
||||
num: 0,
|
||||
progress: "00.0",
|
||||
});
|
||||
const userStore = useUserStore();
|
||||
|
||||
const answer_mode = ref(0);
|
||||
const title = ref("啊谁叫你打开你卡沙发那,那就是看、卡收纳是你");
|
||||
const radio_value = ref("");
|
||||
const options = ref([]);
|
||||
const is_vote = ref(false);
|
||||
const answer_num = ref(0);
|
||||
const answered_num = ref(0);
|
||||
const refresh = ref(false);
|
||||
|
||||
const isUserVote = computed(() => {
|
||||
return options.value.some((iten) => {
|
||||
return iten.is_checked;
|
||||
});
|
||||
});
|
||||
|
||||
function loadRefresh() {
|
||||
refresh.value = true;
|
||||
|
||||
setTimeout(() => {
|
||||
refresh.value = false;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function updateStatistics(data) {
|
||||
let count = data.count;
|
||||
options.value.forEach((option) => {
|
||||
option.num = data.options[option.value];
|
||||
|
||||
if (count > 0) {
|
||||
option.progress = (data.options[option.value] / count) * 100;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toSelect(option, index) {
|
||||
if (answer_mode.value == 0) {
|
||||
options.value.forEach((option) => {
|
||||
option.is_checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
this.is_vote = vote_users.some((value) => {
|
||||
return value == user_id;
|
||||
options.value[index].is_checked = !option.is_checked;
|
||||
}
|
||||
|
||||
function toSelect2(option) {
|
||||
if (answer_mode.value == 0) {
|
||||
options.value.forEach((item) => {
|
||||
if (option.value == item.value) {
|
||||
item.is_checked = option.is_checked;
|
||||
} else {
|
||||
item.is_checked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.updateStatistics(statistics);
|
||||
},
|
||||
methods: {
|
||||
loadRefresh() {
|
||||
this.refresh = true;
|
||||
function toVote() {
|
||||
if (isUserVote.value == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.refresh = false;
|
||||
}, 500);
|
||||
},
|
||||
updateStatistics(data) {
|
||||
let count = data.count;
|
||||
this.options.forEach((option) => {
|
||||
option.num = data.options[option.value];
|
||||
let items = [];
|
||||
options.value.forEach((item) => {
|
||||
if (item.is_checked) {
|
||||
items.push(item.value);
|
||||
}
|
||||
});
|
||||
|
||||
if (count > 0) {
|
||||
option.progress = (data.options[option.value] / count) * 100;
|
||||
}
|
||||
});
|
||||
},
|
||||
ServeConfirmVoteHandle({
|
||||
record_id: props.record_id,
|
||||
options: items.join(","),
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
is_vote.value = true;
|
||||
updateStatistics(res.data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toSelect(option, index) {
|
||||
if (this.answer_mode == 0) {
|
||||
this.options.forEach((option) => {
|
||||
option.is_checked = false;
|
||||
});
|
||||
}
|
||||
// 原 created() 生命周期逻辑
|
||||
let user_id = userStore.id;
|
||||
let { detail, statistics, vote_users } = props.vote;
|
||||
|
||||
this.options[index].is_checked = !option.is_checked;
|
||||
},
|
||||
toSelect2(option) {
|
||||
if (this.answer_mode == 0) {
|
||||
this.options.forEach((item) => {
|
||||
if (option.value == item.value) {
|
||||
item.is_checked = option.is_checked;
|
||||
} else {
|
||||
item.is_checked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
toVote() {
|
||||
if (this.isUserVote == false) {
|
||||
return false;
|
||||
}
|
||||
answer_mode.value = detail.answer_mode;
|
||||
answer_num.value = detail.answer_num;
|
||||
answered_num.value = detail.answered_num;
|
||||
|
||||
let items = [];
|
||||
this.options.forEach((item) => {
|
||||
if (item.is_checked) {
|
||||
items.push(item.value);
|
||||
}
|
||||
});
|
||||
detail.answer_option.forEach((item) => {
|
||||
options.value.push({
|
||||
value: item.key,
|
||||
text: item.value,
|
||||
is_checked: false,
|
||||
num: 0,
|
||||
progress: "00.0",
|
||||
});
|
||||
});
|
||||
|
||||
ServeConfirmVoteHandle({
|
||||
record_id: this.record_id,
|
||||
options: items.join(","),
|
||||
}).then((res) => {
|
||||
if (res.code == 200) {
|
||||
this.is_vote = true;
|
||||
this.updateStatistics(res.data);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
is_vote.value = vote_users.some((value) => {
|
||||
return value == user_id;
|
||||
});
|
||||
|
||||
updateStatistics(statistics);
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.vote-message {
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import { computed, nextTick, onMounted, reactive, ref, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import {
|
||||
ServeGetStoreDetail,
|
||||
ServeGetFootPrint,
|
||||
@@ -29,255 +31,258 @@ import StoreDetail from "@/components/chat/panel/template/storeDetail.vue";
|
||||
import FootPrint from "@/components/chat/panel/template/footPrint.vue";
|
||||
import GoodsLink from "@/components/chat/panel/template/goodsLink.vue";
|
||||
import SocketInstance from "@/im-server/socket-instance";
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import { useTalkStore } from "@/stores/talk";
|
||||
import { useDialogueStore } from "@/stores/dialogue";
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { isBuyerImMode } from "@/utils/im-mode";
|
||||
// 与 computed 属性同名,改用别名导入
|
||||
import { isBuyerImMode as isBuyerImModeFn } from "@/utils/im-mode";
|
||||
|
||||
const SIDE_REQUEST_OPTIONS = { skipAuthDialog: true };
|
||||
|
||||
export default {
|
||||
components: {
|
||||
StoreDetail,
|
||||
FootPrint,
|
||||
GoodsLink,
|
||||
const props = defineProps({
|
||||
toUser: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
props: {
|
||||
toUser: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
goodsParams: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["talkItems"]),
|
||||
...mapState({
|
||||
index_name: (state) => state.dialogue.index_name,
|
||||
}),
|
||||
isBuyerImMode() {
|
||||
return isBuyerImMode(this.$route);
|
||||
},
|
||||
goodsParams: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
watch: {
|
||||
toUser() {
|
||||
this.syncStoreFlagCache();
|
||||
this.resetSidePanelData();
|
||||
if (this.toUser.storeFlag) {
|
||||
this.getStoreDetail();
|
||||
}
|
||||
this.getFootPrint();
|
||||
if (this.goodsParams && this.toUser.storeFlag) {
|
||||
this.getGoodsDetail();
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: "history",
|
||||
storeInfo: {},
|
||||
memberInfo: {},
|
||||
footPrintParams: {
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
memberId: "",
|
||||
storeId: "",
|
||||
},
|
||||
goodsDetail: {},
|
||||
footPrintList: [],
|
||||
orderPrintList: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.syncStoreFlagCache();
|
||||
if (this.toUser.storeFlag) {
|
||||
this.getStoreDetail();
|
||||
});
|
||||
|
||||
const talkStore = useTalkStore();
|
||||
const dialogueStore = useDialogueStore();
|
||||
const route = useRoute();
|
||||
|
||||
const activeName = ref("history");
|
||||
const storeInfo = ref({});
|
||||
const memberInfo = ref({});
|
||||
const footPrintParams = reactive({
|
||||
pageSize: 20,
|
||||
pageNumber: 1,
|
||||
memberId: "",
|
||||
storeId: "",
|
||||
});
|
||||
const goodsDetail = ref({});
|
||||
const footPrintList = ref([]);
|
||||
const orderPrintList = ref([]);
|
||||
|
||||
const talkItems = computed(() => talkStore.talkItems);
|
||||
const index_name = computed(() => dialogueStore.index_name);
|
||||
const isBuyerImMode = computed(() => isBuyerImModeFn(route));
|
||||
|
||||
watch(
|
||||
() => props.toUser,
|
||||
() => {
|
||||
syncStoreFlagCache();
|
||||
resetSidePanelData();
|
||||
if (props.toUser.storeFlag) {
|
||||
getStoreDetail();
|
||||
}
|
||||
this.getFootPrint();
|
||||
if (this.goodsParams && this.toUser.storeFlag) {
|
||||
this.getGoodsDetail();
|
||||
getFootPrint();
|
||||
if (props.goodsParams && props.toUser.storeFlag) {
|
||||
getGoodsDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
syncStoreFlagCache() {
|
||||
localStorage.setItem(
|
||||
"storeFlag",
|
||||
this.isBuyerImMode ? "true" : "false"
|
||||
);
|
||||
},
|
||||
resetSidePanelData() {
|
||||
this.footPrintList = [];
|
||||
this.orderPrintList = [];
|
||||
this.footPrintParams.pageNumber = 1;
|
||||
},
|
||||
getStoreDetail() {
|
||||
ServeGetStoreDetail(this.toUser.userId, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.storeInfo = res.result;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
loadMoreFootPrint() {
|
||||
this.footPrintParams.pageNumber++;
|
||||
this.getFootPrint();
|
||||
},
|
||||
handleClick() {},
|
||||
getGoodsDetail() {
|
||||
if (!this.toUser.storeFlag) {
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
syncStoreFlagCache();
|
||||
if (props.toUser.storeFlag) {
|
||||
getStoreDetail();
|
||||
}
|
||||
getFootPrint();
|
||||
if (props.goodsParams && props.toUser.storeFlag) {
|
||||
getGoodsDetail();
|
||||
}
|
||||
});
|
||||
|
||||
function syncStoreFlagCache() {
|
||||
localStorage.setItem(
|
||||
"storeFlag",
|
||||
isBuyerImMode.value ? "true" : "false"
|
||||
);
|
||||
}
|
||||
|
||||
function resetSidePanelData() {
|
||||
footPrintList.value = [];
|
||||
orderPrintList.value = [];
|
||||
footPrintParams.pageNumber = 1;
|
||||
}
|
||||
|
||||
function getStoreDetail() {
|
||||
ServeGetStoreDetail(props.toUser.userId, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
storeInfo.value = res.result;
|
||||
}
|
||||
if (!this.goodsParams || !this.goodsParams.goodsId) {
|
||||
return;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function loadMoreFootPrint() {
|
||||
footPrintParams.pageNumber++;
|
||||
getFootPrint();
|
||||
}
|
||||
|
||||
function handleClick() {}
|
||||
|
||||
function getGoodsDetail() {
|
||||
if (!props.toUser.storeFlag) {
|
||||
return;
|
||||
}
|
||||
if (!props.goodsParams || !props.goodsParams.goodsId) {
|
||||
return;
|
||||
}
|
||||
ServeGetGoodsDetail(props.goodsParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
goodsDetail.value = res.result.data;
|
||||
}
|
||||
ServeGetGoodsDetail(this.goodsParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res.success) {
|
||||
this.goodsDetail = res.result.data;
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
normalizeFootPrintRecords(records = []) {
|
||||
const goodsId = this.goodsParams?.goodsId;
|
||||
return records
|
||||
.filter((item) => item != null)
|
||||
.filter((item) => !goodsId || item.goodsId !== goodsId)
|
||||
.map((item) => ({
|
||||
...item,
|
||||
btnHide: localStorage.getItem(item.goodsId) ? 0 : 1,
|
||||
}));
|
||||
},
|
||||
normalizeOrderRecords(records = []) {
|
||||
return records.map((item) => ({
|
||||
...item,
|
||||
btnHide: 1,
|
||||
}));
|
||||
},
|
||||
getFootPrint() {
|
||||
if (!getToken()) {
|
||||
return;
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function normalizeFootPrintRecords(records = []) {
|
||||
const goodsId = props.goodsParams?.goodsId;
|
||||
return records
|
||||
.filter((item) => item != null)
|
||||
.filter((item) => !goodsId || item.goodsId !== goodsId)
|
||||
.map((item) => ({
|
||||
...item,
|
||||
btnHide: localStorage.getItem(item.goodsId) ? 0 : 1,
|
||||
}));
|
||||
}
|
||||
|
||||
function normalizeOrderRecords(records = []) {
|
||||
return records.map((item) => ({
|
||||
...item,
|
||||
btnHide: 1,
|
||||
}));
|
||||
}
|
||||
|
||||
function getFootPrint() {
|
||||
if (!getToken()) {
|
||||
return;
|
||||
}
|
||||
if (!props.toUser?.userId || !props.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBuyerImMode.value) {
|
||||
footPrintParams.memberId = props.id;
|
||||
footPrintParams.storeId = props.toUser.userId;
|
||||
fetchBuyerSideData();
|
||||
} else {
|
||||
footPrintParams.memberId = props.toUser.userId;
|
||||
footPrintParams.storeId = props.id;
|
||||
fetchStoreSideData();
|
||||
}
|
||||
}
|
||||
|
||||
function fetchBuyerSideData() {
|
||||
ServeGetFootPrint(footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
footPrintList.value.push(
|
||||
...normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
if (!this.toUser?.userId || !this.id) {
|
||||
return;
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
ServeGetOrderPrint(footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
orderPrintList.value.push(
|
||||
...normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
if (this.isBuyerImMode) {
|
||||
this.footPrintParams.memberId = this.id;
|
||||
this.footPrintParams.storeId = this.toUser.userId;
|
||||
this.fetchBuyerSideData();
|
||||
} else {
|
||||
this.footPrintParams.memberId = this.toUser.userId;
|
||||
this.footPrintParams.storeId = this.id;
|
||||
this.fetchStoreSideData();
|
||||
function fetchStoreSideData() {
|
||||
ServeStoreGetFootPrint(footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
footPrintList.value.push(
|
||||
...normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
},
|
||||
fetchBuyerSideData() {
|
||||
ServeGetFootPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
this.footPrintList.push(
|
||||
...this.normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
ServeGetOrderPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
this.orderPrintList.push(
|
||||
...this.normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
fetchStoreSideData() {
|
||||
ServeStoreGetFootPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.result?.records) {
|
||||
this.footPrintList.push(
|
||||
...this.normalizeFootPrintRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
ServeStoreGetOrderPrint(this.footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
this.orderPrintList.push(
|
||||
...this.normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
submitSendMessage(record, context, messageType) {
|
||||
SocketInstance.emit("event_talk", record);
|
||||
this.$store.commit("UPDATE_TALK_ITEM", {
|
||||
index_name: this.index_name,
|
||||
draft_text: "",
|
||||
});
|
||||
const insterChat = {
|
||||
createTime: this.formateDateAndTimeToString(new Date()),
|
||||
fromUser: this.id,
|
||||
toUser: record.to,
|
||||
isRead: false,
|
||||
messageType: messageType,
|
||||
text: context,
|
||||
float: "right",
|
||||
};
|
||||
|
||||
this.$store.commit("PUSH_DIALOGUE", insterChat);
|
||||
let el = document.getElementById("lumenChatPanel");
|
||||
let isBottom =
|
||||
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
||||
|
||||
if (isBottom || record.to == this.id) {
|
||||
this.$nextTick(() => {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
} else {
|
||||
this.$store.commit("SET_TLAK_UNREAD_MESSAGE", {
|
||||
content: context,
|
||||
nickname: record.name,
|
||||
});
|
||||
ServeStoreGetOrderPrint(footPrintParams, SIDE_REQUEST_OPTIONS)
|
||||
.then((res) => {
|
||||
if (res?.code === 200 && res?.result?.records) {
|
||||
orderPrintList.value.push(
|
||||
...normalizeOrderRecords(res.result.records)
|
||||
);
|
||||
}
|
||||
},
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
formateDateAndTimeToString(date) {
|
||||
var hours = date.getHours();
|
||||
var mins = date.getMinutes();
|
||||
var secs = date.getSeconds();
|
||||
var msecs = date.getMilliseconds();
|
||||
if (hours < 10) hours = "0" + hours;
|
||||
if (mins < 10) mins = "0" + mins;
|
||||
if (secs < 10) secs = "0" + secs;
|
||||
if (msecs < 10) secs = "0" + msecs;
|
||||
return (
|
||||
this.formatDateToString(date) + " " + hours + ":" + mins + ":" + secs
|
||||
);
|
||||
},
|
||||
function submitSendMessage(record, context, messageType) {
|
||||
SocketInstance.emit("event_talk", record);
|
||||
talkStore.UPDATE_TALK_ITEM({
|
||||
index_name: index_name.value,
|
||||
draft_text: "",
|
||||
});
|
||||
const insterChat = {
|
||||
createTime: formateDateAndTimeToString(new Date()),
|
||||
fromUser: props.id,
|
||||
toUser: record.to,
|
||||
isRead: false,
|
||||
messageType: messageType,
|
||||
text: context,
|
||||
float: "right",
|
||||
};
|
||||
|
||||
formatDateToString(date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
if (month < 10) month = "0" + month;
|
||||
if (day < 10) day = "0" + day;
|
||||
return year + "-" + month + "-" + day;
|
||||
},
|
||||
},
|
||||
};
|
||||
dialogueStore.PUSH_DIALOGUE(insterChat);
|
||||
let el = document.getElementById("lumenChatPanel");
|
||||
let isBottom =
|
||||
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
||||
|
||||
if (isBottom || record.to == props.id) {
|
||||
nextTick(() => {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
} else {
|
||||
talkStore.SET_TLAK_UNREAD_MESSAGE({
|
||||
content: context,
|
||||
nickname: record.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function formateDateAndTimeToString(date) {
|
||||
var hours = date.getHours();
|
||||
var mins = date.getMinutes();
|
||||
var secs = date.getSeconds();
|
||||
var msecs = date.getMilliseconds();
|
||||
if (hours < 10) hours = "0" + hours;
|
||||
if (mins < 10) mins = "0" + mins;
|
||||
if (secs < 10) secs = "0" + secs;
|
||||
if (msecs < 10) secs = "0" + msecs;
|
||||
return (
|
||||
formatDateToString(date) + " " + hours + ":" + mins + ":" + secs
|
||||
);
|
||||
}
|
||||
|
||||
function formatDateToString(date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
if (month < 10) month = "0" + month;
|
||||
if (day < 10) day = "0" + day;
|
||||
return year + "-" + month + "-" + day;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
@@ -39,75 +39,89 @@
|
||||
</div>
|
||||
</el-header>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
params: 0,
|
||||
nickname: '',
|
||||
}
|
||||
},
|
||||
},
|
||||
online: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
keyboard: {
|
||||
type: [Boolean, Number],
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
params: {
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
params: 0,
|
||||
nickname: '',
|
||||
},
|
||||
isOnline: false,
|
||||
isKeyboard: false,
|
||||
groupNum: 0,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.setParamsData(this.data)
|
||||
this.setOnlineStatus(this.online)
|
||||
},
|
||||
watch: {
|
||||
data(value) {
|
||||
this.setParamsData(value)
|
||||
},
|
||||
online(value) {
|
||||
this.setOnlineStatus(value)
|
||||
},
|
||||
keyboard(value) {
|
||||
this.isKeyboard = value
|
||||
setTimeout(() => {
|
||||
this.isKeyboard = false
|
||||
}, 2000)
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setOnlineStatus(value) {
|
||||
this.isOnline = value
|
||||
},
|
||||
setParamsData(object) {
|
||||
Object.assign(this.params, object)
|
||||
},
|
||||
setGroupNum(value) {
|
||||
this.groupNum = value
|
||||
},
|
||||
triggerEvent(event_name) {
|
||||
this.$emit('event', event_name)
|
||||
},
|
||||
online: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
keyboard: {
|
||||
type: [Boolean, Number],
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['event'])
|
||||
|
||||
const params = reactive({
|
||||
talk_type: 0,
|
||||
receiver_id: 0,
|
||||
params: 0,
|
||||
nickname: '',
|
||||
})
|
||||
const isOnline = ref(false)
|
||||
const isKeyboard = ref(false)
|
||||
const groupNum = ref(0)
|
||||
|
||||
// created 钩子
|
||||
setParamsData(props.data)
|
||||
setOnlineStatus(props.online)
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(value) => {
|
||||
setParamsData(value)
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.online,
|
||||
(value) => {
|
||||
setOnlineStatus(value)
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.keyboard,
|
||||
(value) => {
|
||||
isKeyboard.value = value
|
||||
setTimeout(() => {
|
||||
isKeyboard.value = false
|
||||
}, 2000)
|
||||
}
|
||||
)
|
||||
|
||||
function setOnlineStatus(value) {
|
||||
isOnline.value = value
|
||||
}
|
||||
|
||||
function setParamsData(object) {
|
||||
Object.assign(params, object)
|
||||
}
|
||||
|
||||
function setGroupNum(value) {
|
||||
groupNum.value = value
|
||||
}
|
||||
|
||||
function triggerEvent(event_name) {
|
||||
emit('event', event_name)
|
||||
}
|
||||
|
||||
// 父组件 TalkPanel 通过 $refs.panelHeader.setGroupNum() 访问
|
||||
defineExpose({ setGroupNum })
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
#panel-header {
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
default: 0,
|
||||
},
|
||||
<script setup>
|
||||
defineProps({
|
||||
value: {
|
||||
default: 0,
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
defineEmits(["event"]);
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.multi-select {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -76,116 +76,115 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useTalkStore } from "@/stores/talk";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
noMoreList:{
|
||||
'goods':{title:'暂无最近浏览',value:false},
|
||||
'orders':{title:'暂无订单信息',value:false},
|
||||
},
|
||||
activeName: 'goods',
|
||||
btnHide: undefined,
|
||||
hide: true,
|
||||
col: {
|
||||
CANCELLED: 'danger',
|
||||
PAID: 'danger',
|
||||
TAKE: '',
|
||||
COMPLETED: 'success',
|
||||
DELIVERED: 'danger',
|
||||
UNDELIVERED: 'warning',
|
||||
UNPAID: '',
|
||||
STAY_PICKED_UP: ''
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["talkItems"]),
|
||||
...mapState({
|
||||
id: (state) => state.user.id,
|
||||
toUser: (state) => state.user.toUser,
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
//跳转订单列表
|
||||
const talkStore = useTalkStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
scrollBottom (e) {
|
||||
const { scrollTop, scrollHeight, clientHeight } = e.srcElement
|
||||
if (scrollTop + clientHeight >= scrollHeight) {
|
||||
this.$emit('loadMore')
|
||||
}
|
||||
},
|
||||
loadMore () {
|
||||
const emit = defineEmits(["loadMore", "sendMessage"]);
|
||||
|
||||
},
|
||||
// 发送消息回调事件
|
||||
submitSendGoodsMessage (item) {
|
||||
const context = {
|
||||
id: item.id,
|
||||
goodsId: item.goodsId,
|
||||
thumbnail: item.thumbnail,
|
||||
price: item.price,
|
||||
goodsName: item.goodsName
|
||||
}
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.id,
|
||||
message_type: "GOODS",
|
||||
context: context,
|
||||
talk_id: this.toUser.id,
|
||||
};
|
||||
this.$emit('sendMessage', record, context, 'GOODS');
|
||||
localStorage.setItem(item.goodsId, 0)
|
||||
item.btnHide = 0
|
||||
},
|
||||
// 发送订单列表
|
||||
submitSendOrderMessage (item, index) {
|
||||
console.log(item, 'item');
|
||||
|
||||
const context = {
|
||||
sn: item.sn,
|
||||
groupImages: item.groupImages,
|
||||
paymentTime: item.paymentTime,
|
||||
groupName: item.groupName,
|
||||
flowPrice: item.flowPrice,
|
||||
orderItems:item.orderItems,
|
||||
orderStatus: item.orderStatus
|
||||
}
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.id,
|
||||
message_type: "ORDER",
|
||||
context: context,
|
||||
talk_id: this.toUser.id,
|
||||
};
|
||||
this.$emit('sendMessage', record, context, 'ORDER');
|
||||
localStorage.setItem(item.goodsId, 0)
|
||||
item.btnHide = 0
|
||||
},
|
||||
handleClick (tab, event) {
|
||||
|
||||
}
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
props: {
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
orderList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
orderList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
mounted () {
|
||||
// state.user.toUser
|
||||
// console.log(this.orderList, ' this.$store.state.user.toUser this.$store.state.user.toUser this.$store.state.user.toUser');
|
||||
this.btnHide = localStorage.getItem('btnHide')
|
||||
});
|
||||
|
||||
const noMoreList = ref({
|
||||
'goods': { title: '暂无最近浏览', value: false },
|
||||
'orders': { title: '暂无订单信息', value: false },
|
||||
});
|
||||
const activeName = ref('goods');
|
||||
const btnHide = ref(undefined);
|
||||
const hide = ref(true);
|
||||
const col = ref({
|
||||
CANCELLED: 'danger',
|
||||
PAID: 'danger',
|
||||
TAKE: '',
|
||||
COMPLETED: 'success',
|
||||
DELIVERED: 'danger',
|
||||
UNDELIVERED: 'warning',
|
||||
UNPAID: '',
|
||||
STAY_PICKED_UP: ''
|
||||
});
|
||||
|
||||
const talkItems = computed(() => talkStore.talkItems);
|
||||
const id = computed(() => userStore.id);
|
||||
const toUser = computed(() => userStore.toUser);
|
||||
|
||||
//跳转订单列表
|
||||
|
||||
function scrollBottom (e) {
|
||||
const { scrollTop, scrollHeight, clientHeight } = e.srcElement
|
||||
if (scrollTop + clientHeight >= scrollHeight) {
|
||||
emit('loadMore')
|
||||
}
|
||||
}
|
||||
function loadMore () {
|
||||
|
||||
}
|
||||
// 发送消息回调事件
|
||||
function submitSendGoodsMessage (item) {
|
||||
const context = {
|
||||
id: item.id,
|
||||
goodsId: item.goodsId,
|
||||
thumbnail: item.thumbnail,
|
||||
price: item.price,
|
||||
goodsName: item.goodsName
|
||||
}
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: toUser.value.userId,
|
||||
from: id.value,
|
||||
message_type: "GOODS",
|
||||
context: context,
|
||||
talk_id: toUser.value.id,
|
||||
};
|
||||
emit('sendMessage', record, context, 'GOODS');
|
||||
localStorage.setItem(item.goodsId, 0)
|
||||
item.btnHide = 0
|
||||
}
|
||||
// 发送订单列表
|
||||
function submitSendOrderMessage (item, index) {
|
||||
console.log(item, 'item');
|
||||
|
||||
const context = {
|
||||
sn: item.sn,
|
||||
groupImages: item.groupImages,
|
||||
paymentTime: item.paymentTime,
|
||||
groupName: item.groupName,
|
||||
flowPrice: item.flowPrice,
|
||||
orderItems:item.orderItems,
|
||||
orderStatus: item.orderStatus
|
||||
}
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: toUser.value.userId,
|
||||
from: id.value,
|
||||
message_type: "ORDER",
|
||||
context: context,
|
||||
talk_id: toUser.value.id,
|
||||
};
|
||||
emit('sendMessage', record, context, 'ORDER');
|
||||
localStorage.setItem(item.goodsId, 0)
|
||||
item.btnHide = 0
|
||||
}
|
||||
function handleClick (tab, event) {
|
||||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// state.user.toUser
|
||||
// console.log(this.orderList, ' this.$store.state.user.toUser this.$store.state.user.toUser this.$store.state.user.toUser');
|
||||
btnHide.value = localStorage.getItem('btnHide')
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -19,125 +19,124 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
<script setup>
|
||||
import { computed, onMounted, nextTick, ref } from "vue";
|
||||
import SocketInstance from "@/im-server/socket-instance";
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
btnHide: undefined,
|
||||
hide: true
|
||||
}
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { useDialogueStore } from "@/stores/dialogue";
|
||||
import { useTalkStore } from "@/stores/talk";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const dialogueStore = useDialogueStore();
|
||||
const talkStore = useTalkStore();
|
||||
|
||||
const props = defineProps({
|
||||
goodsDetail: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["talkItems"]),
|
||||
...mapState({
|
||||
id: (state) => state.user.id,
|
||||
index_name: (state) => state.dialogue.index_name,
|
||||
toUser: (state) => state.user.toUser,
|
||||
}),
|
||||
},
|
||||
mounted () {
|
||||
console.log(this.goodsDetail)
|
||||
this.btnHide = localStorage.getItem('btnHide')
|
||||
},
|
||||
methods: {
|
||||
toGoods () {
|
||||
alert("toGoods")
|
||||
},
|
||||
toMessage () {
|
||||
alert(JSON.stringify(this.toUser))
|
||||
alert("toMessage")
|
||||
},
|
||||
// 回车键发送消息回调事件
|
||||
submitSendMessage () {
|
||||
console.log("发送");
|
||||
const context = this.goodsDetail
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: this.toUser.userId,
|
||||
from: this.id,
|
||||
message_type: "GOODS",
|
||||
context: context,
|
||||
talk_id: this.toUser.id,
|
||||
};
|
||||
SocketInstance.emit("event_talk", record);
|
||||
});
|
||||
|
||||
this.$store.commit("UPDATE_TALK_ITEM", {
|
||||
index_name: this.index_name,
|
||||
draft_text: "",
|
||||
});
|
||||
const btnHide = ref(undefined);
|
||||
const hide = ref(true);
|
||||
|
||||
const talkItems = computed(() => talkStore.talkItems);
|
||||
const id = computed(() => userStore.id);
|
||||
const index_name = computed(() => dialogueStore.index_name);
|
||||
const toUser = computed(() => userStore.toUser);
|
||||
|
||||
onMounted(() => {
|
||||
console.log(props.goodsDetail)
|
||||
btnHide.value = localStorage.getItem('btnHide')
|
||||
});
|
||||
|
||||
function toGoods () {
|
||||
alert("toGoods")
|
||||
}
|
||||
function toMessage () {
|
||||
alert(JSON.stringify(toUser.value))
|
||||
alert("toMessage")
|
||||
}
|
||||
// 回车键发送消息回调事件
|
||||
function submitSendMessage () {
|
||||
console.log("发送");
|
||||
const context = props.goodsDetail
|
||||
const record = {
|
||||
operation_type: "MESSAGE",
|
||||
to: toUser.value.userId,
|
||||
from: id.value,
|
||||
message_type: "GOODS",
|
||||
context: context,
|
||||
talk_id: toUser.value.id,
|
||||
};
|
||||
SocketInstance.emit("event_talk", record);
|
||||
|
||||
talkStore.UPDATE_TALK_ITEM({
|
||||
index_name: index_name.value,
|
||||
draft_text: "",
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* 插入数据
|
||||
*/
|
||||
const insterChat = {
|
||||
createTime: this.formateDateAndTimeToString(new Date()),
|
||||
fromUser: this.id,
|
||||
toUser: record.to,
|
||||
isRead: false,
|
||||
messageType: "GOODS",
|
||||
text: context,
|
||||
float: "right",
|
||||
};
|
||||
/**
|
||||
* 插入数据
|
||||
*/
|
||||
const insterChat = {
|
||||
createTime: formateDateAndTimeToString(new Date()),
|
||||
fromUser: id.value,
|
||||
toUser: record.to,
|
||||
isRead: false,
|
||||
messageType: "GOODS",
|
||||
text: context,
|
||||
float: "right",
|
||||
};
|
||||
|
||||
console.log("insterChat", insterChat);
|
||||
// console.log("插入对话记录",'')
|
||||
// 插入对话记录
|
||||
this.$store.commit("PUSH_DIALOGUE", insterChat);
|
||||
// 获取聊天面板元素节点
|
||||
let el = document.getElementById("lumenChatPanel");
|
||||
// 判断的滚动条是否在底部
|
||||
let isBottom =
|
||||
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
||||
console.log("insterChat", insterChat);
|
||||
// console.log("插入对话记录",'')
|
||||
// 插入对话记录
|
||||
dialogueStore.PUSH_DIALOGUE(insterChat);
|
||||
// 获取聊天面板元素节点
|
||||
let el = document.getElementById("lumenChatPanel");
|
||||
// 判断的滚动条是否在底部
|
||||
let isBottom =
|
||||
Math.ceil(el.scrollTop) + el.clientHeight >= el.scrollHeight;
|
||||
|
||||
if (isBottom || record.to == this.id) {
|
||||
this.$nextTick(() => {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
} else {
|
||||
this.$store.commit("SET_TLAK_UNREAD_MESSAGE", {
|
||||
content: content,
|
||||
nickname: record.name,
|
||||
});
|
||||
}
|
||||
// 发送后隐藏按钮 0:隐藏 1:显示
|
||||
localStorage.setItem('btnHide', 0)
|
||||
this.hide = false
|
||||
},
|
||||
|
||||
formateDateAndTimeToString (date) {
|
||||
var hours = date.getHours();
|
||||
var mins = date.getMinutes();
|
||||
var secs = date.getSeconds();
|
||||
var msecs = date.getMilliseconds();
|
||||
if (hours < 10) hours = "0" + hours;
|
||||
if (mins < 10) mins = "0" + mins;
|
||||
if (secs < 10) secs = "0" + secs;
|
||||
if (msecs < 10) secs = "0" + msecs;
|
||||
return (
|
||||
this.formatDateToString(date) + " " + hours + ":" + mins + ":" + secs
|
||||
);
|
||||
},
|
||||
|
||||
formatDateToString (date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
if (month < 10) month = "0" + month;
|
||||
if (day < 10) day = "0" + day;
|
||||
return year + "-" + month + "-" + day;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
goodsDetail: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
if (isBottom || record.to == id.value) {
|
||||
nextTick(() => {
|
||||
el.scrollTop = el.scrollHeight;
|
||||
});
|
||||
} else {
|
||||
talkStore.SET_TLAK_UNREAD_MESSAGE({
|
||||
content: content,
|
||||
nickname: record.name,
|
||||
});
|
||||
}
|
||||
// 发送后隐藏按钮 0:隐藏 1:显示
|
||||
localStorage.setItem('btnHide', 0)
|
||||
hide.value = false
|
||||
}
|
||||
|
||||
function formateDateAndTimeToString (date) {
|
||||
var hours = date.getHours();
|
||||
var mins = date.getMinutes();
|
||||
var secs = date.getSeconds();
|
||||
var msecs = date.getMilliseconds();
|
||||
if (hours < 10) hours = "0" + hours;
|
||||
if (mins < 10) mins = "0" + mins;
|
||||
if (secs < 10) secs = "0" + secs;
|
||||
if (msecs < 10) secs = "0" + msecs;
|
||||
return (
|
||||
formatDateToString(date) + " " + hours + ":" + mins + ":" + secs
|
||||
);
|
||||
}
|
||||
|
||||
function formatDateToString (date) {
|
||||
var year = date.getFullYear();
|
||||
var month = date.getMonth() + 1;
|
||||
var day = date.getDate();
|
||||
if (month < 10) month = "0" + month;
|
||||
if (day < 10) day = "0" + day;
|
||||
return year + "-" + month + "-" + day;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
@@ -34,24 +34,18 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
value: null,
|
||||
colors: ['#99A9BF', '#F7BA2A', '#FF9900']
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
props: {
|
||||
storeInfo: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
}
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
defineProps({
|
||||
storeInfo: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const value = ref(null);
|
||||
const colors = ref(['#99A9BF', '#F7BA2A', '#FF9900']);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
Reference in New Issue
Block a user