Squashed commit of the following:

commit 0e84bedb67
Author: 浅念 <email@sample.com>
Date:   Fri Aug 15 16:31:55 2025 +0800

    v1.0.2 更新内容

commit f5deb7b8f7
Author: 浅念 <email@sample.com>
Date:   Wed Aug 13 19:27:49 2025 +0800

    添加菜单 权限 等页面

commit e797cb24de
Author: 浅念 <email@sample.com>
Date:   Mon Aug 11 19:24:24 2025 +0800

    添加工单附件  及样式

commit 619311dfbe
Author: chenlan <suya123456>
Date:   Fri Aug 8 22:13:25 2025 +0800

    添加crm  归属客户

commit b402e522bf
Author: 浅念 <email@sample.com>
Date:   Thu Aug 7 10:51:17 2025 +0800

    询单权限校验

commit f950f665a9
Author: 浅念 <email@sample.com>
Date:   Thu Aug 7 10:10:45 2025 +0800

    添加 询单图片预览

commit 8deecc8197
Author: 浅念 <email@sample.com>
Date:   Wed Aug 6 18:36:42 2025 +0800

    修改用户页面 询单

commit 3e24d1905f
Author: 浅念 <email@sample.com>
Date:   Tue Aug 5 18:25:32 2025 +0800

    添加用户页面 客户页面接口 等

commit 7542d80e38
Author: 浅念 <email@sample.com>
Date:   Mon Aug 4 18:05:07 2025 +0800

    修改 仪表盘页面样式

commit e5548f95e4
Author: 浅念 <email@sample.com>
Date:   Mon Aug 4 14:50:55 2025 +0800

    修改询单字段  仪表盘页面  及添加管理端客户页面

commit d30ea5b7bf
Author: 浅念 <email@sample.com>
Date:   Mon Aug 4 14:48:58 2025 +0800

    添加echarts 插件

commit 0e4160c5ca
Author: 浅念 <email@sample.com>
Date:   Fri Aug 1 18:27:22 2025 +0800

    仪表盘接口

commit bd23288acd
Author: 浅念 <email@sample.com>
Date:   Fri Aug 1 18:26:46 2025 +0800

    修改 仪表盘

commit 6bfb940881
Author: 浅念 <email@sample.com>
Date:   Fri Aug 1 10:01:35 2025 +0800

    客户列表 添加公海详情展示

commit b50f650565
Author: 浅念 <email@sample.com>
Date:   Thu Jul 31 17:26:36 2025 +0800

    修改 客户标签样式  个人信息添加邮箱 修复关闭全部页面404

commit ea1dbb7af4
Author: 浅念 <email@sample.com>
Date:   Wed Jul 30 18:50:31 2025 +0800

    修改公海和询单页面

commit 1bfbb95bd9
Author: 浅念 <email@sample.com>
Date:   Wed Jul 30 17:23:09 2025 +0800

    修改样式和添加用户数据显示

commit a9f5f76b35
Author: 浅念 <email@sample.com>
Date:   Wed Jul 30 15:06:03 2025 +0800

    设置默认页面

commit 3ea9d3d5df
Author: 浅念 <email@sample.com>
Date:   Wed Jul 30 11:46:31 2025 +0800

    修改飞书登录 公司id 系统id 获取不到问题  客户及公海添加用户信息显示

commit 0cef82279f
Author: 浅念 <email@sample.com>
Date:   Tue Jul 29 16:42:36 2025 +0800

    修改工单 客户等页面

commit 695ebbcc71
Author: 浅念 <email@sample.com>
Date:   Fri Jul 25 17:50:04 2025 +0800

    修改默认值

commit ffc194a1c1
Author: 浅念 <email@sample.com>
Date:   Fri Jul 25 17:05:33 2025 +0800

    飞书授权添加系统码  及登录进入页面路由

commit 48b95e252f
Author: 浅念 <email@sample.com>
Date:   Fri Jul 25 15:48:49 2025 +0800

    回收站添加占位

commit 382011d592
Author: 浅念 <email@sample.com>
Date:   Fri Jul 25 15:11:50 2025 +0800

    修改登录页样式公海数据 个人信息默认图

commit 0f790269db
Author: 浅念 <email@sample.com>
Date:   Fri Jul 25 09:16:55 2025 +0800

    修改字段名称

