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:
lifenlong
2026-10-13 07:06:59 +08:00
parent 870bacdd8c
commit 88fc1b0b2a
674 changed files with 71220 additions and 69943 deletions

View File

@@ -34,57 +34,55 @@
</div>
</div>
</template>
<script>
<script setup>
import { ref, nextTick, getCurrentInstance } from 'vue'
import { ServeSearchContact } from '@/api/contacts'
export default {
name: 'UserSearch',
data() {
return {
loading: false,
isShow: false,
mobile: '',
error: false,
}
},
methods: {
// 显示窗口
open() {
this.mobile = ''
this.isShow = true
this.$nextTick(() => {
document.getElementById('serach-mobile').focus()
})
},
defineOptions({ name: 'UserSearch' })
// 关闭窗口
close() {
this.isShow = false
},
const { proxy } = getCurrentInstance()
onSubmit() {
let { mobile } = this
const loading = ref(false)
const isShow = ref(false)
const mobile = ref('')
const error = ref(false)
if (mobile == '') return false
this.loading = true
ServeSearchContact({
mobile,
})
.then(res => {
if (res.code == 200) {
this.$user(res.data.id)
this.close()
} else {
this.error = true
}
})
.finally(() => {
this.loading = false
})
},
},
// 显示窗口
const open = () => {
mobile.value = ''
isShow.value = true
nextTick(() => {
document.getElementById('serach-mobile').focus()
})
}
// 关闭窗口
const close = () => {
isShow.value = false
}
const onSubmit = () => {
if (mobile.value == '') return false
loading.value = true
ServeSearchContact({
mobile: mobile.value,
})
.then(res => {
if (res.code == 200) {
proxy.$user(res.data.id)
close()
} else {
error.value = true
}
})
.finally(() => {
loading.value = false
})
}
// 父组件通过 ref 调用 open()(im/src/views/message/index.vue)
defineExpose({ open, close })
</script>
<style lang="less" scoped>
.lum-dialog-box {

View File

@@ -9,7 +9,7 @@
<div class="user-header">
<div class="avatar">
<div class="avatar-box">
<img :src="detail.avatar" :onerror="$store.state.defaultAvatar" />
<img :src="detail.avatar" :onerror="appStore.defaultAvatar" />
</div>
</div>
<div class="nickname">
@@ -121,136 +121,141 @@
</el-container>
</div>
</template>
<script>
<script setup>
// import { ServeSearchUser } from "@/api/user";
import { reactive, ref } from "vue";
import { ServeCreateContact, ServeEditContactRemark } from "@/api/contacts";
import { toTalk } from "@/utils/talk";
import { defaultUserBanner } from "@/assets/images";
import { ElMessage } from "@/utils/message";
import { useAppStore } from "@/stores/app";
export default {
name: "UserCardDetail",
props: {
user_id: {
type: Number,
default: 0,
},
defineOptions({ name: "UserCardDetail" });
const props = defineProps({
user_id: {
type: Number,
default: 0,
},
data() {
return {
detail: {
mobile: "",
nickname: "",
avatar: "",
motto: "",
friend_status: 0,
friend_apply: 0,
nickname_remark: "",
bag: defaultUserBanner,
gender: 0,
},
});
// 好友备注表单
editRemark: {
isShow: false,
text: "",
},
const emit = defineEmits(["close", "changeRemark"]);
// 好友申请表单
apply: {
isShow: false,
text: "",
},
const appStore = useAppStore();
contacts: false,
};
},
created() {
// this.loadUserDetail();
},
methods: {
formatGender(value) {
const arr = ["未知", "男", "女"];
return arr[value] || "未知";
},
formatMobile(value) {
if (!value) return "";
return (
value.substr(0, 3) + " " + value.substr(3, 4) + " " + value.substr(7, 4)
);
},
close() {
if (this.contacts) return false;
const detail = reactive({
mobile: "",
nickname: "",
avatar: "",
motto: "",
friend_status: 0,
friend_apply: 0,
nickname_remark: "",
bag: defaultUserBanner,
gender: 0,
});
this.$emit("close");
},
// 好友备注表单
const editRemark = reactive({
isShow: false,
text: "",
});
// 点击编辑备注信息
clickEditRemark() {
this.editRemark.isShow = true;
this.editRemark.text = this.detail.nickname_remark;
},
// 好友申请表单
const apply = reactive({
isShow: false,
text: "",
});
// 获取用户信息
// loadUserDetail() {
// ServeSearchUser({
// user_id: this.user_id,
// }).then((res) => {
// if (res.code == 200) {
// this.detail.user_id = res.data.id;
// Object.assign(this.detail, res.data);
// }
// });
// },
const contacts = ref(false);
// 发送添加好友申请
sendApply() {
if (this.apply.text == "") return;
ServeCreateContact({
friend_id: this.detail.user_id,
remark: this.apply.text,
}).then((res) => {
if (res.code == 200) {
this.apply.isShow = false;
this.apply.text = "";
this.detail.friend_apply = 1;
} else {
this.$message.error("发送好友申请失败,请稍后再试...");
}
});
},
// created() {
// loadUserDetail();
// }
// 编辑好友备注信息
editRemarkSubmit() {
let data = {
friend_id: this.detail.user_id,
remarks: this.editRemark.text,
};
const formatGender = (value) => {
const arr = ["未知", "男", "女"];
return arr[value] || "未知";
};
if (data.remarks == this.detail.nickname_remark) {
this.editRemark.isShow = false;
return;
}
const formatMobile = (value) => {
if (!value) return "";
return (
value.substr(0, 3) + " " + value.substr(3, 4) + " " + value.substr(7, 4)
);
};
ServeEditContactRemark(data).then((res) => {
if (res.code == 200) {
this.editRemark.isShow = false;
this.detail.nickname_remark = data.remarks;
this.$emit("changeRemark", data);
}
});
},
const close = () => {
if (contacts.value) return false;
// 隐藏申请表单
closeApply() {
this.apply.isShow = false;
},
emit("close");
};
// 发送好友消息
sendMessage() {
this.close();
toTalk(1, this.user_id);
},
},
// 点击编辑备注信息
const clickEditRemark = () => {
editRemark.isShow = true;
editRemark.text = detail.nickname_remark;
};
// 获取用户信息
// const loadUserDetail = () => {
// ServeSearchUser({
// user_id: props.user_id,
// }).then((res) => {
// if (res.code == 200) {
// detail.user_id = res.data.id;
// Object.assign(detail, res.data);
// }
// });
// };
// 发送添加好友申请
const sendApply = () => {
if (apply.text == "") return;
ServeCreateContact({
friend_id: detail.user_id,
remark: apply.text,
}).then((res) => {
if (res.code == 200) {
apply.isShow = false;
apply.text = "";
detail.friend_apply = 1;
} else {
ElMessage.error("发送好友申请失败,请稍后再试...");
}
});
};
// 编辑好友备注信息
const editRemarkSubmit = () => {
let data = {
friend_id: detail.user_id,
remarks: editRemark.text,
};
if (data.remarks == detail.nickname_remark) {
editRemark.isShow = false;
return;
}
ServeEditContactRemark(data).then((res) => {
if (res.code == 200) {
editRemark.isShow = false;
detail.nickname_remark = data.remarks;
emit("changeRemark", data);
}
});
};
// 隐藏申请表单
const closeApply = () => {
apply.isShow = false;
};
// 发送好友消息
const sendMessage = () => {
close();
toTalk(1, props.user_id);
};
</script>
<style lang="less" scoped>

View File

@@ -1,7 +1,7 @@
import { createApp, h } from "vue";
import UserCardDetail from "./UserCardDetail";
import router from "@/router";
import store from "@/store";
import { createPinia } from "pinia";
import { setupElementPlus } from "@/plugins/element";
import { setupLegacyMessage } from "@/utils/message";
import { registerDirectives } from "@/core/directives";
@@ -35,7 +35,7 @@ export default {
cardApp.component("legacy-el-icon", LegacyElIcon);
cardApp.config.globalProperties.$legacyIcon = resolveLegacyIcon;
cardApp.use(router);
cardApp.use(store);
cardApp.use(createPinia());
cardApp.mount(container);
}