commit f18cfdb69e
Author: 浅念 <email@sample.com>
Date:   Thu Jul 24 17:28:51 2025 +0800

    调整代码格式

commit 858147fbbd
Author: 浅念 <email@sample.com>
Date:   Thu Jul 24 10:17:22 2025 +0800

    修改token刷新 及修改询单详情展示

commit c333b907e6
Author: 浅念 <email@sample.com>
Date:   Wed Jul 23 18:22:56 2025 +0800

    对接询单接口

commit 7979a31e36
Author: 浅念 <email@sample.com>
Date:   Wed Jul 23 14:40:02 2025 +0800

    修改代码格式

commit 4a39387865
Author: 浅念 <email@sample.com>
Date:   Wed Jul 23 14:07:13 2025 +0800

    设置客户列表权限

commit fc4de02582
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 17:08:13 2025 +0800

    feat(router): 调整菜单

commit 2ffe0c9753
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 17:04:16 2025 +0800

    feat(crmApi.ts): 调整结构

commit c3fb2c48d3
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 17:00:25 2025 +0800

    feat(router): 路由调整

commit c5b0a8265a
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 16:54:06 2025 +0800

    chore: 添加询单页面及调整菜单

commit ca06c9bc46
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 16:35:43 2025 +0800

    询单页面及菜单

commit 3b6de4c7fa
Merge: d3bb4ec 85e8b9b
Author: 浅念 <email@sample.com>
Date:   Tue Jul 22 09:22:20 2025 +0800

    Merge branch 'master' into feature/crm_pc

commit d3bb4ec6e5
Merge: c7d8908 d7ab6f1
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 18:22:55 2025 +0800

    Merge branch 'master' into feature/crm_pc

    # Conflicts:
    #	.gitignore
    #	src/api/crmApi.ts
    #	src/api/usersApi.ts
    #	src/store/modules/user.ts
    #	src/utils/http/index.ts
    #	src/views/auth/login/index.vue
    #	src/views/crmpc/customer/Show.vue
    #	src/views/crmpc/customer/index.vue

commit c7d890809c
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 18:12:16 2025 +0800

    添加系统码

commit 31cd18fade
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 18:02:48 2025 +0800

    Merge branch 'master' into feature/crm_pc

    # Conflicts:
    #	.gitignore

commit 59c9c97c08
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 17:56:52 2025 +0800

    Merge branch 'master' into feature/crm_pc

    # Conflicts:
    #	.gitignore

commit d4b577c42e
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 13:03:56 2025 +0800

    feat(crm): 添加相关图片

commit e4967760b7
Merge: 0c67666 85102fc
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 11:25:49 2025 +0800

    Finish crm_pc

commit 85102fcf32
Author: 浅念 <email@sample.com>
Date:   Mon Jul 21 11:24:06 2025 +0800

    crm 接口对接

commit 0c67666793
Author: 浅念 <email@sample.com>
Date:   Wed Jul 16 17:18:14 2025 +0800

    添加上传头部信息

commit a41c75f703
Author: 浅念 <email@sample.com>
Date:   Tue Jul 15 09:40:53 2025 +0800

    修改页面

commit 22ae0e86c8
Author: 浅念 <email@sample.com>
Date:   Mon Jul 14 17:59:02 2025 +0800

    修改页面

commit 812e3c4b0c
Author: 浅念 <email@sample.com>
Date:   Mon Jul 14 10:09:10 2025 +0800

    修改菜单问题

commit 2ad479b006
Author: 浅念 <email@sample.com>
Date:   Fri Jul 11 19:45:57 2025 +0800

    修改样式

commit 5802e157bf
Author: 浅念 <email@sample.com>
Date:   Fri Jul 11 19:43:34 2025 +0800

    修改工单

commit 713d43f7b4
Author: 浅念 <email@sample.com>
Date:   Fri Jul 11 18:37:16 2025 +0800

    添加登录

commit 719911918f
Author: 浅念 <email@sample.com>
Date:   Fri Jul 4 17:16:38 2025 +0800

    项目创建

commit ce47b39fa5
Author: 浅念 <email@sample.com>
Date:   Wed Jul 2 09:37:51 2025 +0800

    删除
This commit is contained in:
浅念
2025-08-15 16:37:41 +08:00
parent 85e8b9b6b4
commit 5d906087d3
66 changed files with 13539 additions and 2803 deletions
+533
View File
@@ -0,0 +1,533 @@
<template>
<div class="page-content user">
<div class="content">
<div class="left-wrap">
<div class="user-wrap box-style">
<!-- <img class="bg" src="@imgs/user/bg.webp" /> -->
<img
class="avatar"
:src="userInfo.avatar != '' ? userInfo.avatar : '/src/assets/img/user/avatar.webp'"
/>
<h2 class="name">{{ userInfo.name }}</h2>
<p class="des">SN:{{ userInfo.sn }}</p>
<div class="outer-info">
<!-- <div class="info-row">
<span class="info-label">昵 称:</span>
<span class="info-value">{{ userInfo.phone }}</span>
</div> -->
<div class="info-row">
<span class="info-label">电 话:</span>
<span class="info-value">{{ userInfo.phone }}</span>
</div>
<div class="info-row">
<span class="info-label">邮 箱:</span>
<span class="info-value">{{ userInfo.email }}</span>
</div>
<div class="info-row">
<span class="info-label">公 司:</span>
<span class="info-value">{{ userInfo.corp_name }}</span>
</div>
<!-- <div class="info-row">
<span class="info-label">国 家:</span>
<span class="info-value">{{ userInfo.country_txt }}</span>
</div> -->
</div>
</div>
</div>
<div class="right-wrap">
<div class="info box-style">
<h1 class="title"><span class="border" style="margin-right: 5px"></span>基本信息</h1>
<ElForm
:model="form"
class="form"
ref="ruleFormRef"
label-width="86px"
label-position="left"
>
<ElFormItem label="头像" prop="avatar">
<el-upload
class="qrcode-upload"
:action="actionImageUplode"
:headers="uploadHeaders"
:show-file-list="false"
:on-success="handleUploadavatar"
:disabled="!isEdit"
>
<div class="qrcode-upload-box">
<img
class="avatar"
:src="
imageUrlavatar != '' ? imageUrlavatar : '/src/assets/img/user/avatar.webp'
"
/>
</div>
</el-upload>
</ElFormItem>
<ElRow>
<ElFormItem label="昵称" prop="name">
<el-input v-model="form.name" :disabled="!isEdit" />
</ElFormItem>
<ElFormItem label="性别" prop="sex" class="right-input">
<ElSelect v-model="form.sex" placeholder="未知" :disabled="!isEdit">
<ElOption
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</ElSelect>
</ElFormItem>
</ElRow>
<ElRow>
<ElFormItem label="联系方式" prop="phone">
<ElInput v-model="form.phone" disabled />
</ElFormItem>
<ElFormItem label="公司" prop="company" class="right-input">
<ElInput v-model="form.corp_name" disabled />
</ElFormItem>
<!-- <ElFormItem label="职务" prop="position" class="right-input">
<ElInput v-model="form.position" :disabled="!isEdit" />
</ElFormItem> -->
</ElRow>
<!-- <ElRow>
<ElFormItem label="公司" prop="company">
<ElInput v-model="form.corp_name" disabled />
</ElFormItem>
<ElFormItem label="国家" prop="address" class="right-input">
<el-select
v-model="form.country_id"
filterable
placeholder="请选择国家"
:disabled="!isEdit"
>
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.cn_addr"
:value="item.id"
/>
</el-select>
</ElFormItem>
</ElRow> -->
<ElRow>
<ElFormItem label="邮箱" prop="email">
<ElInput v-model="form.email" :disabled="!isEdit" />
</ElFormItem>
</ElRow>
<!-- <ElRow>
<ElFormItem
label="二维码"
prop="socialize"
:class="isEdit ? 'qrcode-radio-group' : ''"
>
<el-radio-group v-model="form.socialize" v-if="isEdit">
<el-radio label="微信">微信</el-radio>
<el-radio label="WhatsApp">WhatsApp</el-radio>
</el-radio-group>
<template v-else>
<img
v-if="form.socialize_pic_full"
:src="form.socialize_pic_full"
class="qrcode-img"
/>
<span v-else class="qrcode-upload-text">暂无二维码</span>
</template>
</ElFormItem>
<ElFormItem v-if="isEdit" label="上传二维码" prop="address" class="right-input">
<el-upload
class="qrcode-upload"
:action="actionImageUplode"
:headers="uploadHeaders"
:show-file-list="false"
:on-success="handleUploadavatarqrcode"
>
<div class="qrcode-upload-box">
<img
v-if="form.socialize_pic_full"
:src="socialize_pic_full"
class="qrcode-img"
/>
<span v-else class="qrcode-upload-text">
<img :src="imageUrls" class="qrcode-img" />
</span>
</div>
</el-upload>
</ElFormItem>
</ElRow> -->
<div class="el-form-item-right">
<ElButton type="primary" style="width: 90px" v-ripple @click="edit">
<i v-if="!isEdit" class="iconfont-sys"> &#xe6bf;</i>
{{ isEdit ? '保存' : '编辑' }}
</ElButton>
</div>
</ElForm>
</div>
<div class="info box-style" style="margin-top: 20px">
<h1 class="title">更改密码</h1>
<ElForm :model="pwdForm" class="form" label-width="86px" label-position="left">
<ElFormItem label="当前密码" prop="password">
<ElInput
v-model="pwdForm.password"
type="password"
:disabled="!isEditPwd"
show-password
/>
</ElFormItem>
<ElFormItem label="新密码" prop="password_new">
<ElInput
v-model="pwdForm.password_new"
type="password"
:disabled="!isEditPwd"
show-password
/>
</ElFormItem>
<ElFormItem label="确认新密码" prop="confirmPassword">
<ElInput
v-model="pwdForm.confirmPassword"
type="password"
:disabled="!isEditPwd"
show-password
/>
</ElFormItem>
<div class="el-form-item-right">
<ElButton type="primary" style="width: 90px" v-ripple @click="editPwd">
<i v-if="!isEditPwd" class="iconfont-sys"> &#xe6bf;</i>
{{ isEditPwd ? '保存' : '编辑' }}
</ElButton>
</div>
</ElForm>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ElForm, FormInstance } from 'element-plus'
// import imageUrl from '@/assets/img/crm/upimg.png'
import { CrmService } from '@/api/crmApi'
import { UserService } from '@/api/usersApi'
import { useUploadHeaders } from '@/composables/useUploadHeaders'
import { useUserStore } from '@/store/modules/user'
const { uploadHeaders } = useUploadHeaders()
let actionImageUplode = `${import.meta.env.VITE_API_URL}/ticket/upload`
defineOptions({ name: 'UserCenter' })
// 定义客户详情类型
interface CustomerInfo {
[key: string]: any
}
// const imageUrls = ref(imageUrl)
const imageUrlavatar = ref('')
// const socialize_pic_full = ref('')
// const countryOptions = ref<any>()
const form = ref<CustomerInfo>({})
//获取公司 getCompanyList
// const companyList = ref<any>()
//国家
// const getarea = async () => {
// try {
// // 这里调用获取品牌列表的接口
// const res = await CrmService.getCountry()
// countryOptions.value = res||[]
// } catch (error) { countryOptions.value = [] }
// }
const { getUserInfo } = useUserStore()
const userInfo = ref<CustomerInfo>({})
const getuserInfo = async () => {
// const data = await CrmService.userget()
userInfo.value = getUserInfo.user
form.value = getUserInfo.user
imageUrlavatar.value = getUserInfo.user.avatar
// socialize_pic_full.value = data.socialize_pic_full
}
const isEdit = ref(false)
const isEditPwd = ref(false)
const pwdForm = reactive({
password: '',
password_new: '',
confirmPassword: ''
})
const ruleFormRef = ref<FormInstance>()
const options = [
{
value: '',
label: '未知'
},
{
value: '1',
label: '男'
},
{
value: '2',
label: '女'
}
]
onMounted(async () => {
// await getarea()
await getuserInfo()
})
const edit = async () => {
if (isEdit.value) {
const res = await UserService.editUserInfo(form.value)
ElMessage.success(res?.message || '操作成功')
getuserInfo()
}
isEdit.value = !isEdit.value
}
const editPwd = async () => {
if (isEditPwd.value) {
// 判断新密码和确认密码是否一致
if (pwdForm.password_new !== pwdForm.confirmPassword) {
ElMessage.error('新密码和确认密码不一致')
return
}
const res = await CrmService.savePassword(pwdForm)
ElMessage.success(res?.message || '操作成功')
}
isEditPwd.value = !isEditPwd.value
}
//头像上传
function handleUploadavatar(response: any) {
// 假设返回图片地址字段为 response.url 或 response.data.url
imageUrlavatar.value = response.url || (response.data && response.data.file_url) || ''
// 如需同步到 form.picture
form.value.avatar = response.url || (response.data && response.data.file_name) || ''
}
//二维码上传
// function handleUploadavatarqrcode(response: any) {
// // 假设返回图片地址字段为 response.url 或 response.data.url
// socialize_pic_full.value = response.url || (response.data && response.data.file_url) || ''
// imageUrls.value = response.url || (response.data && response.data.file_url) || ''
// // 如需同步到 form.picture
// form.value.socialize_pic = response.url || (response.data && response.data.file_name) || ''
// }
</script>
<style lang="scss">
.user {
.icon {
width: 1.4em;
height: 1.4em;
overflow: hidden;
vertical-align: -0.15em;
fill: currentcolor;
}
}
</style>
<style lang="scss" scoped>
:deep(.qrcode-radio-group .el-form-item__content){
height: 40px;
}
.avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.qrcode-img{
width: 80px;
height: 80px;
}
.page-content {
width: 100%;
height: 100%;
padding: 0 !important;
background: transparent !important;
border: none !important;
box-shadow: none !important;
$box-radius: calc(var(--custom-radius) + 4px);
.box-style {
border: 1px solid var(--art-border-color);
}
.content {
position: relative;
display: flex;
justify-content: space-between;
margin-top: 10px;
.left-wrap {
width: 350px;
margin-right: 25px;
.user-wrap {
position: relative;
height: 400px;
padding: 35px 30px;
overflow: hidden;
text-align: center;
// background: var(--art-main-bg-color);
background: linear-gradient(180deg, #E9F0FF 0%, #FFFFFF 67.9%);
border-radius: $box-radius;
.avatar {
position: relative;
z-index: 10;
width: 80px;
height: 80px;
// margin-top: 120px;
object-fit: cover;
border: 2px solid #fff;
border-radius: 50%;
}
.name {
margin-top: 20px;
font-size: 22px;
font-weight: 400;
}
.des {
margin-top: 20px;
font-size: 14px;
}
.outer-info {
// width: 260px;
margin: 0 auto;
margin-top: 30px;
}
.info-row {
display: flex;
justify-content: flex-start;
align-items: center;
margin-top: 10px;
font-size: 16px;
}
.info-label {
display: inline-block;
width: 100px;
color: #222;
text-align: right;
letter-spacing: 2px;
}
.info-value {
color: #333;
margin-left: 8px;
word-break: break-all;
}
.lables {
margin-top: 40px;
h3 {
font-size: 15px;
font-weight: 500;
}
> div {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-top: 15px;
> div {
padding: 3px 6px;
margin: 0 10px 10px 0;
font-size: 12px;
background: var(--art-main-bg-color);
border: 1px solid var(--art-border-color);
border-radius: 2px;
}
}
}
}
.gallery {
margin-top: 25px;
border-radius: 10px;
.item {
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
}
.right-wrap {
flex: 1;
overflow: hidden;
border-radius: $box-radius;
.info {
background: var(--art-main-bg-color);
border-radius: $box-radius;
.title {
padding: 15px 25px;
font-size: 20px;
font-weight: 400;
color: var(--art-text-gray-800);
// border-bottom: 1px solid var(--art-border-color);
}
.form {
box-sizing: border-box;
padding: 30px 25px;
> .el-row {
.el-form-item {
width: calc(50% - 10px);
}
.el-input,
.el-select {
width: 100%;
}
}
.right-input {
margin-left: 20px;
}
.el-form-item-right {
display: flex;
align-items: center;
justify-content: end;
.el-button {
width: 110px !important;
}
}
}
}
}
}
}
@media only screen and (max-width: $device-ipad-vertical) {
.page-content {
.content {
display: block;
margin-top: 5px;
.left-wrap {
width: 100%;
}
.right-wrap {
width: 100%;
margin-top: 15px;
}
}
}
}
</style>