im删除,团长

This commit is contained in:
BabyBoy 2025-09-17 17:39:59 +08:00
parent af7243203c
commit 75dc1baf3c
52 changed files with 768 additions and 3698 deletions

View File

@ -22,8 +22,6 @@
"dependencies": {
"@element-plus/icons-vue": "2.3.1",
"@highlightjs/vue-plugin": "2.1.0",
"@tencentcloud/chat": "^3.5.5",
"@tencentcloud/chat-uikit-vue": "^2.4.3",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "13.1.0",
"animate.css": "4.1.1",

View File

@ -81,7 +81,27 @@ export function updateTenant(data: any) {
data: data
});
}
// 新增团长
export function addTenantdarren(data: any) {
return request({
url: '/system/reference/add',
method: 'post',
headers: {
// isEncrypt: true // 加密传输
validateRepeat: true // 校验重复提交
},
data: data
});
}
// 修改团长
export function updateTenantdarren(data: any) {
return request({
url: '/system/reference/update',
method: 'post',
data: data
});
}
// 租户状态修改
export function changeTenantStatus(id: string | number, tenantId: string | number, status: string) {
const data = {

View File

@ -37,6 +37,7 @@ export interface TenantForm {
id: number | string | undefined;
tenantId: number | string | undefined;
username: string;
joinTime: string;
type: number;
templateName: string;
password: string;

View File

@ -1,7 +1,7 @@
import { getDicts } from '@/api/system/dict/data';
import { useDictStore } from '@/store/modules/dict';
import { TUIChatService } from '@tencentcloud/chat-uikit-engine';
import { IChatResponese } from '@/TUIKit/interface';
// import { TUIChatService } from '@tencentcloud/chat-uikit-engine';
// import { IChatResponese } from '@/TUIKit/interface';
/**
*
*/

BIN
src/views/darren/d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

745
src/views/darren/index.vue Normal file
View File

@ -0,0 +1,745 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<!--店铺名称负责人联系人推广人店铺类型地址签约状态 -->
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="店铺名称:" prop="storeName" label-width="100px">
<el-input v-model="queryParams.storeName" placeholder="请输入店铺名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="负责人:" prop="personName" label-width="100px">
<el-input v-model="queryParams.personName" placeholder="请输入负责人" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="联系人:" prop="contactUserName" label-width="100px">
<el-input v-model="queryParams.contactUserName" placeholder="请输入联系人" clearable @keyup.enter="handleQuery" />
</el-form-item>
<!-- <el-form-item label="推广人" prop="companyName">
<el-input v-model="queryParams.companyName" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" />
</el-form-item> -->
<el-form-item label="企业名称:" prop="companyName" label-width="100px">
<el-input v-model="queryParams.companyName" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="店铺类型:" prop="companyName" label-width="100px">
<el-select v-model="queryParams.companyType" placeholder="请选择店铺类型" style="width: 100%" clearable>
<el-option v-for="(item, index) in enterpriseList" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="地址:" prop="address" label-width="100px">
<el-input v-model="queryParams.address" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="签约状态:" prop="signStatus" label-width="100px">
<el-select v-model="queryParams.signStatus" placeholder="请选择签约状态" clearable>
<el-option v-for="(item, index) in signList" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" v-hasPermi="['system:tenant:query']">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="hover">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button v-hasPermi="['system:tenant:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button v-hasPermi="['system:tenant:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button v-hasPermi="['system:tenant:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">
删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button v-hasPermi="['system:tenant:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button v-if="userId === 1" type="success" plain icon="Refresh" @click="handleSyncTenantDict">同步租户字典</el-button>
</el-col> -->
<right-toolbar v-model:show-search="showSearch" @query-table="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="tenantList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column v-if="false" label="id" align="center" prop="id" />
<el-table-column label="店铺名称" align="center" prop="storeName" />
<el-table-column label="企业名称" align="center" prop="companyName" />
<el-table-column label="企业地址" align="center" prop="address" />
<el-table-column label="负责人" align="center" prop="personName" />
<el-table-column label="负责人联系电话" align="center" prop="personPhone">
<template #default="scope">
{{ getPhon(scope.row.personPhone) }}
</template>
</el-table-column>
<el-table-column label="邀请人" align="center" prop="inviteUserName" />
<el-table-column label="签约状态" align="center" prop="signStatus">
<template #default="scope">
{{ signList.filter((item) => item.value == scope.row.signStatus)[0]?.label }}
</template>
</el-table-column>
<el-table-column label="不通过理由" align="center" prop="failureReason">
<template #default="scope">
{{ scope.row.failureReason || '-' }}
</template>
</el-table-column>
<el-table-column label="租户状态" align="center" prop="status">
<template #default="scope">
<!-- 0启用 1停用 -->
{{ scope.row.status == 0 ? '启用' : '停用' }}
</template>
</el-table-column>
<el-table-column width="580" label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button v-hasPermi="['system:tenant:edit']" link type="primary" @click="handleUpdate(scope.row)"> 修改</el-button>
</el-tooltip>
<el-tooltip content="提交" placement="top">
<el-button v-hasPermi="['system:tenant:submit']" link type="primary" @click="handleTl(scope.row)"> 提交 </el-button>
</el-tooltip>
<el-tooltip content="审核" placement="top">
<el-button v-hasPermi="['system:tenant:review']" link type="primary" @click="handleSh(scope.row)"> 审核 </el-button>
</el-tooltip>
<el-tooltip content="确认审核" placement="top">
<el-button v-hasPermi="['system:tenant:confirm']" link type="primary" @click="handleSubmit(scope.row)"> 确认审核 </el-button>
</el-tooltip>
<el-tooltip content="切换租户状态" placement="top">
<el-button v-hasPermi="['system:tenant:status']" link type="primary" @click="handleStatusChange(scope.row)"> 切换租户状态 </el-button>
</el-tooltip>
<el-tooltip content="同步套餐" placement="top">
<el-button v-hasPermi="['system:tenant:edit']" link type="primary" @click="handleSyncTenantPackage(scope.row)"> 同步套餐 </el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button v-hasPermi="['system:tenant:remove']" link type="primary" @click="handleDelete(scope.row)">删除</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" v-model:current="queryParams.current" v-model:size="queryParams.size" :total="total" @pagination="getList" />
</el-card>
<!-- 添加或修改租户对话框 -->
<el-dialog v-model="dialog.visible" :title="dialog.title" width="1200px" append-to-body>
<el-form ref="tenantFormRef" :model="form" :rules="rules">
<div class="form-group">
<h3 class="group-title">人员信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="团长名称:" prop="personName">
<el-input v-model="form.personName" type="text" placeholder="请输入企业负责人" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="团长名称电话:" prop="personPhone">
<el-input v-model="form.personPhone" type="text" placeholder="请输入企业负责人电话" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="地址:" prop="address">
<el-input v-model="form.address" placeholder="请输入地址" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="负责人证件类型:" prop="idCardType">
<el-select v-model="form.idCardType" placeholder="请选择负责人证件类型" style="width: 100%" clearable>
<el-option v-for="(item, index) in certificateList" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="负责人证件信息:" prop="idCard">
<el-input v-model="form.idCard" placeholder="请输入负责人证件信息" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="任聘时间:" prop="joinTime">
<el-date-picker
v-model="form.joinTime"
clearable
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择任聘时间
"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-col :span="8">
<el-form-item label="证件信息:" prop="certificate">
<oss-image-upload v-model="form.certificate" :limit="2"> </oss-image-upload>
</el-form-item>
</el-col>
</div>
<div class="form-group">
<h3 class="group-title">用户信息</h3>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="用户名:" prop="username">
<el-input v-model="form.username" placeholder="请输入系统用户名" maxlength="30" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="用户密码:" prop="password">
<el-input v-model="form.password" type="password" placeholder="请输入系统用户密码" maxlength="20" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="租户套餐:" prop="packageId">
<el-select v-model="form.packageId" placeholder="请选择租户套餐" clearable style="width: 100%">
<el-option v-for="item in packageList" :key="item.packageId" :label="item.packageName" :value="item.packageId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="备注:" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" type="textarea" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="合同年限" prop="contractYear" align="left">
<el-input v-model="form.contractYear" placeholder="请输入合同年限" />
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Tenant" lang="ts">
import {
getlistDivide,
listTenant,
getTenant,
delTenant,
addTenantdarren,
updateTenantdarren,
changeTenantStatus,
syncTenantPackage,
syncTenantDict,
getTenantBannelList,
getTenantSub,
auditTenant,
auditSubmit
} from '@/api/system/tenant';
import { listUmsMember } from '@/api/ums/member';
import { getDictionaryByKey } from '@/utils/dict';
import { selectTenantPackage } from '@/api/system/tenantPackage';
import { useUserStore } from '@/store/modules/user';
import { TenantForm, TenantQuery, TenantVO, TenantModal, enterpriseType } from '@/api/system/tenant/types';
import { TenantPkgVO } from '@/api/system/tenantPackage/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadFileUrl = ref(baseUrl + '/resource/oss/upload'); //
const userStore = useUserStore();
const userId = ref(userStore.userId);
const tenantList = ref<TenantVO[]>([]);
const packageList = ref<TenantPkgVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const tenantBannedInfoModalVisible = ref(false);
const tenantBannedInfoTableLoading = ref(false);
const bannedDataParams = ref({
current: 1,
size: 10
});
const userSelectLoading = ref(false);
const userSelectOption = ref([]);
const userSelectfun = (query: string) => {};
//
const tenantBannedInfo = ref<TenantModal>({
total: 0,
data: [],
record: {}
});
const tenantForbiddenUnitMap = ref([]);
const tenantForbiddenReasonMap = ref([]);
const queryFormRef = ref<ElFormInstance>();
const tenantFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const sexDialog = ref<DialogOption>({
visible: false,
title: ''
});
//
const tenantForm = ref<TenantForm>();
const funseach = (data) => {
getTenantPackage();
sexDialog.value.visible = true;
tenantForm.value = data;
};
const handleTl = async (row) => {
try {
await ElMessageBox.confirm('确定要执行提交操作吗?', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
//
const res = await getTenantSub(row.tenantId);
//
if (res.code == 200) {
ElMessage.success('操作成功');
//
getList();
} else {
ElMessage.error(res.msg || '操作失败');
}
} catch (error) {
//
console.log('用户取消了操作');
}
};
const handleSubmit = async (row) => {
try {
await ElMessageBox.confirm('确认审核通过的签约', '确认提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
//
const res = await auditSubmit(row.tenantId);
//
if (res.code == 200) {
ElMessage.success('操作成功');
//
getList();
} else {
ElMessage.error(res.msg || '操作失败');
}
} catch (error) {
//
console.log('用户取消了操作');
}
};
const managefun = (data: any) => {
const dataArray = data.split(',');
console.log(typeof dataArray);
let finds = '';
dataArray.forEach((item) => {
const matchedItem = manageList.value.find((option: any) => option.value === item);
finds += matchedItem ? matchedItem.label + ',' : '';
});
return finds;
};
const certificatefun = (data: any) => {
return certificateList.value.find((item) => item.value === data)?.label;
};
const enterprisefun = (data: any) => {
return enterpriseList.value.find((item) => item.value === data)?.label;
};
const bankfun = (data: any) => {
return bankList.value.find((item) => item.value === data)?.label;
};
const signfun = (data: any) => {
return signList.value.find((item) => item.value === data)?.label;
};
const enterpriseList = ref([]); //
const manageList = ref([]); //
const certificateList = ref([]); //
const bankList = ref([]); //
const signList = ref([]); //
const getByKey = async () => {
const value1 = await getDictionaryByKey('sys_enterprise_type');
enterpriseList.value = value1;
const orderStatusresulttype = await getDictionaryByKey('sys_manage_type');
manageList.value = orderStatusresulttype;
const orderStatusreasontype = await getDictionaryByKey('sys_certificate_type');
certificateList.value = orderStatusreasontype;
const orderStatusaimobject = await getDictionaryByKey('sys_bank_type');
bankList.value = orderStatusaimobject;
const orderStatusstatus = await getDictionaryByKey('sys_sign_status');
signList.value = orderStatusstatus;
};
const businessTypesjson = ref([]); //
const fnall = ref([]);
const accountCountFun = async () => {
const res = await getlistDivide();
fnall.value = res.data;
};
const initFormData: TenantForm = {
id: undefined,
tenantId: undefined,
type: 2,
personPhone: '', //
address: '', //
idCard: '', ///
certificate: '', //
password: '', //
packageId: '', //
remark: '', //
username: '', //
contractYear: '', //
joinTime: '', //
idCardType: '', //
personName: '' //
};
const data = reactive<PageData<TenantForm, TenantQuery>>({
form: { ...initFormData },
queryParams: {
current: 1,
size: 10,
type: 2,
tenantId: null,
personName: null, //
storeName: null, //
contactUserName: null, //
companyName: null, //
companyType: null, //
address: null, //
signStatus: null //
},
rules: {
id: [{ required: true, message: 'id不能为空', trigger: 'blur' }],
tenantId: [{ required: true, message: '租户编号不能为空', trigger: 'blur' }],
personPhone: [{ required: true, message: '团长电话不能为空', trigger: 'blur' }],
address: [{ required: true, message: '企业地址不能为空', trigger: 'blur' }],
idCard: [{ required: true, message: '负责人证件信息/身份证号不能为空', trigger: 'blur' }],
certificate: [{ required: true, message: '身份证附件不能为空', trigger: 'blur' }],
packageId: [{ required: true, message: '租户套餐不能为空', trigger: 'blur' }],
remark: [{ required: true, message: '备注不能为空', trigger: 'blur' }],
contractYear: [{ required: true, message: '合同年限不能为空', trigger: 'blur' }],
joinTime: [{ required: true, message: '加入时间不能为空', trigger: 'blur' }],
idCardType: [{ required: true, message: '证件类型不能为空', trigger: 'blur' }],
personName: [{ required: true, message: '团长姓名不能为空', trigger: 'blur' }],
username: [
{ required: true, message: '用户名不能为空', trigger: 'blur' },
{ min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }
],
password: [
{ required: true, message: '密码不能为空', trigger: 'blur' },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' }
]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询代理租户套餐 */
const getTenantPackage = async () => {
const res = await selectTenantPackage(2);
packageList.value = res.data;
};
const packagefun = (data) => {
return packageList.value.find((item) => item.packageId === data)?.packageName;
};
//
const getUserListByName = (params: string) => {
if (params) {
userSelectLoading.value = true;
const query = { current: 1, size: 200, nickname: params };
const pageReq = { current: 1, size: 200 };
listUmsMember(query, pageReq).then((response) => {
const { records = [] } = response.data || {};
userSelectOption.value = records || [];
userSelectLoading.value = false;
});
} else {
userSelectOption.value = [];
userSelectLoading.value = false;
}
};
/** 查询租户列表 */
const getList = async () => {
loading.value = true;
const res = await listTenant(queryParams.value);
tenantList.value = res.data.records;
total.value = res.data.total;
loading.value = false;
};
//
const handleStatusChange = async (row: TenantVO) => {
// 0 1
const text = row.status === '0' ? '停用' : '启用';
try {
await proxy?.$modal.confirm('确认要"' + text + '""' + row.companyName + '"租户吗?');
await changeTenantStatus(row.id, row.tenantId, row.status == '0' ? '1' : '0');
proxy?.$modal.msgSuccess(text + '成功');
getList(); //
} catch {
getList(); //
}
};
//
const showTenantBannedInfoModal = (record, isFirst) => {
const { id } = tenantBannedInfo.record || {};
const reqParams = {
...bannedDataParams.value,
memberId: record.id ? record.id : id
};
tenantBannedInfoTableLoading.value = true;
if (isFirst) {
//
getBannedReasonEmu();
}
getTenantBannelList(reqParams)
.then((response) => {
const { records = [], total = 0 } = response.data || {};
if (isFirst) {
tenantBannedInfoModalVisible.value = true;
}
tenantBannedInfo.value = {
total: total,
data: records || [],
record: record
};
tenantBannedInfoTableLoading.value = false;
})
.catch(() => {
tenantBannedInfoTableLoading.value = false;
});
};
const getBannedReasonEmu = async () => {
const reasonMap1 = await proxy?.getDictionaryByKey('ums_forbidden_unit');
const reasonMap2 = await proxy?.getDictionaryByKey('sys_tenant_forbidden_reason');
tenantForbiddenUnitMap.value = reasonMap1;
tenantForbiddenReasonMap.value = reasonMap2;
};
const handleSh = (row) => {
ElMessageBox.confirm('请选择审核结果', '审核确认', {
confirmButtonText: '通过',
cancelButtonText: '不通过',
distinguishCancelAndClose: true,
type: 'warning'
})
.then(() => {
// ""
return auditTenant({
tenantId: row.tenantId,
isPass: true
});
})
.then((res) => {
if (res.code === 200) {
ElMessage.success('审核通过');
getList(); //
} else {
ElMessage.error(res.msg || '审核失败');
}
})
.catch((action) => {
if (action === 'cancel') {
// ""
ElMessageBox.prompt('请输入不通过原因', '审核不通过', {
confirmButtonText: '确认',
cancelButtonText: '取消',
inputPattern: /^[\s\S]+$/,
inputErrorMessage: '必须填写不通过原因',
type: 'error'
})
.then(({ value }) => {
return auditTenant({
tenantId: row.tenantId,
isPass: false, //
failureReason: value
});
})
.then((res) => {
if (res.code === 200) {
ElMessage.success('操作成功');
getList(); //
} else {
ElMessage.error(res.msg || '操作失败');
}
});
}
});
};
//
const cancel = () => {
reset();
dialog.visible = false;
};
//
const reset = () => {
form.value = { ...initFormData };
tenantFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.current = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
//
const handleSelectionChange = (selection: TenantVO[]) => {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
getTenantPackage();
dialog.visible = true;
dialog.title = '新增团长';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: TenantVO) => {
reset();
await getTenantPackage();
const _id = row?.id || ids.value[0];
const res = await getTenant(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改团长';
};
/** 提交按钮 */
const submitForm = () => {
tenantFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
await updateTenantdarren(form.value).finally(() => (buttonLoading.value = false));
} else {
await addTenantdarren(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: TenantVO) => {
const _ids = row?.id || ids.value;
await proxy?.$modal.confirm('是否确认删除租户编号为"' + _ids + '"的数据项?');
loading.value = true;
await delTenant(_ids).finally(() => (loading.value = false));
await getList();
proxy?.$modal.msgSuccess('删除成功');
};
/** 同步租户套餐按钮操作 */
const handleSyncTenantPackage = async (row: TenantVO) => {
try {
await proxy?.$modal.confirm('是否确认同步租户套餐租户编号为"' + row.tenantId + '"的数据项?');
loading.value = true;
await syncTenantPackage(row.tenantId, row.packageId);
await getList();
proxy?.$modal.msgSuccess('同步成功');
} catch {
return;
} finally {
loading.value = false;
}
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'system/tenant/export',
{
...queryParams.value
},
`tenant_${new Date().getTime()}.xlsx`
);
};
/**同步租户字典*/
const handleSyncTenantDict = async () => {
await proxy?.$modal.confirm('确认要同步所有租户字典吗?');
const res = await syncTenantDict();
proxy?.$modal.msgSuccess(res.msg);
};
onMounted(() => {
accountCountFun();
getByKey();
getList();
});
</script>
<style scoped lang="scss">
.form-group {
margin-bottom: 24px;
}
.group-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
color: #1f2937;
padding-left: 8px;
border-left: 3px solid #409eff;
}
.upload__tip {
background: url('./d.png') no-repeat;
background-size: 100% 100%;
width: 100%;
height: 100%;
}
::v-deep {
#searc {
.el-form-item--default .el-form-item__label {
width: 100px;
}
}
.el-form-item__content {
width: 240px;
}
.el-form-item--default .el-form-item__label {
width: 150px;
}
.el-upload--picture-card {
width: 100px;
height: 100px;
}
.el-upload-list {
width: 320px;
.el-upload-list__item {
width: 100px;
height: 100px;
}
}
}
</style>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="21px" height="21px" viewBox="0 0 21 21" version="1.1">
<title>编组 5</title>
<g id="web" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录" transform="translate(-627.000000, -516.000000)" stroke="#FFFFFF" stroke-width="1.2">
<g id="编组-3" transform="translate(266.400000, 332.400000)">
<g id="编组-6" transform="translate(3.600000, 172.800000)">
<g id="编组-5" transform="translate(357.600000, 10.800000)">
<rect id="矩形" x="6.6" y="10.2" width="6" height="1" rx="0.5"></rect>
<circle id="椭圆形" cx="10.2" cy="10.2" r="9.6"></circle>
<polyline id="路径-2" stroke-linecap="round" stroke-linejoin="round" points="9.6 13.4662027 13.2 10.2 9.6 7.30762441"></polyline>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 969 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

View File

@ -1,8 +0,0 @@
<svg width="16" height="14" viewBox="0 0 16 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="&#229;&#189;&#162;&#231;&#138;&#182;&#231;&#187;&#147;&#229;&#144;&#136;"
fill-rule="evenodd" clip-rule="evenodd"
d="M3.73333 0H5.86667V1.55556H10.1333V0H12.2667V1.55556H16V14H0V1.55556H3.73333V0ZM10.1333 3.11111V4.14815H12.2667V3.11111H14.4V12.4444H1.6V3.11111H3.73333V4.14815H5.86667V3.11111H10.1333ZM12.2667 7.25926H9.06667V10.3704H12.2667V7.25926Z"
fill="#596174"
style="fill:#596174;fill:color(display-p3 0.3490 0.3804 0.4549);fill-opacity:1;" />
</svg>

Before

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
<title>编组 8</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="通讯页" transform="translate(-123.000000, -1406.000000)">
<g id="编组-15" transform="translate(0.000000, 1378.000000)">
<g id="编组-12备份-5" transform="translate(32.000000, 12.000000)">
<g id="编组-8" transform="translate(91.000000, 16.000000)">
<rect id="矩形" x="0" y="0" width="48" height="48"></rect>
<path d="M24,5 C34.4934102,5 43,13.5065898 43,24 C43,34.1653543 35.0169798,42.4661744 24.9781429,42.9752568 L25.004234,43 L7,43 C5.8954305,43 5,42.1045695 5,41 L5,23 L5.02459166,23.0248508 C5.53217539,12.9846073 13.8336352,5 24,5 Z M24,25 L14,25 C13.4477153,25 13,25.4477153 13,26 L13,26 L13,28 C13,28.5522847 13.4477153,29 14,29 L14,29 L24,29 C24.5522847,29 25,28.5522847 25,28 L25,28 L25,26 C25,25.4477153 24.5522847,25 24,25 L24,25 Z M34,17 L14,17 C13.4477153,17 13,17.4477153 13,18 L13,18 L13,20 C13,20.5522847 13.4477153,21 14,21 L14,21 L34,21 C34.5522847,21 35,20.5522847 35,20 L35,20 L35,18 C35,17.4477153 34.5522847,17 34,17 L34,17 Z" id="形状结合" fill="#A0A3A6"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
<title>编组 8</title>
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="更多" transform="translate(-498.000000, -339.000000)">
<g id="左侧边栏" transform="translate(480.000000, 220.000000)">
<g id="编组-8" transform="translate(18.000000, 119.000000)">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<g id="编组-18" transform="translate(3.000000, 3.000000)" fill="#147AFF">
<path d="M1.33333333,18 C0.596953667,18 -7.9799792e-16,17.4030463 0,16.6666667 L0,8.52631579 L0.0116474743,8.53811106 C0.252069935,3.78219505 4.18434547,0 9,0 C13.9705627,0 18,4.02943725 18,9 C18,13.815317 14.2183351,17.7473789 9.46288884,17.9883019 L9.47568977,18 L1.33333333,18 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
<title>编组 8</title>
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ICON" transform="translate(-58.000000, -20.000000)">
<g id="编组-8" transform="translate(58.000000, 20.000000)">
<g id="编组-18" transform="translate(3.000000, 3.000000)" stroke="#999999">
<path d="M9,0.5 C11.3472102,0.5 13.4722102,1.45139491 15.0104076,2.98959236 C16.5486051,4.52778981 17.5,6.65278981 17.5,9 C17.5,11.2679988 16.6117526,13.3285462 15.1641141,14.8526931 C13.7116662,16.3819037 11.6961744,17.3713309 9.44969786,17.4883204 L9.44969786,17.4883204 L1.33333333,17.5 C1.10321469,17.5 0.894881354,17.406726 0.744077682,17.2559223 C0.59327401,17.1051186 0.5,16.8967853 0.5,16.6666667 L0.5,16.6666667 L0.5,8.53977783 C0.62256394,6.29760907 1.61581474,4.28394186 3.14775549,2.83262957 C4.67315258,1.38751653 6.73292542,0.5 9,0.5 Z" id="形状结合"></path>
</g>
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
<title>编组 8</title>
<defs>
<path d="M16,0 L670,0 C678.836556,-1.623249e-15 686,7.163444 686,16 L686,94 C686,102.836556 678.836556,110 670,110 L16,110 C7.163444,110 1.082166e-15,102.836556 0,94 L0,16 C-1.082166e-15,7.163444 7.163444,1.623249e-15 16,0 Z" id="path-1"></path>
<filter x="-7.0%" y="-43.6%" width="114.0%" height="187.3%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="16" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.941176471 0 0 0 0 0.964705882 0 0 0 0 1 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="个人信息" transform="translate(-580.000000, -1405.000000)">
<rect fill="#F7F8FA" x="0" y="0" width="750" height="1624"></rect>
<g id="编组-17" transform="translate(0.000000, 1378.000000)">
<polygon id="矩形" fill="#FFFFFF" points="0 -1.15130128e-13 750 -1.15130128e-13 750 122 0 122"></polygon>
<g id="编组-12备份-5" transform="translate(32.000000, 12.000000)">
<g id="矩形备份-22">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#EBF0F6" fill-rule="evenodd" xlink:href="#path-1"></use>
</g>
<g id="编组-6" transform="translate(457.000000, 0.000000)">
<polygon id="矩形" points="0 3.55965257e-14 229 3.55965257e-14 229 110 0 110"></polygon>
<g id="编组-8" transform="translate(91.000000, 15.000000)" fill="#006EFF">
<path d="M31,26 C35.418278,26 39,29.581722 39,34 L39,40 C39,41.1045695 38.1045695,42 37,42 L11,42 C9.8954305,42 9,41.1045695 9,40 L9,34 C9,29.581722 12.581722,26 17,26 L31,26 Z M24.0020419,6 C28.9737572,6 33.0040839,10.0294125 33.0040839,15 C33.0040839,19.9705875 28.9737572,24 24.0020419,24 C19.0303267,24 15,19.9705875 15,15 C15,10.0294125 19.0303267,6 24.0020419,6 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
<title>编组 8</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="消息页" transform="translate(-580.000000, -1405.000000)" fill="#B0B4B8">
<g id="编组-15" transform="translate(0.000000, 1378.000000)">
<g id="编组-12备份-5" transform="translate(32.000000, 12.000000)">
<g id="编组-6" transform="translate(457.000000, 0.000000)">
<g id="编组-8" transform="translate(91.000000, 15.000000)">
<path d="M31,26 C35.418278,26 39,29.581722 39,34 L39,40 C39,41.1045695 38.1045695,42 37,42 L11,42 C9.8954305,42 9,41.1045695 9,40 L9,34 C9,29.581722 12.581722,26 17,26 L31,26 Z M24.0020419,6 C28.9737572,6 33.0040839,10.0294125 33.0040839,15 C33.0040839,19.9705875 28.9737572,24 24.0020419,24 C19.0303267,24 15,19.9705875 15,15 C15,10.0294125 19.0303267,6 24.0020419,6 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="48px" height="48px" viewBox="0 0 48 48" version="1.1">
<title>编组 8</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="消息页" transform="translate(-351.000000, -1405.000000)" fill="#B0B4B8">
<g id="编组-15" transform="translate(0.000000, 1378.000000)">
<g id="编组-12备份-5" transform="translate(32.000000, 12.000000)">
<g id="编组-6" transform="translate(229.000000, 0.000000)">
<g id="编组-2" transform="translate(84.000000, 15.000000)">
<g id="编组-8" transform="translate(6.000000, 0.000000)">
<path d="M25,26 C29.418278,26 33,29.581722 33,34 L33,40 C33,41.1045695 32.1045695,42 31,42 L5,42 C3.8954305,42 3,41.1045695 3,40 L3,34 C3,29.581722 6.581722,26 11,26 L25,26 Z M43.9994591,26 C44.5517438,26 44.9994591,26.4477153 44.9994591,27 L44.9994591,29 C44.9994591,29.5522847 44.5517438,30 43.9994591,30 L36.9994591,30 C36.4471743,30 35.9994591,29.5522847 35.9994591,29 L35.9994591,27 C35.9994591,26.4477153 36.4471743,26 36.9994591,26 L43.9994591,26 Z M18.0020419,6 C22.9737572,6 27.0040839,10.0294125 27.0040839,15 C27.0040839,19.9705875 22.9737572,24 18.0020419,24 C13.0303267,24 9,19.9705875 9,15 C9,10.0294125 13.0303267,6 18.0020419,6 Z M43.9994591,18 C44.5517438,18 44.9994591,18.4477153 44.9994591,19 L44.9994591,21 C44.9994591,21.5522847 44.5517438,22 43.9994591,22 L31.9994591,22 C31.4471743,22 30.9994591,21.5522847 30.9994591,21 L30.9994591,19 C30.9994591,18.4477153 31.4471743,18 31.9994591,18 L43.9994591,18 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
<title>编组 8</title>
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ICON" transform="translate(-19.000000, -60.000000)">
<g id="编组-8" transform="translate(19.000000, 60.000000)">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<rect id="矩形" stroke="#006EFF" transform="translate(19.000000, 8.500000) scale(1, -1) translate(-19.000000, -8.500000) " x="16.5" y="8.5" width="5" height="1" rx="0.5"></rect>
<rect id="矩形备份-2" stroke="#006EFF" x="16.5" y="11.5" width="5" height="1" rx="0.5"></rect>
<rect id="矩形备份-3" stroke="#006EFF" x="18.5" y="14.5" width="3" height="1" rx="0.5"></rect>
<path d="M9,12 C11.209139,12 13,9.35025579 13,7.09090909 C13,4.83156239 11.209139,3 9,3 C6.790861,3 5,4.83156239 5,7.09090909 C5,9.35025579 6.790861,12 9,12 Z" id="椭圆形" fill="#006EFF"></path>
<path d="M6,13 L12,13 C14.209139,13 16,14.790861 16,17 L16,20 C16,20.5522847 15.5522847,21 15,21 L3,21 C2.44771525,21 2,20.5522847 2,20 L2,17 C2,14.790861 3.790861,13 6,13 Z" id="矩形" fill="#006EFF"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
<title>编组 8</title>
<g id="页面-2备份" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="更多" transform="translate(-498.000000, -389.000000)">
<g id="左侧边栏" transform="translate(480.000000, 220.000000)">
<g id="编组-8" transform="translate(18.000000, 169.000000)">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<rect id="矩形" stroke="#999999" transform="translate(19.000000, 8.500000) scale(1, -1) translate(-19.000000, -8.500000) " x="16.5" y="8.5" width="5" height="1" rx="0.5"></rect>
<rect id="矩形备份-2" stroke="#999999" x="16.5" y="11.5" width="5" height="1" rx="0.5"></rect>
<rect id="矩形备份-3" stroke="#999999" x="18.5" y="14.5" width="3" height="1" rx="0.5"></rect>
<path d="M9,3.5 C9.9652364,3.5 10.8385592,3.90102188 11.4709238,4.54775835 C12.1073095,5.19860738 12.5,6.09799921 12.5,7.09090909 C12.5,8.1638596 12.0512293,9.33155704 11.3410312,10.2031638 C10.7279048,10.9556371 9.91231344,11.5 9,11.5 C8.08768656,11.5 7.27209516,10.9556371 6.65896878,10.2031638 C5.94877068,9.33155704 5.5,8.1638596 5.5,7.09090909 C5.5,6.09799921 5.89269049,5.19860738 6.52907621,4.54775835 C7.16144075,3.90102188 8.0347636,3.5 9,3.5 L9,3.5 Z" id="椭圆形" stroke="#999999"></path>
<path d="M12,13.5 C12.9664983,13.5 13.8414983,13.8917508 14.4748737,14.5251263 C15.1082492,15.1585017 15.5,16.0335017 15.5,17 L15.5,17 L15.5,20 L3,20.5 L2.5,17 C2.5,16.0335017 2.89175084,15.1585017 3.52512627,14.5251263 C4.15850169,13.8917508 5.03350169,13.5 6,13.5 L6,13.5 Z" id="矩形" stroke="#999999"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

View File

@ -1,41 +0,0 @@
<svg width="232" height="72" viewBox="0 0 232 72" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_12_66883" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0"
width="232" height="72">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M0 4C0 1.79086 1.79086 0 4 0L228 0C230.209 0 232 1.79086 232 4V68C232 70.2091 230.209 72 228 72H4C1.79086 72 0 70.2091 0 68V4Z"
fill="white" style="fill:white;fill:white;fill-opacity:1;" />
</mask>
<g mask="url(#mask0_12_66883)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M11.0001 19.4285C11.0001 15.3284 14.3239 12 18.424 12C22.5241 12 25.8479 15.3284 25.8479 19.4285C25.8479 23.5287 22.5241 26.8571 18.424 26.8571C14.3239 26.8571 11.0001 23.5287 11.0001 19.4285ZM25.8478 53.5361C25.8478 57.6363 22.524 60.9601 18.4239 60.9601C14.3238 60.9601 11 57.6363 11 53.5361V36.7114C11 32.6113 14.3238 29.2875 18.4239 29.2875C22.524 29.2875 25.8478 32.6113 25.8478 36.7114V53.5361ZM77.8672 59.9647C74.3164 62.016 69.7765 60.7995 67.7271 57.2476L56.3033 37.4486L45.1079 57.2172C43.0546 60.8429 38.4299 62.0818 34.839 59.9682C31.3292 57.9024 30.1236 53.4023 32.1305 49.8585L49.7493 18.7476C51.8026 15.1218 56.4273 13.883 60.0182 15.9966C61.2926 16.7467 62.2633 17.8178 62.8866 19.0475L66.0031 24.5456L80.5857 49.8191C82.6351 53.371 81.418 57.9133 77.8672 59.9647ZM95.0556 57.066C97.109 60.6917 101.734 61.9306 105.325 59.817C108.834 57.7512 110.04 53.2511 108.033 49.7074L90.4143 18.5964C88.3609 14.9707 83.7363 13.7318 80.1454 15.8454C78.8711 16.5954 77.9006 17.6663 77.2772 18.8958L71.7783 28.5969C73.904 26.338 77.5844 26.6727 79.2694 29.2781L79.6668 29.8927L95.0556 57.066Z"
fill="url(#paint0_linear_12_66883)" style="" />
</g>
<g filter="url(#filter0_b_12_66883)">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M0 4C0 1.79086 1.79086 0 4 0L228 0C230.209 0 232 1.79086 232 4V68C232 70.2091 230.209 72 228 72H4C1.79086 72 0 70.2091 0 68V4Z"
fill="url(#paint1_linear_12_66883)" fill-opacity="0.5" style="" />
</g>
<defs>
<filter id="filter0_b_12_66883" x="-1.35914" y="-1.35914" width="234.718" height="74.7183"
filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feGaussianBlur in="BackgroundImageFix" stdDeviation="0.67957" />
<feComposite in2="SourceAlpha" operator="in" result="effect1_backgroundBlur_12_66883" />
<feBlend mode="normal" in="SourceGraphic" in2="effect1_backgroundBlur_12_66883" result="shape" />
</filter>
<linearGradient id="paint0_linear_12_66883" x1="5.19355" y1="42.1342" x2="39.8324" y2="91.0797"
gradientUnits="userSpaceOnUse">
<stop stop-color="#D4E7FF"
style="stop-color:#D4E7FF;stop-color:color(display-p3 0.8298 0.9061 1.0000);stop-opacity:1;" />
<stop offset="1" stop-color="#AACCFF"
style="stop-color:#AACCFF;stop-color:color(display-p3 0.6675 0.7981 1.0000);stop-opacity:1;" />
</linearGradient>
<linearGradient id="paint1_linear_12_66883" x1="31.8498" y1="0" x2="31.8498" y2="52.2312"
gradientUnits="userSpaceOnUse">
<stop stop-color="white" style="stop-color:white;stop-color:white;stop-opacity:1;" />
<stop offset="1" stop-color="#F5F9FF"
style="stop-color:#F5F9FF;stop-color:color(display-p3 0.9596 0.9771 1.0000);stop-opacity:1;" />
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="401px" height="41px" viewBox="0 0 401 41" version="1.1">
<title>矩形</title>
<defs>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-1">
<stop stop-color="#35E7FF" offset="0%"></stop>
<stop stop-color="#3E60FF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="web" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录" transform="translate(-270.000000, -505.000000)" fill="url(#linearGradient-1)">
<g id="编组-3" transform="translate(266.400000, 332.400000)">
<g id="编组-6" transform="translate(3.600000, 172.800000)">
<rect id="矩形" x="0" y="0" width="400.8" height="40.8" rx="4.8"></rect>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,24 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 232 72" class="design-iconfont">
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="72.5432672%" id="3m7u4ef0gc">
<stop stop-color="#FFF" offset="0%"/>
<stop stop-color="#F5F9FF" offset="100%"/>
</linearGradient>
<linearGradient x1="-2.96386364%" y1="50%" x2="100%" y2="50%" id="1t3m9qcp9d">
<stop stop-color="#CEE3FF" offset="0%"/>
<stop stop-color="#B5D2FF" offset="100%"/>
</linearGradient>
<path d="M4,0 L228,0 C230.209139,-4.05812251e-16 232,1.790861 232,4 L232,68 C232,70.209139 230.209139,72 228,72 L4,72 C1.790861,72 2.705415e-16,70.209139 0,68 L0,4 C-2.705415e-16,1.790861 1.790861,4.05812251e-16 4,0 Z" id="noxzn0gwva"/>
<path d="M4,0 L228,0 C230.209139,-4.05812251e-16 232,1.790861 232,4 L232,68 C232,70.209139 230.209139,72 228,72 L4,72 C1.790861,72 2.705415e-16,70.209139 0,68 L0,4 C-2.705415e-16,1.790861 1.790861,4.05812251e-16 4,0 Z" id="1xc15s665b"/>
<filter x="-1.5%" y="-3.1%" width="103.1%" height="106.1%" filterUnits="objectBoundingBox" id="183q9jim4e">
<feGaussianBlur stdDeviation=".5" in="SourceGraphic"/>
</filter>
</defs>
<g fill="none" fill-rule="evenodd">
<mask id="uaaxxy4ytf" fill="#fff">
<use xlink:href="#1xc15s665b"/>
</mask>
<use fill-opacity=".5" fill="url(#3m7u4ef0gc)" xlink:href="#1xc15s665b"/>
<path d="M18.5006766,29 C22.643186,29 26.0013533,32.3581673 26.0013533,36.5006766 L26.0013533,53.4993234 C26.0013533,57.6418327 22.643186,61 18.5006766,61 C14.3581673,61 11,57.6418327 11,53.4993234 L11,36.5006766 C11,32.3581673 14.3581673,29 18.5006766,29 Z M59.4587876,15.9438886 C59.4985795,15.9663688 59.5381591,15.9892228 59.5775211,16.0124475 C60.1577643,16.3548079 60.675775,16.7627669 61.1275574,17.2214095 C61.8771751,17.7979547 62.52949,18.5281053 63.0321514,19.3985444 L63.0321514,19.3985444 L80.5770893,49.7804325 C80.5773303,49.7808499 80.5775713,49.7812673 80.5778122,49.7816847 L80.7016313,50.0048019 C82.5751102,53.5194926 81.3362448,57.9128548 77.8604228,59.9191702 C74.3097528,61.9686893 69.7699204,60.7522449 67.7197096,57.2019743 L67.7197096,57.2019743 L56.152,37.171 L44.7832626,57.2957598 C42.8033952,60.8002981 38.3574059,62.036288 34.8528676,60.0564205 C34.8130121,60.0339044 34.7733696,60.0110132 34.7339454,59.9877502 C31.1820613,57.8918876 29.9621789,53.3380143 31.9907466,49.7472716 L49.5280914,18.7046339 C51.5080186,15.1999891 55.9541428,13.9639613 59.4587876,15.9438886 Z M80.5518583,15.9438886 C84.0565032,13.9639613 88.5026273,15.1999891 90.4825546,18.7046339 L90.4825546,18.7046339 L108.019899,49.7472716 C110.048467,53.3380143 108.828585,57.8918876 105.276701,59.9877502 C105.237276,60.0110132 105.197634,60.0339044 105.157778,60.0564205 C101.65324,62.036288 97.2072508,60.8002981 95.2273833,57.2957598 L95.2273833,57.2957598 L79.856,30.0869675 L79.4556434,29.4665594 C79.2460305,29.1416441 78.9975059,28.8435556 78.715593,28.5789189 C76.8040822,26.7845495 73.7998728,26.8795114 72.0055034,28.7910221 L72.0055034,28.7910221 L77.8023001,18.5393367 L77.8125611,18.5959107 C78.4392122,17.5640516 79.3220837,16.6679942 80.4331248,16.0124475 C80.4724868,15.9892228 80.5120664,15.9663688 80.5518583,15.9438886 Z M18.5013533,12 C22.6434889,12 26.0013533,15.3578644 26.0013533,19.5 C26.0013533,23.6421356 22.6434889,27 18.5013533,27 L18.5,27 C14.3578644,27 11,23.6421356 11,19.5 C11,15.3578644 14.3578644,12 18.5,12 L18.5013533,12 Z" fill="url(#1t3m9qcp9d)" opacity=".5" filter="url(#183q9jim4e)" mask="url(#uaaxxy4ytf)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="230px" height="70px" viewBox="0 0 230 70" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组</title>
<defs>
<path d="M4,0 L226,0 C228.209139,-4.05812251e-16 230,1.790861 230,4 L230,66 C230,68.209139 228.209139,70 226,70 L4,70 C1.790861,70 2.705415e-16,68.209139 0,66 L0,4 C-2.705415e-16,1.790861 1.790861,4.05812251e-16 4,0 Z" id="path-1"></path>
<linearGradient x1="0%" y1="3.17377732%" x2="115.312974%" y2="115.99274%" id="linearGradient-3">
<stop stop-color="#D4E7FF" offset="0%"></stop>
<stop stop-color="#A9CBFF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="72.5432672%" id="linearGradient-4">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#F5F9FF" offset="100%"></stop>
</linearGradient>
<path d="M4,0 L226,0 C228.209139,-4.05812251e-16 230,1.790861 230,4 L230,66 C230,68.209139 228.209139,70 226,70 L4,70 C1.790861,70 2.705415e-16,68.209139 0,66 L0,4 C-2.705415e-16,1.790861 1.790861,4.05812251e-16 4,0 Z" id="path-5"></path>
</defs>
<g id="new" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="广告位" transform="translate(-318.000000, -123.000000)">
<g id="编组" transform="translate(318.000000, 123.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="v"></g>
<path d="M36.5081967,9.93488869 L36.5081967,32.4576271 L67,32.4576271 L67,5 L36.5081967,9.93488869 Z M36.5081967,60.1481125 L67,65 L67,37.5423729 L36.5081967,37.5423729 L36.5081967,60.1481125 Z M5,31.440678 L29.3934426,31.440678 L29.3934426,10.0847458 L5,14.1901801 L5,31.440678 Z M5,55.8947745 L29.3934426,59.9152542 L29.3934426,38.559322 L5,38.559322 L5,55.8947745 Z" id="形状" fill="url(#linearGradient-3)" mask="url(#mask-2)"></path>
<mask id="mask-6" fill="white">
<use xlink:href="#path-5"></use>
</mask>
<use id="v" fill-opacity="0.5" fill="url(#linearGradient-4)" xlink:href="#path-5"></use>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 69 38" class="design-iconfont">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 7.00285C1 4.23985 3.23985 2 6.00285 2C8.76585 2 11.0057 4.23985 11.0057 7.00285C11.0057 9.76585 8.76585 12.0057 6.00285 12.0057C3.23985 12.0057 1 9.76585 1 7.00285ZM11.006 29.9706C11.006 32.7336 8.7661 34.9735 6.0031 34.9735C3.2401 34.9735 1.00025 32.7336 1.00025 29.9706V18.646C1.00025 15.883 3.2401 13.6431 6.0031 13.6431C8.7661 13.6431 11.006 15.883 11.006 18.646V29.9706ZM46.0605 34.3022C43.6676 35.6837 40.608 34.8639 39.2265 32.471L31.5293 19.1392L23.9741 32.4717C22.5963 34.9031 19.4736 35.7224 17.0648 34.3055C14.7104 32.9206 13.8825 29.8918 15.2291 27.5153L27.1233 6.52593C28.5011 4.09455 31.6238 3.27524 34.0326 4.69216C34.8897 5.19631 35.5445 5.91831 35.9657 6.74739L38.0402 10.405L47.8916 27.4682C49.2731 29.861 48.4533 32.9207 46.0605 34.3022ZM57.6544 32.3693C59.0322 34.8007 62.1549 35.62 64.5637 34.2031C66.918 32.8182 67.746 29.7894 66.3993 27.4129L54.5052 6.42353C53.1274 3.99215 50.0046 3.17285 47.5958 4.58977C46.7395 5.09346 46.0852 5.81462 45.6639 6.64276L41.9572 13.178C43.3898 11.6567 45.8695 11.8817 47.0048 13.6361L47.2778 14.058L57.6544 32.3693Z" fill="url(#paint0_linear_118_5600)"/>
<defs>
<linearGradient id="paint0_linear_118_5600" x1="52.993" y1="27.5055" x2="1.00004" y2="20.6384" gradientUnits="userSpaceOnUse">
<stop stop-color="#006EFF"/>
<stop offset="1" stop-color="#2DB2FF"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="45px" height="33px" viewBox="0 0 45 33" version="1.1">
<title>编组 8</title>
<g id="web" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录" transform="translate(-32.000000, -37.000000)">
<g id="Group-1322" transform="translate(32.000000, 37.200000)">
<g id="编组-8" transform="translate(0.000000, -0.000108)">
<path d="M41.4141377,14.5526416 C39.557447,12.6651244 36.9696233,11.4755334 34.0927508,11.4755334 C31.6058158,11.4752249 29.4648729,12.3302 27.5956485,13.8477731 C26.7806481,14.5092911 25.9258802,15.3013233 24.850612,16.3426588 C24.3164594,16.8597784 8.83160619,31.839892 8.83160619,31.839892 C9.64335713,31.9551332 10.7597855,31.9895358 11.7552094,31.995861 C12.68781,32.001569 30.4793295,31.999872 31.2240793,31.999872 C32.7230178,31.999872 33.6986353,31.998175 34.7465151,31.9218104 C37.1497374,31.7470203 39.4200404,30.8682874 41.2552227,29.0716364 C45.3305342,25.081547 45.3918101,18.6056739 41.4141377,14.5526416 M38.4377692,26.2004814 C37.6479909,26.9797089 36.2392641,27.864767 33.9267178,27.9429829 C32.8573296,27.9793911 31.608601,27.9832479 31.0371568,27.9832479 L18.6114565,27.9832479 C23.132411,23.6054731 27.0760413,19.7866256 27.5233863,19.3537385 C27.9332849,18.9566425 28.8550539,18.0774468 29.6500933,17.3637848 C31.3953733,15.7968447 32.9668835,15.4815129 34.077896,15.4918491 C35.8191528,15.5082019 37.4027325,16.2172358 38.5346346,17.361625 C40.9559611,19.8290504 40.8987083,23.7723953 38.4377692,26.2004814" id="Fill-10" fill="#00A3FF"></path>
<path d="M16.4306689,13.5894293 C14.6104961,12.2312191 12.5726082,11.4722012 10.262383,11.4754306 C7.38551042,11.4754306 4.79753206,12.6650318 2.94084133,14.5527033 C-1.03667638,18.6057356 -0.97540048,25.0814544 3.09991109,29.0713896 C4.73610142,30.6735036 6.71828395,31.5451401 8.83214777,31.8393367 L12.8191044,27.9822297 C12.1744696,27.9796071 11.2492963,27.9708136 10.4282612,27.9430446 C8.11586963,27.8646745 6.70714287,26.9799249 5.91720987,26.2005431 C3.45627069,23.7724571 3.39901795,19.8289578 5.82049917,17.3613782 C6.95240121,16.2171432 8.53598092,15.5082636 10.277083,15.4920651 C11.3681345,15.4875912 12.8489687,15.8033859 14.5221412,17.1862795 C15.3208942,17.8464091 17.0943364,19.4006989 17.8723546,20.1001679 C17.9119673,20.1358047 17.9596264,20.1388901 18.0060475,20.1010935 L20.7512388,17.430492 C20.7987431,17.3846732 20.7959578,17.3225016 20.7490725,17.2803854 C19.4288553,16.0904859 17.5571551,14.4257375 16.4306689,13.5894293" id="Fill-11" fill="#00C8DC"></path>
<path d="M35.172135,9.15742793 C33.2778432,3.82285861 28.176934,0 22.1774663,0 C15.2955328,0 9.59254146,5.04546371 8.55967117,11.6176025 C9.11316585,11.5247308 9.68167004,11.4753638 10.2623985,11.4753638 C11.070281,11.4742839 11.8441213,11.5683898 12.5877879,11.7467281 C12.6023332,11.7498136 12.6168785,11.7515106 12.6312691,11.7550588 C13.5637149,7.31758081 17.4983705,4.02156086 22.1774663,4.02156086 C26.074366,4.02156086 29.4931279,6.36495159 31.0344644,9.68565505 C31.0587581,9.73795323 31.0997635,9.75523169 31.141852,9.74366129 C32.3009878,9.42616965 33.6908366,9.24150614 35.0331811,9.34024018 C35.163934,9.34980504 35.2142235,9.2763716 35.172135,9.15742793" id="Fill-12" fill="#006EFF"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="116px" height="116px" viewBox="0 0 116 116" version="1.1">
<title>椭圆形</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="注销账户" transform="translate(-317.000000, -427.000000)">
<rect fill="#F7F8FA" x="0" y="0" width="750" height="1624"></rect>
<g id="编组-24" transform="translate(0.000000, 268.000000)" fill="#FFFFFF">
<polygon id="矩形" points="0 -8.32003216e-12 750 -8.32003216e-12 750 1356 0 1356"></polygon>
</g>
<g id="编组-9" transform="translate(317.000000, 427.000000)">
<circle id="椭圆形" fill="#FF9C19" cx="58" cy="58" r="58"></circle>
<rect id="矩形" fill="#FFFFFF" x="54.4848485" y="26.3636364" width="7.03030303" height="47.4545455" rx="3.51515152"></rect>
<rect id="矩形备份-9" fill="#FFFFFF" x="54.4848485" y="80.8484848" width="7.03030303" height="7.03030303" rx="3.51515152"></rect>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,349 +0,0 @@
<template>
<div :class="['about-container', 'container', isH5 && 'container-h5']" @click="closeAboutBox" @mousedown.stop>
<div :class="['about-box', 'box', isH5 && 'box-h5']" @click.stop>
<header v-if="isH5" class="title">
<div class="title-back" @click="closeAboutBox">
<Icon :file="backSVG" />
</div>
<div class="title-name">
{{ TUITranslateService.t('Home.关于腾讯云·通信') }}
</div>
</header>
<main class="main">
<div class="main-name">
<img class="logo" src="../assets/image/logo.svg" alt="" />
<div class="name">
{{ TUITranslateService.t('即时通信') }}
</div>
</div>
<div class="main-version">{{ TUITranslateService.t('Home.SDK版本') }}: {{ SDKVersion }}</div>
</main>
<footer class="footer">
<ul class="list">
<li class="line">
<a class="link" :href="Link.privacy.url" target="_blank">
{{ TUITranslateService.t(`Login.${Link.privacy.label}`) }}
</a>
<a class="link" :href="Link.agreement.url" target="_blank">
{{ TUITranslateService.t(`Login.${Link.agreement.label}`) }}
</a>
<a class="link" @click="toggleDisclaimer">
{{ TUITranslateService.t('Home.免责声明') }}
<div v-if="isDisclaimerBoxShow" :class="['disclaimer-container', 'container', isH5 && 'container-h5']" @click="toggleDisclaimer">
<div :class="['disclaimer-box', 'box', isH5 && 'box-h5']" @click.stop>
<header v-if="isH5" class="title">
<div class="title-back" @click="toggleDisclaimer">
<Icon :file="backSVG" />
</div>
<div class="title-name">
{{ TUITranslateService.t('Home.关于腾讯云·通信') }}
</div>
</header>
<main class="main">
<header class="main-title">
{{ TUITranslateService.t(`Home.IM-免责声明`) }}
</header>
<p class="main-info">
{{
TUITranslateService.t(
`Home.IM“本产品”是由腾讯云提供的一款测试产品腾讯云享有本产品的著作权和所有权。本产品仅用于功能体验不得用于任何商业用途。依据相关部门监管要求严禁在使用中有任何色情、辱骂、暴恐、涉政等违法内容传播。`
)
}}
</p>
</main>
<footer class="footer">
<button class="btn btn-default" @click.stop="submitDisclaimer">
{{ TUITranslateService.t('Home.同意') }}
</button>
</footer>
</div>
</div>
</a>
</li>
<li class="line">
<a class="link" :href="Link.contact.url" target="_blank">
{{ TUITranslateService.t(`Home.${Link.contact.label}`) }}
</a>
<a class="link" @click="toggleCancellation">
{{ TUITranslateService.t('Home.注销账户') }}
<div v-if="isCancellationBoxShow" :class="['cancellation-container', 'container', isH5 && 'container-h5']" @click="toggleCancellation">
<div :class="['cancellation-box', 'box', isH5 && 'box-h5']" @click.stop>
<header v-if="isH5" class="title">
<div class="title-back" @click="toggleCancellation">
<Icon :file="backSVG" />
</div>
<div class="title-name">
{{ TUITranslateService.t('Home.关于腾讯云·通信') }}
</div>
</header>
<main class="main">
<img src="../assets/image/warn.svg" width="60" height="60" />
<p class="main-text">
{{ TUITranslateService.t('Home.注销后,您将无法使用当前账号,相关数据也将删除无法找回') }}
</p>
<p>
<span>{{ TUITranslateService.t('Home.当前账号') + ': ' }}</span>
<span class="main-id">{{ props.userProfile.userID }}</span>
</p>
</main>
<footer class="footer">
<button class="btn btn-error" @click.stop="submitCancellation">
{{ TUITranslateService.t('Home.注销') }}
</button>
<button class="btn btn-default" @click.stop="toggleCancellation">
{{ TUITranslateService.t('Home.取消') }}
</button>
</footer>
</div>
</div></a
>
</li>
<li class="line">
<p class="copyright">Copyright © 2013-2023 Tencent Cloud. All Rights Reserved.</p>
</li>
</ul>
</footer>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, withDefaults, defineProps, defineEmits } from '@/TUIKit/adapter-vue';
import { TUITranslateService, TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
import { TUILogin } from '@tencentcloud/tui-core';
import Icon from '@/TUIKit/components/common/Icon.vue';
import backSVG from '@/TUIKit/assets/icon/back.svg';
import { isH5 } from '@/TUIKit/utils/env';
import { Link } from '@/utils/link';
import { cancellation } from '@/api/im';
import { IUserProfile } from '@/TUIKit/interface';
import router from '@/router';
const props = withDefaults(
defineProps<{
userProfile: IUserProfile;
}>(),
{
userProfile: () => ({}) as IUserProfile
}
);
const emits = defineEmits(['closeAboutBox']);
const isAboutBoxShow = ref<boolean>(false);
const isDisclaimerBoxShow = ref<boolean>(false);
const isCancellationBoxShow = ref<boolean>(false);
const SDKVersion = TUIStore.getData(StoreName.APP, 'SDKVersion');
function closeAboutBox() {
isAboutBoxShow.value = false;
emits('closeAboutBox');
}
// Disclaimer dialog
function toggleDisclaimer() {
isDisclaimerBoxShow.value = !isDisclaimerBoxShow.value;
}
function submitDisclaimer() {
isDisclaimerBoxShow.value = false;
}
// Cancellation dialog
function toggleCancellation() {
isCancellationBoxShow.value = !isCancellationBoxShow.value;
}
function submitCancellation() {
isCancellationBoxShow.value = false;
const deleteInfo: any = localStorage.getItem('TUIKit-userInfo');
const deleteInfoList = JSON.parse(deleteInfo);
const options: any = {
userId: deleteInfoList.userId,
token: deleteInfoList.token,
phone: deleteInfoList.phone
};
TUILogin.logout().then(() => {
localStorage.removeItem('TUIKit-userInfo');
cancellation(options);
router.push({ path: '/' });
});
}
</script>
<style scoped lang="scss">
@import '../styles/common';
.main {
flex: 1;
@include flex;
}
.btn {
flex: 1;
margin-top: 14px;
margin-right: 10px;
&:last-child {
margin-right: 0;
}
}
.btn-default {
@include btn-default;
}
.btn-error {
@include btn-error;
}
.about-container {
.about-box {
padding: 100px 180px;
padding-bottom: 0;
.main {
padding-bottom: 126px;
.main-name {
@include flex;
padding-bottom: 28px;
.logo {
width: 110px;
}
.name {
font-size: 40px;
font-family: PingFangSC-Medium;
font-weight: 500;
}
}
.main-version {
color: #999;
}
}
.footer {
.list {
@include flex;
list-style: none;
.line {
@include flex(row, center, center);
padding-top: 10px;
.link {
font-size: 16px;
padding: 0 10px;
color: #006eff;
border-right: 1px solid #eee;
}
.link:last-child {
border-right: 0 solid #000;
}
.copyright {
font-size: 14px;
padding: 25px 0;
color: #999;
}
}
}
}
}
.disclaimer-box {
@include flex(column, center, stretch);
padding: 10px 10px 0;
.main {
align-items: flex-start;
width: 360px;
font-size: 1rem;
padding: 3.5rem 4rem;
color: #000;
.main-title {
font-size: 18px;
padding-bottom: 5px;
}
.main-info {
text-wrap: wrap;
}
}
.footer {
display: flex;
padding: 4rem;
}
}
.cancellation-box {
@include flex;
padding: 55px 42px;
max-width: 566px;
.main {
@include flex;
padding-bottom: 30px;
.main-text {
margin-top: 20px;
text-wrap: wrap;
text-align: center;
}
.main-info {
text-wrap: wrap;
}
.main-id {
color: #006eff;
}
}
.footer {
display: flex;
flex-direction: row;
width: 100%;
.btn {
flex: 1;
}
}
}
}
.about-box.box-h5 {
padding: 0;
}
.disclaimer-box.box-h5,
.cancellation-box.box-h5 {
padding: 0;
width: 100%;
height: 100%;
justify-content: flex-start;
.main {
flex: none;
box-sizing: border-box;
padding: 30px;
width: 100%;
}
.footer {
box-sizing: border-box;
padding: 10px 30px;
.btn {
height: 50px;
}
}
}
</style>

View File

@ -1,31 +0,0 @@
<template>
<ul class="adv-list">
<li v-for="(item, index) of list" :key="index" :item="item">
<slot name="item" :data="item" />
</li>
</ul>
</template>
<script setup lang="ts">
import { defineProps } from '@/TUIKit/adapter-vue';
const props = defineProps({
list: {
type: Array,
default: () => []
}
});
</script>
<style scoped lang="scss">
.adv-list {
flex: 1;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
li {
width: 150px;
}
}
</style>

View File

@ -1,105 +0,0 @@
<template>
<li class="adv-list-item">
<div class="show-box" @click="showEvent">
<label class="img-box">
<img :src="item?.icon" alt="" />
</label>
<span class="name">{{ item?.name && TUITranslateService.t(`Login.${item?.name}`) }}</span>
</div>
<div class="show-box hover-box" @click="hoverEvent">
<label class="img-box">
<img :src="item?.link" alt="" />
</label>
<span class="name">{{ item?.detail && TUITranslateService.t(`Login.${item?.name}`) }}</span>
<span class="name">{{ item?.detail && TUITranslateService.t(`Login.${item?.detail}`) }}</span>
</div>
</li>
</template>
<script lang="ts" setup>
import { defineProps, defineEmits, withDefaults } from '@/TUIKit/adapter-vue';
import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
type IAdvListItem = {
name?: string;
link?: string;
detail?: string;
};
const props = withDefaults(
defineProps<{
item: IAdvListItem;
}>(),
{
item: () => ({}) as IAdvListItem
}
);
const emits = defineEmits(['showEvent', 'hoverEvent']);
const showEvent = () => {
emits('showEvent', props.item);
};
const hoverEvent = () => {
emits('hoverEvent', props.item);
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.adv-list-item {
display: flex;
flex-direction: column;
align-items: center;
&:hover {
.show-box {
display: none;
}
.hover-box {
display: flex;
}
}
.show-box {
display: flex;
flex-direction: column;
align-items: center;
.img-box {
width: 82px;
height: 82px;
border-radius: 8px;
background: rgba(255, 255, 255, 1);
box-shadow: 0 8px 12px 0 rgba(223, 235, 253, 0.5);
display: flex;
justify-content: center;
align-items: center;
img {
max-width: 100%;
max-height: 100%;
}
}
.name {
color: rgba(0, 0, 0, 1);
font-size: 12px;
font-weight: 400;
font-family: 'PingFang SC';
text-align: left;
line-height: 16px;
height: 16px;
padding-top: 8px;
}
}
.hover-box {
display: none;
position: relative;
top: -15px;
}
}
</style>

View File

@ -1,59 +0,0 @@
<template>
<div class="welcome">
<div class="welcome-title">
{{ TUITranslateService.t('Home.欢迎使用') }}
<img class="logo" src="../assets/image/logo.svg" alt="" />
{{ TUITranslateService.t('即时通信') }}
</div>
<div v-if="isOfficial" class="welcome-content">
{{
TUITranslateService.t(
'Home.我们为您默认提供了一位“示例好友”和一个“示例客服群”您不用额外添加好友和群聊就可完整体验腾讯云 IM 单聊、群聊的所有功能。'
)
}}
<br />
{{ TUITranslateService.t('Home.随时随地') }}
</div>
</div>
</template>
<script setup lang="ts">
import { TUITranslateService, TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
const isOfficial = TUIStore.getData(StoreName.APP, 'isOfficial');
</script>
<style lang="scss" scoped>
.welcome {
width: 100%;
height: 100%;
box-sizing: border-box;
padding-left: 40px;
padding-top: 100px;
display: flex;
flex-direction: column;
background: url('../assets/image/login-background.png') no-repeat;
background-size: cover;
background-position-x: -17px;
background-position-y: 173px;
.welcome-title {
font-size: 1.75rem;
display: flex;
align-items: center;
font-family: PingFangSC-Medium;
font-weight: 500;
color: #000;
.logo {
width: 40px;
padding-left: 0.98rem;
padding-right: 0.98rem;
}
}
.welcome-content {
padding-top: 1.88rem;
max-width: 393px;
font-size: 16px;
line-height: 24px;
font-family: PingFangSC-Regular;
font-weight: 400;
color: #666;
}
}
</style>

View File

@ -1,463 +0,0 @@
<template>
<div
class="edit-profile-container container dialog"
:class="[isH5 ? 'edit-profile-container-h5' : 'edit-profile-container-pc']"
@click="closeEditProfileBox"
@mousedown.stop
>
<div :class="['edit-profile-box']" @click.stop>
<header class="title">
<div v-if="isH5" class="title-back" @click="closeEditProfileBox">
<Icon :file="backSVG"></Icon>
</div>
<div class="title-name">{{ TUITranslateService.t('Profile.编辑资料') }}</div>
</header>
<div class="edit-form">
<div v-if="isH5" class="edit-form-space"></div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.头像') }}</div>
<div v-if="isH5" class="form-info" @click="showBottomPopup('avatar')">
<Avatar useSkeletonAnimation :url="userProfile.avatar" size="60px" />
<Icon class="form-info-arrow" :file="rightArrowIcon" size="14px"></Icon>
</div>
<EditProfilePopup
class="form-item"
:show="isPC || currentBottomPopupShow === 'avatar'"
:title="TUITranslateService.t('Profile.选择头像')"
@onClose="closeBottomPopup"
@onSubmit="submitEditProfileBox"
>
<ul class="avatar-list">
<li
:class="['avatar-list-item', currentEditProfile.avatar === avatar && 'avatar-list-item-selected']"
v-for="avatar in avatarList"
:key="avatar"
@click="changeCurrentEditProfile('avatar', avatar)"
>
<Avatar useSkeletonAnimation :url="avatar" :size="isPC ? '36px' : '50px'" />
</li>
</ul>
</EditProfilePopup>
</div>
<div v-if="isH5" class="edit-form-space"></div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.昵称') }}</div>
<div v-if="isH5" class="form-info" @click="showBottomPopup('nick')">
<div class="form-info-content">{{ userProfile.nick }}</div>
<Icon class="form-info-arrow" :file="rightArrowIcon" size="14px"></Icon>
</div>
<EditProfilePopup
class="form-item"
:show="isPC || currentBottomPopupShow === 'nick'"
:title="TUITranslateService.t('Profile.设置昵称')"
@onClose="closeBottomPopup"
@onSubmit="submitEditProfileBox"
>
<input class="form-item-input" type="text" v-model="currentEditProfile.nick" />
</EditProfilePopup>
</div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.账号') }}</div>
<div class="form-info">{{ userProfile.userID }}</div>
</div>
<div v-if="isH5" class="edit-form-space"></div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.个性签名') }}</div>
<div v-if="isH5" class="form-info" @click="showBottomPopup('selfSignature')">
<div class="form-info-content">{{ userProfile.selfSignature }}</div>
<Icon class="form-info-arrow" :file="rightArrowIcon" size="14px"></Icon>
</div>
<EditProfilePopup
class="form-item"
:show="isPC || currentBottomPopupShow === 'selfSignature'"
:title="TUITranslateService.t('Profile.个性签名')"
@onClose="closeBottomPopup"
@onSubmit="submitEditProfileBox"
>
<input class="form-item-input" type="text" v-model="currentEditProfile.selfSignature" />
</EditProfilePopup>
</div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.性别') }}</div>
<div v-if="isH5" class="form-info" @click="showBottomPopup('gender')">
<div>
{{ (userProfile.gender && TUITranslateService.t(`Profile.${genderLabelList[userProfile.gender]}`)) || '' }}
</div>
<Icon class="form-info-arrow" :file="rightArrowIcon" size="14px"></Icon>
</div>
<EditProfilePopup
class="form-item"
:show="isPC || currentBottomPopupShow === 'gender'"
:title="TUITranslateService.t('Profile.性别选择')"
@onClose="closeBottomPopup"
@onSubmit="submitEditProfileBox"
>
<ul class="gender-list">
<li class="gender-list-li" v-for="(value, key) in genderLabelList" :key="key" @click="changeCurrentEditProfile('gender', key)">
<div
:class="['gender-list-item', currentEditProfile.gender === key && 'gender-list-item-selected']"
@click="changeCurrentEditProfile('gender', key)"
>
<input v-if="isPC" class="gender-list-radio" type="radio" name="gender" :value="key" :checked="currentEditProfile.gender === key" />
{{ TUITranslateService.t(`Profile.${value}`) }}
</div>
</li>
</ul>
</EditProfilePopup>
</div>
<div class="edit-form-item">
<div class="form-label">{{ TUITranslateService.t('Profile.出生年月') }}</div>
<div v-if="isH5" class="form-info" @click="showBottomPopup('birthday')">
<div class="form-info-content">{{ birthdayObj.format }}</div>
<Icon class="form-info-arrow" :file="rightArrowIcon" size="14px"></Icon>
</div>
<EditProfilePopup
class="form-item"
:show="isPC || currentBottomPopupShow === 'birthday'"
:title="TUITranslateService.t('Profile.请选择出生日期')"
@onClose="closeBottomPopup"
@onSubmit="submitEditProfileBox"
>
<div class="birthday-container">
<DatePicker
class="birthday-date-picker"
type="single"
rangeTableType="one"
:startPlaceholder="TUITranslateService.t('Profile.请选择出生日期')"
popupPosition="top"
:defaultSingleDate="birthdayObj.obj"
@pick="pickBirthday"
>
<template #end-icon>
<Icon :file="calendarSVG" size="16px"></Icon>
</template>
</DatePicker>
</div>
</EditProfilePopup>
</div>
</div>
<footer v-if="!isH5" class="edit-footer">
<button class="btn-close" @click="closeEditProfileBox">
{{ TUITranslateService.t('Profile.取消') }}
</button>
<button class="btn-save" @click="submitEditProfileBox">
{{ TUITranslateService.t('Profile.保存') }}
</button>
</footer>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, defineEmits } from '@/TUIKit/adapter-vue';
import TUIChatEngine, { TUITranslateService, TUIUserService, TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
import dayjs, { Dayjs } from 'dayjs';
import { Toast, TOAST_TYPE } from '@/TUIKit/components/common/Toast/index';
import EditProfilePopup from './EditProfilePopup.vue';
import DatePicker from '@/TUIKit/components/common/DatePicker';
import Avatar from '@/TUIKit/components/common/Avatar/index.vue';
import Icon from '@/TUIKit/components/common/Icon.vue';
import backSVG from '@/TUIKit/assets/icon/back.svg';
import rightArrowIcon from '@/TUIKit/assets/icon/right-icon.svg';
import calendarSVG from '../assets/icon/calendar.svg';
import { IUserProfile } from '@/TUIKit/interface';
import { isH5, isPC } from '@/TUIKit/utils/env';
import { enableSampleTaskStatus } from '@/TUIKit/utils/enableSampleTaskStatus';
const emits = defineEmits(['closeEditProfileBox']);
// config
const avatarListBaseUrl = 'https://im.sdk.qcloud.com/download/tuikit-resource/avatar/avatar_';
const avatarList = ['1.png', '2.png', '3.png', '4.png', '5.png', '6.png'].map((url: string) => avatarListBaseUrl + url);
const genderLabelList: {
[propsName: string]: string;
} = {
[TUIChatEngine.TYPES.GENDER_MALE]: '男',
[TUIChatEngine.TYPES.GENDER_FEMALE]: '女',
[TUIChatEngine.TYPES.GENDER_UNKNOWN]: '不显示'
};
const userProfile = ref<IUserProfile>({});
// current edit value
const currentEditProfile = ref<IUserProfile>({
avatar: userProfile.value?.avatar,
nick: userProfile.value?.nick,
selfSignature: userProfile.value?.selfSignature,
gender: userProfile.value?.gender,
birthday: userProfile.value?.birthday
});
const birthdayObj = ref<{ obj: typeof Dayjs; format: string; value: number }>({});
const currentBottomPopupShow = ref<string>('');
TUIStore.watch(StoreName.USER, {
userProfile: (userProfileData: IUserProfile) => {
userProfile.value = userProfileData;
const { avatar, nick, selfSignature, gender, birthday } = userProfileData;
currentEditProfile.value = { avatar, nick, selfSignature, gender, birthday };
birthdayObj.value = generateBirthdayObj(userProfileData.birthday);
}
});
function generateBirthdayObj(YYYYMMDD: any) {
let birthdayDayjsObj: typeof Dayjs = null;
let birthdayFormat = '';
if (YYYYMMDD && typeof YYYYMMDD === 'number') {
birthdayDayjsObj = dayjs(YYYYMMDD.toString(), 'YYYYMMDD');
birthdayFormat = birthdayDayjsObj.format('YYYY/MM/DD');
}
return {
obj: birthdayDayjsObj,
format: birthdayFormat,
value: userProfile.value?.birthday || 0
};
}
function showBottomPopup(key: string) {
currentBottomPopupShow.value = key;
}
function closeBottomPopup() {
currentBottomPopupShow.value = '';
}
function pickBirthday(date: typeof Dayjs) {
currentEditProfile.value.birthday = parseInt(date.format('YYYYMMDD'), 10);
}
function changeCurrentEditProfile(key: keyof IUserProfile, value: any) {
if (Object.prototype.hasOwnProperty.call(currentEditProfile.value, key)) {
currentEditProfile.value[key] = value;
}
}
function closeEditProfileBox() {
emits('closeEditProfileBox');
}
function submitEditProfileBox() {
const isNickModified = currentEditProfile.value.nick !== userProfile.value.nick;
const profileOptions = Object.fromEntries(
Object.entries(currentEditProfile.value).filter(([key, value]) => {
return value !== null && value !== undefined && value !== '';
})
);
TUIUserService.updateMyProfile(profileOptions)
.then(() => {
isNickModified && enableSampleTaskStatus('modifyNickName');
Toast({
message: TUITranslateService.t('Profile.修改个人资料成功'),
type: TOAST_TYPE.SUCCESS
});
isPC && closeEditProfileBox();
})
.catch((error: Error) => {
Toast({
message: TUITranslateService.t('Profile.修改个人资料失败') + error?.message,
type: TOAST_TYPE.ERROR
});
isPC && closeEditProfileBox();
});
}
</script>
<style lang="scss" scoped>
@import '../styles/common.scss';
.edit-profile-container {
@extend .container;
font-size: 14px;
.edit-profile-box {
@extend .box;
align-items: stretch;
.edit-form {
flex: 1;
@include flex(column, flex-start, stretch);
.edit-form-item {
@include flex(row, flex-start, center);
min-height: 54px;
padding: 10px;
.form-label {
box-sizing: border-box;
width: 70px;
margin-right: 20px;
color: #333;
}
.form-item {
@include flex(row, flex-start, stretch);
.avatar-list {
@include flex(row, space-between, stretch);
.avatar-list-item {
margin: 10px;
border: 1px solid transparent;
}
.avatar-list-item:first-child {
margin-left: 0px;
}
.avatar-list-item-selected {
border: 1px solid #006eff;
color: #006eff;
border-radius: 5px;
}
}
.form-item-input {
flex: 1;
padding: 6px 10px;
border: 1px solid rgba(131, 137, 153, 0.4);
border-radius: 2px;
line-height: 20px;
color: #596174;
}
.gender-list {
@include flex(row, space-between, center);
.gender-list-li {
@include flex(row);
margin-right: 20px;
.gender-list-item {
@include flex(row);
flex: 1;
font-size: 14px;
.gender-list-item-radio {
margin: 0px 2px;
}
}
}
}
.birthday-container {
@include flex(row, space-between, stretch);
flex: 1;
padding: 6px 10px;
border: 1px solid rgba(131, 137, 153, 0.4);
.birthday-date-picker {
@include flex(row);
flex: 1;
height: 20px;
:deep(.tui-date-picker-input) {
@include flex(row, flex-start);
flex: 1;
}
:deep(.tui-date-picker-input-start) {
padding: 2px 0px;
text-align: start;
font-size: 14px;
&::placeholder {
text-align: start;
}
}
:deep(.tui-date-picker-dialog-container-one) {
left: -220px;
}
}
}
}
}
}
.edit-footer {
@include flex(row, flex-end);
.btn-close {
@include btn-normal;
margin-right: 10px;
}
.btn-save {
@include btn-default;
}
.btn-close,
.btn-save {
width: 90px;
height: 30px;
padding: 2px;
}
}
}
}
.edit-profile-container-pc {
.edit-profile-box {
width: 495px;
height: 472px;
border-radius: 10px;
padding: 20px;
.edit-form {
.edit-form-item {
.form-item {
flex: 1;
}
}
}
}
.title {
justify-content: flex-start;
padding: 0px;
}
}
.edit-profile-container-h5 {
@extend .edit-profile-container;
.edit-profile-box {
@extend .box-h5;
width: 100%;
height: 100%;
background-color: #efefef;
.title {
background-color: #ffffff;
}
.edit-form {
.edit-form-item {
background-color: #ffffff;
.form-label {
font-size: 16px;
color: #000000;
width: 80px;
}
.form-info {
@include flex(row, flex-end, stretch);
.form-info-content {
@include single-line-ellipsis(auto);
}
flex: 1;
overflow: hidden;
font-size: 16px;
color: rgba(151, 151, 151, 1);
.form-info-arrow {
margin-left: 2px;
}
}
.form-item {
flex: none;
.avatar-list,
.form-item-input,
.gender-list,
.birthday-container {
margin: 0 20px;
}
.avatar-list {
.avatar-list-item {
margin: 10px 0px;
}
}
.gender-list {
.gender-list-li {
margin: 0px;
.gender-list-item {
border: 1px solid rgba(221, 221, 221, 1);
font-size: 16px;
border-radius: 5px;
width: 120px;
height: 40px;
&-selected {
border: 1px solid #006eff;
color: #006eff;
border-radius: 5px;
}
}
}
}
.form-item-input {
padding: 14px 10px;
font-size: 16px;
border: 0px;
background-color: rgba(248, 248, 248, 1);
}
}
}
.edit-form-space {
box-sizing: border-box;
height: 10px;
padding: 0px;
background-color: transparent;
}
}
}
}
</style>

View File

@ -1,38 +0,0 @@
<template>
<BottomPopup
class="form-item-bottom-popup"
:show="props.show"
:title="props.title"
:showHeaderCloseButton="true"
:showFooterSubmitButton="true"
:submitButtonContent="TUITranslateService.t('确认')"
borderRadius="20px"
@onClose="onClose"
@onSubmit="onSubmit"
>
<slot></slot>
</BottomPopup>
</template>
<script setup lang="ts">
import { withDefaults, defineProps, defineEmits } from '@/TUIKit/adapter-vue';
import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
import BottomPopup from '@/TUIKit/components/common/BottomPopup';
const props = withDefaults(
defineProps<{
show: boolean;
title: string;
}>(),
{
show: false,
title: ''
}
);
const emits = defineEmits(['onClose', 'onSubmit']);
function onClose() {
emits('onClose');
}
function onSubmit() {
emits('onSubmit');
}
</script>
<style scoped lang="scss"></style>

View File

@ -1,147 +0,0 @@
<template>
<div class="header">
<div class="left">
<div v-if="showType === 'menu'" class="menu" @click="toggleMenu">
<Icon :file="menuPNG" />
<div class="menu-guide">
{{ TUITranslateService.t('使用指引') }}
</div>
</div>
<div v-else-if="showType === 'logo'" class="logo">
<a :href="Link.im.url" target="_blank" class="logo">
<img class="logo-img" src="../assets/image/txc-logo.svg" alt="" />
<div class="logo-name label-tencent">{{ TUITranslateService.t('腾讯云') }}</div>
<div class="logo-name label-im">{{ TUITranslateService.t('即时通信IM') }}</div>
</a>
</div>
</div>
<div class="right">
<el-dropdown @command="changeLanguage">
<div class="dropdown">
<Icon :file="globalPNG" />
<div class="dropdown-label">
{{ localeLabelMap[locale] }}
</div>
<Icon :file="arrowDownPNG" width="10px" height="5px" />
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="zh" class="language-item"> 简体中文 </el-dropdown-item>
<el-dropdown-item command="en" class="language-item"> English </el-dropdown-item>
<el-dropdown-item command="zh_tw" class="language-item"> 繁體中文 </el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</template>
<script lang="ts" setup>
import { withDefaults, defineProps, defineEmits, ref } from '@/TUIKit/adapter-vue';
import { TUITranslateService } from '@tencentcloud/chat-uikit-engine';
import { TUICore, TUIConstants } from '@tencentcloud/tui-core';
import Icon from '@/TUIKit/components/common/Icon.vue';
import menuPNG from '@/views/im/assets/icon/menu.png';
import globalPNG from '@/views/im/assets/icon/global.png';
import arrowDownPNG from '@/views/im/assets/icon/arrow-down.png';
import { Link } from '@/utils/link';
const props = withDefaults(
defineProps<{
showType: 'menu' | 'logo';
defaultLanguage: string;
}>(),
{
showType: 'logo',
defaultLanguage: 'zh'
}
);
const localeLabelMap: { [propsName: string]: string } = {
zh: '简体中文',
en: 'English',
zh_tw: '繁體中文'
};
const emits = defineEmits(['toggleMenu', 'closeMenu', 'changeLanguage']);
const locale = ref<string>(props.defaultLanguage);
function toggleMenu() {
emits('toggleMenu');
}
function changeLanguage(value: string) {
TUITranslateService.changeLanguage(value).then(() => {
locale.value = value;
emits('changeLanguage', locale.value);
TUICore.notifyEvent(TUIConstants.TUITranslate.EVENT.LANGUAGE_CHANGED, TUIConstants.TUITranslate.EVENT_SUB_KEY.CHANGE_SUCCESS, {
language: locale.value
});
});
}
</script>
<style scoped lang="scss">
.header {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
box-sizing: border-box;
padding: 20px 34px;
user-select: none;
.left {
.menu,
.logo {
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
font-size: 14px;
font-weight: 500;
line-height: 20px;
}
.menu {
.menu-guide {
margin-left: 15px;
}
}
.logo {
.logo-img {
width: 30px;
margin-right: 7px;
}
.logo-name {
font-family: PingFangSC-Regular;
font-size: 18px;
font-weight: 500;
display: flex;
}
.label-tencent {
padding-right: 15px;
border-right: 1px solid #ddd;
}
.label-im {
padding-left: 15px;
}
}
}
.right {
.dropdown {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
cursor: pointer;
.dropdown-label {
padding: 0 8px;
}
}
}
}
</style>

View File

@ -1,389 +0,0 @@
<template>
<div :class="['menu', isH5 && 'menu-h5']">
<div v-if="isPC" class="header header-border">
<div class="header-tencent-cloud">
<img class="header-icon" src="../assets/image/txc-logo.svg" alt="" />
<span class="header-name">{{ TUITranslateService.t('腾讯云') }}</span>
</div>
<div class="header-im header-name">
{{ TUITranslateService.t('即时通信IM') }}
</div>
</div>
<div v-if="isH5" class="header header-guide">
<div class="header-name">
{{ TUITranslateService.t('使用指引') }}
</div>
<div class="header-close" @click="closeMenu">
{{ TUITranslateService.t('关闭') }}
</div>
</div>
<div class="main">
<div v-for="item in apkQRCodeList" :key="item.url" class="task">
<div class="task-title">
{{ TUITranslateService.t(`Home.${item.label}`) }}
</div>
<div class="task-list qr-box">
<img class="qr-code" :src="item.url" />
</div>
</div>
<div class="task">
<div class="task-title">
{{ TUITranslateService.t('Home.建议体验功能') }}
</div>
<div class="task-list">
<div v-for="(taskLabel, taskKey) in taskLabelMap" :key="taskKey" :class="['task-list-item', tasks[taskKey] && 'task-list-item-done']">
<div class="task-list-item-label">
{{ TUITranslateService.t(`Home.${taskLabel}`) }}
</div>
<div class="task-list-item-status">
{{ TUITranslateService.t(tasks[taskKey] ? 'Home.已完成' : 'Home.待体验') }}
</div>
</div>
</div>
</div>
<div class="step">
<div class="step-title">
{{ TUITranslateService.t('Home.用UI组件快速集成') }}
</div>
<div class="step-list">
<div v-for="(step, index) in stepList" :key="step.label" class="step-list-item">
<div class="step-list-item-index">
{{ index + 1 }}
</div>
<a class="step-list-item-label" :href="step.url" target="_blank">{{ TUITranslateService.t(`Home.${step.label}`) }}</a>
</div>
</div>
</div>
</div>
<div class="footer">
<div class="footer-card-list">
<div v-for="advItem in advList" :key="advItem.label" class="footer-card" @click="openLink(advItem.url)">
<div class="footer-card-content">
<div>{{ TUITranslateService.t(`Home.${advItem.label}`) }}</div>
<div>{{ TUITranslateService.t(`Home.${advItem.subLabel}`) }}</div>
</div>
<div class="footer-card-button">
{{ TUITranslateService.t(`Home.${advItem.btnText}`) }}
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { defineEmits, onMounted, ref, onUnmounted } from '@/TUIKit/adapter-vue';
import { TUITranslateService, TUIStore, StoreName } from '@tencentcloud/chat-uikit-engine';
import { Link } from '@/utils/link';
import { isPC, isH5 } from '@/TUIKit/utils/env';
import { deepCopy } from '@/TUIKit/components/TUIChat/utils/utils';
interface ITasks {
[propsName: string]: boolean;
}
const emits = defineEmits(['closeMenu']);
const stepList = Link.stepList;
const advList = Link.advList;
const apkQRCodeList = Link.apkQRCodeList;
const tasks = ref<ITasks>({
sendMessage: false,
revokeMessage: false,
modifyNickName: false,
groupChat: false,
muteGroup: false,
dismissGroup: false,
call: false,
searchCloudMessage: false,
customerService: false
});
const taskLabelMap = {
sendMessage: '发送一条消息',
revokeMessage: '撤回一条消息',
modifyNickName: '修改一次我的昵称',
groupChat: '发起一个群聊',
muteGroup: '开启一次群禁言',
dismissGroup: '解散一个群聊',
call: '发起一次通话',
searchCloudMessage: '搜索一次消息',
customerService: '进行一次客服会话'
};
onMounted(() => {
TUIStore.watch(StoreName.APP, {
tasks: setTasksValue
});
});
onUnmounted(() => {
TUIStore.unwatch(StoreName.APP, {
tasks: setTasksValue
});
});
function setTasksValue(tasksValue: ITasks) {
if (JSON.stringify(tasksValue) === '{}') {
return;
}
tasks.value = deepCopy(tasksValue);
}
function closeMenu() {
emits('closeMenu');
}
function openLink(url: string) {
window.open(url);
}
</script>
<style scoped lang="scss">
.menu,
.header,
.main,
.footer {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.menu {
width: 300px;
z-index: 100;
background: rgb(255, 255, 255);
box-shadow: 10px 20px 30px 0 rgba(56, 73, 90, 0.09);
padding: 0 30px;
user-select: none;
overflow: auto;
.header {
width: 100%;
flex-direction: row;
padding: 20px 0;
.header-tencent-cloud,
.header-im {
box-sizing: border-box;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.header-tencent-cloud {
padding-right: 20px;
}
.header-im {
padding-left: 20px;
border-left: 1px solid rgb(221, 221, 221);
}
.header-name {
font-size: 16px;
font-weight: 500;
color: rgb(0, 0, 0);
font-style: normal;
font-family: PingFangSC-Regular;
}
.header-icon {
width: 30px;
margin-right: 7px;
}
}
.header-border {
border-bottom: 1px solid rgb(221, 221, 221);
}
.header-guide {
padding-bottom: 0;
justify-content: space-between;
.header-name {
font-family: PingFangSC-Medium;
font-weight: 500;
font-size: 20px;
color: #000;
line-height: 28px;
}
.header-close {
font-family: PingFangSC-Regular;
font-weight: 400;
color: #006eff;
font-size: 18px;
}
}
.main {
width: 100%;
padding-bottom: 16px;
font-size: 14px;
font-family: PingFangSC-Regular;
font-weight: 400;
.task,
.step {
width: 100%;
}
.task-title,
.step-title {
padding: 20px 0;
font-size: 16px;
font-family: PingFangSC-Medium;
font-weight: 500;
}
.task-list-item,
.step-list-item {
box-sizing: border-box;
display: flex;
flex-direction: row;
padding-bottom: 16px;
}
.task {
padding-bottom: 14px;
border-bottom: 1px solid rgb(221, 221, 221);
.task-list-item {
justify-content: space-between;
.task-list-item-label {
color: rgb(181, 181, 181);
}
.task-list-item-status {
background-color: rgba(207, 215, 224);
border-radius: 2px;
padding: 0 5px;
color: rgb(255, 255, 255);
text-wrap: nowrap;
height: fit-content;
align-self: center;
}
}
.task-list-item-done {
.task-list-item-label {
color: rgb(51, 51, 51);
}
.task-list-item-status {
background-color: rgb(20, 122, 255);
}
}
}
.step-list-item {
justify-content: flex-start;
.step-list-item-index {
background: rgba(81, 94, 136, 0.04);
border: 1px solid #d2d6dc;
color: rgb(210, 214, 220);
display: inline-flex;
justify-content: center;
align-items: center;
width: 20px;
height: 20px;
border-radius: 50%;
font-size: 11.67px;
margin-right: 10px;
}
.step-list-item-label {
line-height: 22px;
color: #147aff;
}
}
}
.footer {
width: 100%;
margin-top: auto;
margin-bottom: 30px;
.footer-card-list {
box-sizing: border-box;
display: flex;
width: 100%;
.footer-card {
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 100%;
border: 1px solid #96c3ff;
border-radius: 4px;
background-image: url('../assets/image/adv-background.svg');
background-size: cover;
.footer-card-content {
padding: 10px;
font-size: 14px;
font-weight: 500;
line-height: 20px;
}
.footer-card-button {
margin-right: 10px;
padding: 1px 7px;
background: #147aff;
border-radius: 0.88rem;
box-shadow:
0 0.19rem 0.25rem 0 rgba(255, 255, 255, 0.7),
0 0.13rem 0.38rem 0 rgba(20, 122, 255, 0.55);
color: #fff;
}
}
}
}
.qr-box {
display: flex;
justify-content: center;
align-items: center;
.qr-code {
max-width: 150px;
max-height: 150px;
}
}
}
.menu-h5 {
flex: 1;
border-radius: 12px 12px 0 0;
margin-top: 200px;
height: calc(100% - 200px);
display: flex;
flex-direction: column;
overflow: hidden;
padding: 0;
.header-guide {
position: sticky;
padding: 15px 30px;
}
.main {
flex: 1;
overflow: auto;
padding: 0 30px;
}
.footer {
margin: 10px 0;
padding: 0 30px;
}
}
</style>

View File

@ -1,256 +0,0 @@
<template>
<div :class="['navbar', isH5 && 'navbar-h5']">
<div v-if="isPC" class="header">
<div class="user-info">
<Avatar useSkeletonAnimation :url="avatar" />
<div class="user-info-main">
<slot name="profile"></slot>
</div>
</div>
</div>
<div class="navbar-list">
<div
v-for="item in navBarListForShow"
:key="item.name"
:class="['navbar-list-item', currentSelectedNav === item.name && 'navbar-list-item-selected']"
@click="switchNavBar(item.name)"
>
<Icon
:file="(currentSelectedNav === item.name && item.selectedIcon) || (isPC && item.icon) || (!isPC && item.h5Icon)"
:width="isH5 ? '20px' : '24px'"
:height="isH5 ? '20px' : '24px'"
></Icon>
<div v-if="isH5" class="navbar-list-item-name">
{{ TUITranslateService.t(`Home.${item.label}`) }}
</div>
</div>
</div>
<div v-if="isPC" class="footer">
<div class="setting">
<Icon :file="settingPNG" @click="toggleSetting" @mousedown.stop></Icon>
<div v-if="isSettingShow" class="setting-more">
<slot name="setting"></slot>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, defineEmits, watch, withDefaults, defineProps } from '@/TUIKit/adapter-vue';
import { TUIStore, StoreName, TUITranslateService } from '@tencentcloud/chat-uikit-engine';
import Icon from '@/TUIKit/components/common/Icon.vue';
import Avatar from '@/TUIKit/components/common/Avatar/index.vue';
import messageWebSVG from '@/views/im/assets/icon/message.svg';
import messageH5SVG from '@/views/im/assets/icon/message-real.svg';
import messageSelectedSVG from '@/views/im/assets/icon/message-selected.svg';
import relationWebSVG from '@/views/im/assets/icon/relation.svg';
import relationH5SVG from '@/views/im/assets/icon/relation-real.svg';
import relationSelectedSVG from '@/views/im/assets/icon/relation-selected.svg';
import profileH5SVG from '@/views/im/assets/icon/profile.svg';
import profileSelectedSVG from '@/views/im/assets/icon/profile-selected.svg';
import settingPNG from '@/views/im/assets/icon/setting.png';
import { IUserProfile } from '@/TUIKit/interface';
import { isPC, isH5 } from '@/TUIKit/utils/env';
export interface INavBarItem {
icon: any;
h5Icon: any;
selectedIcon: any;
name: string;
label: string;
}
const props = withDefaults(
defineProps<{
currentNavBar: string;
isSettingShow: boolean;
}>(),
{
currentNavBar: () => 'message',
isSettingShow: false
}
);
const emits = defineEmits(['update:currentNavBar', 'update:isSettingShow']);
const currentSettingStatus = ref<boolean>(false);
const currentSelectedNav = ref(props.currentNavBar);
const navBarListForShow = computed<Array<INavBarItem>>(() => {
return isPC ? navBarList.filter((item: INavBarItem) => item.name !== 'profile') : navBarList;
});
const avatar = ref<string>('');
TUIStore.watch(StoreName.USER, {
userProfile: (userProfileData: IUserProfile) => {
avatar.value = userProfileData?.avatar || '';
}
});
const navBarList: Array<INavBarItem> = [
{
icon: messageWebSVG,
h5Icon: messageH5SVG,
selectedIcon: messageSelectedSVG,
name: 'message',
label: '消息'
},
{
icon: relationWebSVG,
h5Icon: relationH5SVG,
selectedIcon: relationSelectedSVG,
name: 'relation',
label: '通讯录'
},
{
icon: profileH5SVG,
h5Icon: profileH5SVG,
selectedIcon: profileSelectedSVG,
name: 'profile',
label: '个人中心'
}
];
function toggleSetting() {
currentSettingStatus.value = !currentSettingStatus.value;
emits('update:isSettingShow', currentSettingStatus.value);
}
function switchNavBar(name: string) {
currentSelectedNav.value = name;
emits('update:currentNavBar', name);
}
watch(
() => props.currentNavBar,
() => {
currentSelectedNav.value = props.currentNavBar;
},
{
immediate: true
}
);
watch(
() => props.isSettingShow,
() => {
currentSettingStatus.value = props.isSettingShow;
},
{
immediate: true
}
);
</script>
<style scoped lang="scss">
.navbar {
box-sizing: border-box;
width: 60px;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 56px 0 17px;
background: #e8e8e9;
user-select: none;
.navbar-list {
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
.navbar-list-item {
padding: 13px;
cursor: pointer;
}
.navbar-list-item-selected {
background: #ddd;
}
}
.header,
.footer {
display: flex;
width: 100%;
flex-direction: row;
justify-content: center;
align-items: center;
}
.header {
.user-info {
padding: 12px;
position: relative;
.avatar {
width: 36px;
height: 36px;
border-radius: 5px;
}
&:hover {
.user-info-main {
display: block;
}
}
.user-info-main {
width: 100%;
display: none;
position: absolute;
min-width: 165px;
max-width: 200px;
top: 0;
left: 100%;
z-index: 5;
padding: 14px 20px;
border-radius: 0 4px 4px 0;
background: #fff;
box-shadow: 0 1px 10px 0 rgba(2, 16, 43, 0.15);
}
}
}
.footer {
.setting {
cursor: pointer;
padding: 12px;
position: relative;
flex: 1;
.setting-more {
background: #fff;
box-shadow: 0 1px 10px 0 rgba(2, 16, 43, 0.15);
min-width: 11.25rem;
border-radius: 0 4px 4px 0;
position: absolute;
bottom: 10px;
left: 100%;
z-index: 9999;
white-space: nowrap;
}
}
}
}
.navbar-h5 {
padding: 0px;
flex-direction: row;
flex: 1;
box-shadow: 0 0 18px 0 #f0f6ff;
border-radius: 9px;
overflow: hidden;
.navbar-list {
flex-direction: row;
background: #ebf0f6;
justify-content: space-around;
.navbar-list-item {
flex: 1;
padding: 10px;
.navbar-list-item-name {
text-align: center;
padding-top: 4px;
font-size: 12px;
color: #a0a3a6;
}
}
.navbar-list-item-selected {
background-color: inherit;
.navbar-list-item-name {
color: #006eff;
}
}
}
}
</style>

View File

@ -1,423 +0,0 @@
<template>
<div :class="['TUI-profile', !isPC && 'TUI-profile-h5']">
<div v-if="displayType !== 'setting'" :class="['TUI-profile-basic', !isPC && 'TUI-profile-h5-basic']">
<img
:class="['TUI-profile-basic-avatar', !isPC && 'TUI-profile-h5-basic-avatar']"
:src="userProfile.avatar || 'https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png'"
/>
<div :class="['TUI-profile-basic-info', !isPC && 'TUI-profile-h5-basic-info']">
<div :class="['TUI-profile-basic-info-nick', !isPC && 'TUI-profile-h5-basic-info-nick']">
{{ userProfile.nick || '-' }}
</div>
<div :class="['TUI-profile-basic-info-id', !isPC && 'TUI-profile-h5-basic-info-id']">
<label :class="['TUI-profile-basic-info-id-label', !isPC && 'TUI-profile-h5-basic-info-id-label']"
>{{ TUITranslateService.t('Profile.用户ID') }}:</label
>
<div :class="['TUI-profile-basic-info-id-value', !isPC && 'TUI-profile-h5-basic-info-id-value']">
{{ userProfile.userID }}
</div>
</div>
</div>
</div>
<div
v-if="displayType !== 'profile' && (!isPC || (showSetting && !hideSetting))"
ref="settingDomRef"
:class="['TUI-profile-setting', !isPC && 'TUI-profile-h5-setting']"
@click.stop
>
<div
v-for="item in settingList"
:key="item.value"
:class="['TUI-profile-setting-item', !isPC && 'TUI-profile-h5-setting-item', item.value === 'exit' && 'TUI-profile-h5-setting-item-exit']"
>
<div :class="['TUI-profile-setting-item-label', !isPC && 'TUI-profile-h5-setting-item-label']" @click="handleSettingListItemOnClick(item)">
<div :class="['label-left']">
<div :class="['label-title']">
{{ TUITranslateService.t(`Profile.${item.label}`) }}
</div>
<div v-if="item.children && !isPC && item.childrenShowType === 'switch'" :class="['label-desc']">
{{ item.value }}
</div>
</div>
<div :class="['label-right']">
<div
v-if="!isPC && item.children && item.selectedChild && item.childrenShowType === 'bottomPopup'"
:class="['TUI-profile-setting-item-label-value', !isPC && 'TUI-profile-h5-setting-item-label-value']"
>
{{ TUITranslateService.t(`Profile.${item?.children[item.selectedChild]?.label}`) }}
</div>
<Icon v-if="item.children" :file="rightArrowIcon" width="14px" height="14px" />
</div>
</div>
<div v-if="item.children && isPC" :class="['TUI-profile-setting-item-children', !isPC && 'TUI-profile-h5-setting-item-children']">
<div
v-for="child in item.children"
:key="child.value"
:class="['TUI-profile-setting-item-children-item', !isPC && 'TUI-profile-h5-setting-item-children-item']"
@click="handleSettingListItemOnClick(child)"
>
<div :class="['TUI-profile-setting-item-children-item-label', !isPC && 'TUI-profile-h5-setting-item-children-item-label']">
{{ TUITranslateService.t(`Profile.${child.label}`) }}
</div>
<Icon v-if="item.selectedChild === child.value" :file="selectedIcon" width="14px" height="14px" />
</div>
</div>
<!-- <BottomPopup
v-if="item.children && !isPC && item.childrenShowType === 'bottomPopup'"
:show="item.showChildren"
@onClose="item.showChildren = false"
>
<div
v-for="child in item.children"
:key="child.value"
:class="['TUI-profile-setting-item-bottom-popup', !isPC && 'TUI-profile-h5-setting-item-bottom-popup']"
@click="handleSettingListItemOnClick(child)"
>
{{ TUITranslateService.t(`Profile.${child.label}`) }}
</div>
</BottomPopup>-->
</div>
</div>
<!-- <AboutDialog v-if="isAboutBoxShow" :userProfile="userProfile" @closeAboutBox="closeAboutBox" />
<EditProfileDialog v-if="isEditProfileBoxShow" @closeEditProfileBox="closeEditProfileBox" />-->
</div>
</template>
<script lang="ts" setup>
import { ref, watch, nextTick, onMounted } from '@/TUIKit/adapter-vue';
import TUIChatEngine, { TUITranslateService, TUIUserService, TUIStore, StoreName, TUIChatService } from '@tencentcloud/chat-uikit-engine';
import { TUILogin } from '@tencentcloud/tui-core';
import { Toast, TOAST_TYPE } from '@/TUIKit/components/common/Toast/index';
import BottomPopup from '@/TUIKit/components/common/BottomPopup/index.vue';
import Icon from '@/TUIKit/components/common/Icon.vue';
/*import AboutDialog from '../components/About.vue';
import EditProfileDialog from '../components/EditProfile.vue';*/
import rightArrowIcon from '@/TUIKit/assets/icon/right-icon.svg';
import selectedIcon from '@/TUIKit/assets/icon/selected.svg';
import { IUserProfile } from '@/TUIKit/interface';
import { isPC } from '@/TUIKit/utils/env';
import { deepCopy } from '@/TUIKit/components/TUIChat/utils/utils';
import { translator } from '@/TUIKit/components/TUIChat/utils/translation';
const props = defineProps({
displayType: {
type: String,
default: 'profile' // "profile"/"setting"/"all"
},
showSetting: {
type: Boolean,
default: false
}
});
const router = useRouter();
const emits = defineEmits(['update:showSetting']);
const settingDomRef = ref();
const userProfile = ref<IUserProfile>({});
const isAboutBoxShow = ref<boolean>(false);
const isEditProfileBoxShow = ref<boolean>(false);
const hideSetting = ref<boolean>(false);
const settingList = ref<{
[propsName: string]: {
value: string;
label: string;
onClick?: any;
// children related
selectedChild?: string;
childrenShowType?: string; // "bottomPopup"/"switch"
showChildren?: boolean;
children?: {
[propsName: string]: {
value: string;
label: string;
onClick?: any;
};
};
};
}>({
editProfile: {
value: 'editProfile',
label: '编辑资料',
onClick: () => {
hideSetting.value = true;
isEditProfileBoxShow.value = true;
}
},
allowType: {
value: 'allowType',
label: '加我为好友时',
selectedChild: '',
childrenShowType: 'bottomPopup',
showChildren: false,
onClick: (item: any) => {
if (!isPC) {
item.showChildren = true;
}
},
children: {
[TUIChatEngine.TYPES.ALLOW_TYPE_ALLOW_ANY]: {
value: TUIChatEngine.TYPES.ALLOW_TYPE_ALLOW_ANY,
label: '同意任何用户加好友',
onClick: (item: any) => {
switchAllowType(item.value);
}
},
[TUIChatEngine.TYPES.ALLOW_TYPE_NEED_CONFIRM]: {
value: TUIChatEngine.TYPES.ALLOW_TYPE_NEED_CONFIRM,
label: '需要验证',
onClick: (item: any) => {
switchAllowType(item.value);
}
},
[TUIChatEngine.TYPES.ALLOW_TYPE_DENY_ANY]: {
value: TUIChatEngine.TYPES.ALLOW_TYPE_DENY_ANY,
label: '拒绝任何人加好友',
onClick: (item: any) => {
switchAllowType(item.value);
}
}
}
},
displayMessageReadReceipt: {
value: 'displayMessageReadReceipt',
label: '消息阅读状态',
selectedChild: 'userLevelReadReceiptOpen',
childrenShowType: 'bottomPopup',
showChildren: false,
onClick(item: any) {
if (!isPC) {
item.showChildren = true;
}
},
children: {
userLevelReadReceiptOpen: {
value: 'userLevelReadReceiptOpen',
label: '开启',
onClick() {
switchEnableUserLevelReadReceipt(true);
}
},
userLevelReadReceiptClose: {
value: 'userLevelReadReceiptClose',
label: '关闭',
onClick() {
switchEnableUserLevelReadReceipt(false);
}
}
}
},
displayOnlineStatus: {
value: 'displayOnlineStatus',
label: '显示在线状态',
selectedChild: 'userLevelOnlineStatusOpen',
childrenShowType: 'bottomPopup',
showChildren: false,
onClick(item: any) {
if (!isPC) {
item.showChildren = true;
}
},
children: {
userLevelOnlineStatusOpen: {
value: 'userLevelOnlineStatusOpen',
label: '开启',
onClick() {
switchUserLevelOnlineStatus(true);
}
},
userLevelOnlineStatusClose: {
value: 'userLevelOnlineStatusClose',
label: '关闭',
onClick() {
switchUserLevelOnlineStatus(false);
}
}
}
},
translateLanguage: {
value: 'translateLanguage',
label: '翻译语言',
selectedChild: 'zh',
childrenShowType: 'bottomPopup',
showChildren: false,
onClick(item: any) {
if (!isPC) {
item.showChildren = true;
}
},
children: {
zh: {
value: 'zh',
label: 'zh',
onClick() {
switchTranslationTargetLanguage('zh');
}
},
en: {
value: 'en',
label: 'en',
onClick() {
switchTranslationTargetLanguage('en');
}
},
jp: {
value: 'jp',
label: 'jp',
onClick() {
switchTranslationTargetLanguage('jp');
}
},
kr: {
value: 'kr',
label: 'kr',
onClick() {
switchTranslationTargetLanguage('kr');
}
}
}
},
about: {
value: 'about',
label: '关于腾讯云IM',
selectedChild: '',
childrenShowType: 'bottomPopup',
showChildren: false,
children: {},
onClick: () => {
hideSetting.value = true;
isAboutBoxShow.value = true;
}
},
exit: {
value: 'exit',
label: '退出登录',
onClick: () => {
TUILogin.logout().then(() => {
router.push({ path: '/' });
});
}
}
});
const handleSettingListItemOnClick = (item: any) => {
if (item?.onClick && typeof item?.onClick === 'function') {
item.onClick(item);
}
};
const closeAboutBox = () => {
isAboutBoxShow.value = false;
emits('update:showSetting', false);
};
const closeEditProfileBox = () => {
isEditProfileBoxShow.value = false;
emits('update:showSetting', false);
};
const updateMyProfile = (props: object) => {
TUIUserService.updateMyProfile(props)
.then(() => {
Toast({
message: '更新用户资料成功',
type: TOAST_TYPE.SUCCESS
});
})
.catch((err: any) => {
console.warn('更新用户资料失败', err);
Toast({
message: '更新用户资料失败',
type: TOAST_TYPE.ERROR
});
});
};
TUIStore.watch(StoreName.USER, {
userProfile: (userProfileData: IUserProfile) => {
userProfile.value = deepCopy(userProfileData);
if (userProfile?.value?.allowType) {
settingList.value.allowType.selectedChild = userProfile?.value?.allowType;
}
},
displayMessageReadReceipt(isDisplay: boolean) {
settingList.value.displayMessageReadReceipt.selectedChild = isDisplay ? 'userLevelReadReceiptOpen' : 'userLevelReadReceiptClose';
},
displayOnlineStatus(isOnlineStatusDisplay: boolean) {
settingList.value.displayOnlineStatus.selectedChild = isOnlineStatusDisplay ? 'userLevelOnlineStatusOpen' : 'userLevelOnlineStatusClose';
}
});
// pc click outside
let clickOutside = false;
let clickInner = false;
const onClickOutside = (component: any) => {
document.addEventListener('mousedown', onClickDocument);
component?.addEventListener && component?.addEventListener('mousedown', onClickTarget);
};
const onClickDocument = () => {
clickOutside = true;
if (!clickInner && clickOutside) {
emits('update:showSetting', false);
removeClickListener(settingDomRef.value);
}
clickOutside = false;
clickInner = false;
};
const onClickTarget = () => {
clickInner = true;
};
const removeClickListener = (component: any) => {
document.removeEventListener('mousedown', onClickDocument);
component?.removeEventListener && component?.removeEventListener('mousedown', onClickTarget);
};
watch(
() => props.showSetting,
(newVal: any, oldVal: any) => {
if (isPC && newVal && !oldVal) {
nextTick(() => {
onClickOutside(settingDomRef.value);
});
}
},
{
immediate: true
}
);
onMounted(() => {
// get user profile
TUIUserService.getUserProfile().then((res: any) => {
userProfile.value = res.data;
});
// get current target language when component mounted
const lang = TUIStore.getData(StoreName.USER, 'targetLanguage');
if (lang) {
settingList.value.translateLanguage.selectedChild = lang;
}
});
function switchAllowType(value: string) {
updateMyProfile({ allowType: value });
settingList.value.allowType.showChildren = false;
}
function switchEnableUserLevelReadReceipt(status: boolean) {
TUIStore.update(StoreName.USER, 'displayMessageReadReceipt', status);
settingList.value.displayMessageReadReceipt.showChildren = false;
}
function switchUserLevelOnlineStatus(status: boolean) {
TUIUserService.switchUserStatus({ displayOnlineStatus: status });
settingList.value.displayOnlineStatus.showChildren = false;
}
function switchTranslationTargetLanguage(lang: string) {
translator.clear();
TUIChatService.setTranslationLanguage(lang);
settingList.value.translateLanguage.selectedChild = lang;
settingList.value.translateLanguage.showChildren = false;
}
</script>
<style lang="scss" scoped>
@import '../styles/profile';
</style>

View File

@ -1,188 +0,0 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div :id="isPC ? 'preloadedImages' : ''" :class="['home', isH5 && 'home-h5']">
<!-- <div v-show="isMenuShow" class="home-menu">
<Menu @closeMenu="toggleMenu(false)" />
</div>-->
<div :class="['home-container', isMenuShow && 'menu-expand']">
<!-- <div v-if="isPC" class="home-header">
<Header
:class="[isMenuShow && 'header-menu-show']"
showType="menu"
:defaultLanguage="locale"
@toggleMenu="toggleMenu(!isMenuShow)"
@changeLanguage="changeLanguage"
/>
</div>-->
<div class="home-main">
<div class="home-TUIKit">
<div v-if="isPC || !currentConversationID" class="home-TUIKit-navbar">
<NavBar v-model:currentNavBar="currentNavBar" v-model:isSettingShow="isSettingShow">
<template #profile>
<Profile display-type="profile" />
</template>
<template #setting>
<Profile v-model:showSetting="isSettingShow" display-type="setting" />
</template>
</NavBar>
</div>
<div v-if="isPC" class="home-TUIKit-main">
<div v-show="currentNavBar === 'message'" class="home-TUIKit-main">
<div class="home-conversation">
<TUISearch searchType="global" />
<TUIConversation />
</div>
<div class="home-chat">
<TUIChat>
<ChatDefaultContent />
</TUIChat>
<TUIGroup class="chat-aside" />
<TUISearch class="chat-aside" searchType="conversation" />
</div>
<TUIContact display-type="selectFriend" />
</div>
<div v-show="currentNavBar === 'relation'" class="home-TUIKit-main">
<TUIContact display-type="contactList" @switchConversation="currentNavBar = 'message'" />
</div>
</div>
<div v-else-if="isH5" class="home-TUIKit-main">
<div v-if="!currentConversationID" class="home-TUIKit-main">
<div v-show="currentNavBar === 'message'" class="home-TUIKit-main">
<TUISearch searchType="global" />
<TUIConversation />
<TUIContact display-type="selectFriend" />
</div>
<div v-show="currentNavBar === 'relation'" class="home-TUIKit-main">
<TUIContact display-type="contactList" @switchConversation="currentNavBar = 'message'" />
</div>
<div v-show="currentNavBar === 'profile'" class="home-TUIKit-main">
<Profile display-type="all" />
</div>
</div>
<TUIChat v-else />
<TUIGroup class="chat-popup" />
<TUISearch class="chat-popup" searchType="conversation" />
</div>
<Drag ref="dragRef" :show="isCalling" domClassName="callkit-drag-container">
<TUICallKit
:class="['callkit-drag-container', `callkit-drag-container-${isMinimized ? 'mini' : isH5 ? 'h5' : 'pc'}`]"
:allowedMinimized="true"
:allowedFullScreen="false"
:beforeCalling="beforeCalling"
:afterCalling="afterCalling"
:onMinimized="onMinimized"
/>
</Drag>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from '@/TUIKit/adapter-vue';
import { SDKAppID, secretKey, userSig } from '@/main';
import { TUILogin } from '@tencentcloud/tui-core';
import { TUIStore, StoreName, TUIUserService } from '@tencentcloud/chat-uikit-engine';
import { TUICallKit } from '@tencentcloud/call-uikit-vue';
import { TUIChat, TUIConversation, TUIContact, TUIGroup, TUISearch, genTestUserSig } from '@/TUIKit';
import Header from '@/views/im/components/Header.vue';
import Menu from '@/views/im/components/Menu.vue';
import NavBar from '@/views/im/components/NavBar.vue';
import Profile from '@/views/im/components/Profile.vue';
import ChatDefaultContent from '@/views/im/components/ChatDefaultContent.vue';
import Drag from '@/TUIKit/components/common/Drag';
import { isPC, isH5 } from '@/TUIKit/utils/env';
import { enableSampleTaskStatus } from '@/TUIKit/utils/enableSampleTaskStatus';
const props = withDefaults(
defineProps<{
language: string;
}>(),
{
language: 'zh'
}
);
const emits = defineEmits(['changeLanguage']);
const locale = ref<string>(props.language);
const isMenuShow = ref<boolean>(true);
const currentNavBar = ref<string>('message');
const currentConversationID = ref<string>('');
const isCalling = ref<boolean>(false);
const isMinimized = ref<boolean>(false);
const dragRef = ref<typeof Drag>();
const isSettingShow = ref<boolean>(false);
function changeLanguage(language: string) {
emits('changeLanguage', language);
}
TUIStore.watch(StoreName.CONV, {
currentConversationID: (id: string) => {
currentConversationID.value = id;
}
});
function toggleMenu(value: boolean) {
isMenuShow.value = value;
}
function beforeCalling() {
isCalling.value = true;
isMinimized.value = false;
enableSampleTaskStatus('call');
}
function afterCalling() {
isCalling.value = false;
isMinimized.value = false;
}
function onMinimized(oldMinimizedStatus: boolean, newMinimizedStatus: boolean) {
isMinimized.value = newMinimizedStatus;
dragRef?.value?.positionReset();
}
function genUser() {
const options = genTestUserSig({
SDKAppID,
secretKey,
userID: 'youyouliangshao'
});
const loginInfo: any = {
SDKAppID,
// userID: ruleForm.value.userID,
userID: 'youyouliangshao',
userSig: userSig,
useUploadPlugin: true,
framework: `vue3`
};
imLogin(loginInfo);
}
function imLogin(loginInfo) {
TUILogin.login(loginInfo)
.then((res: any) => {
// router.push({ path: 'home' });
// TUIUserService.switchUserStatus({ displayOnlineStatus: true });
})
.catch((error: any) => {
ElMessage({
message: '登录失败',
grouping: true,
type: 'error'
});
});
}
onMounted(() => {
/* TUILogin.logout().then(() => {
});*/
genUser();
});
</script>
<style lang="scss">
@import './styles/home';
</style>

View File

@ -1,115 +0,0 @@
@import "@/TUIKit/assets/styles/common.scss";
// button
@mixin btn {
border-radius: 5px;
padding: 13px 0;
cursor: pointer;
}
@mixin btn-default {
@include btn;
background: #006eff;
border: 1px solid #006eff;
color: #fff;
}
@mixin btn-error {
@include btn;
border: 1px solid #e54545;
color: #e54545;
background: #fff;
}
@mixin btn-normal {
@include btn;
background: #fff;
border: 1px solid #ddd;
color: #000;
}
// flex
// flex布局 默认 纵向垂直居中水平居中
@mixin flex($direction: column, $js: center, $al: center) {
box-sizing: border-box;
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
flex-direction: $direction;
justify-content: $js;
align-items: $al;
border: 0px solid black;
margin: 0;
padding: 0;
min-width: 0;
}
// 文本超出隐藏 ...隐藏文本
@mixin single-line-ellipsis($width: 100%) {
width: $width;
overflow: hidden;
-ms-text-overflow: ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
// 文本最多(n)超出部分用...表示
@mixin line($num) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: $num;
-webkit-box-orient: vertical;
}
// position居中
@mixin positionCenter {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.container {
@include flex;
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
z-index: 3;
background: rgba(0, 0, 0, 0.3);
overflow: hidden;
.box {
@include flex;
border-radius: 0.5rem;
background: #fff;
overflow: hidden;
color: #000;
}
.box-h5 {
width: 100%;
height: 100%;
padding: 0px;
border-radius: 0px;
.title {
@include flex;
box-sizing: border-box;
width: 100%;
padding: 15px 18px;
position: relative;
.title-back {
position: absolute;
left: 18px;
}
.title-name {
font-size: 18px;
font-weight: 500;
font-family: PingFangSC-Medium;
}
}
}
}

View File

@ -1,63 +0,0 @@
/* stylelint-disable */
.home-h5 {
flex-direction: column;
min-width: 100%;
min-height: 100%;
background: #fff;
.home-menu {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 10;
align-items: flex-end;
}
.home-container {
.home-main {
padding: 0;
min-width: 0;
.home-TUIKit {
flex-direction: column-reverse;
border-radius: 0;
max-width: 100%;
.home-TUIKit-navbar {
width: 100%;
padding: 12px 18px;
}
.home-TUIKit-main {
flex: 1;
display: flex;
flex-direction: column;
.chat-popup {
position: absolute;
}
}
.callkit-drag-container {
&-h5 {
width: 100%;
height: 100%;
left: 0;
top: 0;
border-radius: 0;
box-shadow: none;
}
&-mini {
width: 72px;
height: 72px;
left: calc(100% - 100px);
top: 20px;
background-color: transparent;
}
}
}
}
}
}

View File

@ -1,154 +0,0 @@
@import "../common.scss";
.login-h5 {
min-width: 100%;
max-width: 100%;
padding: 17px 0;
.login-header {
padding: 0 23px;
}
.login-main {
.login-main-content {
padding: 0 23px;
background: url("../assets/image/h5/login-bg.png") no-repeat;
background-size: 65%;
background-position-x: right;
align-items: flex-start;
.login-form {
flex: 1;
.login-title {
flex-direction: column;
padding: 60px 0 18px;
p {
padding-left: 0;
font-size: 27px;
line-height: 40px;
}
}
.login-form-item {
font-size: 18px;
.el-checkbox {
.checked-text {
font-size: 14px;
}
}
.login-form-item-disabled {
font-size: 18px;
padding: 20px;
}
}
.login-btn {
button {
height: auto !important;
font-size: 20px;
line-height: 27px;
padding: 13px 0;
}
}
}
}
}
.login-footer {
background: none;
padding: 10px 10px;
&-list {
flex: 1;
display: flex;
&-item {
flex: 1;
display: flex;
background: url("../assets/image/h5/adv-more.svg") no-repeat;
background-size: 100% 100%;
border: solid #96c3ff 1px;
&:last-child {
background: url("../assets/image/h5/adv-im.svg") no-repeat;
background-size: 100% 100%;
}
a {
flex: 1;
display: flex;
justify-content: space-around;
align-items: center;
box-sizing: border-box;
padding: 20px;
span {
padding: 5px 20px;
background: #147aff;
box-shadow: 0 4px 5px 0 rgba(255, 255, 255, 0.7), 0 3px 8px 0 rgba(20, 122, 255, 0.55);
border-radius: 30.5px;
display: flex;
align-items: center;
justify-content: center;
font-family: PingFangSC-Regular;
font-weight: 400;
font-size: 15px;
color: #ffffff;
letter-spacing: 0;
}
aside {
display: flex;
flex-direction: column;
h1 {
font-family: PingFangSC-Regular;
font-size: 16px;
color: #000000;
letter-spacing: 0;
}
.sub {
align-self: flex-end;
}
}
}
}
&-bottom {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.text-header {
display: flex;
align-items: center;
span {
padding: 20px 20px;
width: 84px;
font-family: "PingFang SC";
font-style: normal;
font-weight: 400;
color: #bbbbbb;
}
}
i {
width: 120px;
height: 1px;
background: #dbdbdb;
}
&-image {
display: flex;
.platform {
width: 41px;
height: 41px;
padding: 0 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
}

View File

@ -1,94 +0,0 @@
.TUI-profile-h5 {
background: #efefef;
flex: 1;
display: flex;
flex-direction: column;
width: 100%;
&-basic {
width: 100%;
box-sizing: border-box;
background: #ffffff;
padding: 14px 18px;
flex-direction: row;
align-items: flex-start;
margin-bottom: 10px;
&-avatar {
width: 78px;
height: 78px;
border-radius: 8px;
}
&-info {
&-nick {
font-size: 14px;
flex: 1;
word-break: keep-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 6px 0;
font-family: PingFangSC-Medium;
font-weight: 500;
color: #000;
letter-spacing: 0;
}
&-id {
font-family: PingFangSC-Regular;
font-weight: 400;
color: #999;
letter-spacing: 0;
font-size: 14px;
word-break: keep-all;
padding: 6px 0;
&-label {
}
&-value {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
&-setting {
width: 100%;
flex-direction: column;
&-item {
margin-bottom: 10px;
background: #ffffff;
padding: 10px;
&-exit {
.TUI-profile-h5-setting-item-label {
justify-content: center;
.label-left {
.label-title {
color: red;
}
}
}
}
&-label {
.label-left {
display: flex;
flex-direction: column;
.label-title {
color: #444444;
font-size: 14px;
}
}
.label-right {
color: #000000;
font-size: 14px;
display: flex;
flex-direction: row;
}
}
&-bottom-popup {
font-size: 16px;
color: #147aff;
padding: 10px;
border-bottom: 1px solid #DBDBDB;
}
}
}
}

View File

@ -1,3 +0,0 @@
@import './web/home.scss';
@import './h5/home.scss';
@import "./common.scss";

View File

@ -1,3 +0,0 @@
@import "./web/login.scss";
@import "./h5/login.scss";
@import "./common.scss";

View File

@ -1,3 +0,0 @@
@import "./web/profile.scss";
@import "./h5/profile.scss";
@import "./common.scss";

View File

@ -1,121 +0,0 @@
#preloadedImages {
background: linear-gradient(135deg, #f1f4f7 0%, #edf5ff 100%) no-repeat;
background-size: cover;
background-image: url("https://web.sdk.qcloud.com/im/assets/images/background-zip.png");
}
.home {
box-sizing: border-box;
flex: 1;
display: flex;
flex-direction: row;
min-width: 1024px;
background-size: contain;
width: 100%;
height: 100%;
overflow: hidden;
.home-menu {
box-sizing: border-box;
display: flex;
}
.home-container {
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
overflow: hidden;
align-items: stretch;
.home-header {
box-sizing: border-box;
overflow: hidden;
.header-menu-show {
padding-left: 0px;
}
}
.home-main {
box-sizing: border-box;
flex: 1;
display: flex;
justify-content: center;
overflow: hidden;
padding: 50px;
min-width: 968px;
.home-TUIKit {
box-sizing: border-box;
display: flex;
flex: 1;
width: 100%;
height: 100%;
max-width: 1400px;
overflow: hidden;
min-height: 640px;
border-radius: 12px;
background-color: #ffffff;
box-shadow: 0 11px 20px 0 rgba(0, 0, 0, 0.3);
.home-TUIKit-navbar {
box-sizing: border-box;
display: flex;
}
.home-TUIKit-main {
box-sizing: border-box;
flex: 1;
display: flex;
overflow: hidden;
flex-direction: row;
border: 0 solid black;
.home-conversation,
.home-relation {
min-width: 285px;
box-sizing: border-box;
flex: 0 0 24%;
display: flex;
flex-direction: column;
border-right: 1px solid #f4f5f9;
}
.home-chat {
box-sizing: border-box;
min-width: 0;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
}
.callkit-drag-container {
position: fixed;
z-index: 100;
background-color: #ffffff;
user-select: none;
&-pc {
left: calc(50% - 25rem);
top: calc(50% - 18rem);
width: 50rem;
height: 36rem;
border-radius: 16px;
box-shadow: rgba(0, 0, 0, 0.16) 0px 3px 6px, rgba(0, 0, 0, 0.23) 0px 3px 6px;
}
&-mini {
width: 168px;
height: 56px;
right: 10px;
top: 70px;
background-color: transparent;
border-radius: 0px;
box-shadow: none;
}
}
}
}
}
.home-container.menu-expand {
.dialog,
.container {
width: calc(100% - 300px) !important;
left: 300px !important;
}
.home-main .home-TUIKit .callkit-drag-container.callkit-drag-container-pc {
left: calc(50% - 25rem + 150px);
}
}
}

View File

@ -1,237 +0,0 @@
@import "../common.scss";
.login {
flex: 1;
@include flex(column, center, stretch);
min-width: 980px;
width: 100%;
height: 100%;
background: #ffffff;
.login-main {
flex: 1;
@include flex(column, center, stretch);
padding-bottom: 5vw;
.login-main-content {
flex: 1;
@include flex(row, space-between, center);
padding: 0 6vh;
width: 100%;
max-width: 100rem;
align-self: center;
background: url("../assets/image/login-background.png") no-repeat;
background-position: center left;
.login-main-adv {
@include flex(column, flex-start, flex-start);
.login-main-adv-introduce {
font-size: 3rem;
line-height: 4.2rem;
font-family: PingFangSC-Regular;
font-weight: 400;
color: #000000;
}
}
.login-sale {
margin-top: 40px;
padding: 8px 16px;
font-size: 1.4rem;
line-height: 2rem;
border-radius: 6px;
display: flex;
align-items: center;
cursor: pointer;
color: #ffffff;
background: url("../assets/image/adv-bg.svg") no-repeat;
background-size: cover;
background-position: center;
.icon {
margin: 0 8px;
}
}
.small-txt {
width: 42rem;
font-size: 2.6rem;
line-height: 3.6rem;
}
.checked-text {
display: flex;
flex-wrap: wrap;
font-size: 0.88rem;
line-height: 1.73rem;
font-family: PingFangSC-Regular;
font-weight: 400;
color: #bbbbbb;
letter-spacing: 0;
a {
color: #006ef0;
}
}
.login-form {
box-sizing: border-box;
width: 22.41rem;
.login-title {
display: flex;
letter-spacing: 0;
font-family: PingFangSC-Medium;
font-weight: 500;
color: #000000;
img {
width: 4.61rem;
height: 3.23rem;
}
p {
padding-left: 10.5px;
font-size: 1.8rem;
line-height: 2.7rem;
align-items: center;
display: flex;
}
}
.login-form-item {
margin: 18px 0;
.el-select {
width: 100%;
font-size: 1rem;
padding-top: 28px;
line-height: 1.73rem;
font-weight: 400;
color: #000000;
}
.el-input__inner {
width: 356.4px;
height: 54px;
margin-top: 12px;
border-radius: 4.8px;
background: #ffffff;
border: 1.2px solid #dddddd;
}
.input-with-select {
margin-top: 14px;
input {
height: 40px;
}
}
.el-input-group__append {
.code-box {
color: #006eff;
}
}
.login-form-item-disabled {
cursor: pointer;
background: #f4f5f9;
border: 1.2px solid #dddddd;
color: #111111;
letter-spacing: 0;
border-radius: 4.8px;
width: 100%;
margin-top: 28px;
padding: 14px 11px;
box-sizing: border-box;
font-size: 1rem;
line-height: 1.2rem;
label {
cursor: pointer;
color: #999999;
padding-right: 16px;
}
}
}
.login-form-footer {
display: flex;
flex-direction: row;
justify-content: space-between;
text-decoration: none;
a {
color: #006ef0;
}
}
.login-btn {
flex: 1;
@include flex(column, center, stretch);
.btn {
width: 100%;
flex: 1;
height: 3rem;
font-size: 1.25rem;
font-weight: 400;
letter-spacing: 0;
border: 1px solid #006eff;
border-radius: 5px;
color: #006eff;
margin-bottom: 10px;
background-color: transparent;
cursor: pointer;
&:disabled {
opacity: 0.3;
}
&-primary {
background: #006eff;
color: #ffffff;
}
}
}
}
}
.login-main-middle {
height: 130px;
width: 100%;
max-width: 100rem;
align-self: center;
padding: 0 1.6rem 20px;
box-sizing: border-box;
display: flex;
.login-main-middle-box {
flex: 1;
display: flex;
}
}
.login-main-footer {
box-sizing: border-box;
padding: 0 1.6rem;
width: 100%;
max-width: 100rem;
display: flex;
align-items: center;
align-self: center;
background: rgba(231, 242, 255, 0.4);
.mask {
flex: 0 0 25%;
padding: 1.6rem 0;
display: flex;
flex-direction: column;
align-items: center;
.mask-top {
word-break: break-all;
white-space: nowrap;
font-size: 3rem;
height: 4.19rem;
font-family: PingFangSC-Regular;
font-weight: 400;
color: #006eff;
letter-spacing: 0;
}
.mask-under {
opacity: 0.49;
font-weight: 400;
font-size: 1.2rem;
font-family: PingFangSC-Regular;
color: #000;
letter-spacing: 0;
height: 62px;
text-align: center;
}
}
}
}
}

View File

@ -1,124 +0,0 @@
/* stylelint-disable-next-line selector-class-pattern */
.TUI-profile {
background: #fff;
display: flex;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
&-basic {
display: flex;
flex-direction: row;
box-sizing: border-box;
overflow: hidden;
&-avatar {
width: 30px;
height: 30px;
border-radius: 5px;
margin-right: 10px;
}
&-info {
flex: 1;
display: flex;
flex-direction: column;
box-sizing: border-box;
overflow: hidden;
font-size: 14px;
&-nick {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&-id {
display: flex;
flex-direction: row;
overflow: hidden;
&-label {
font-weight: 400;
color: #999;
}
&-value {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
&-setting {
&-item {
height: 40px;
padding-left: 14px;
padding-right: 8px;
display: flex;
line-height: 40px;
text-align: center;
align-items: center;
justify-content: space-between;
cursor: pointer;
&:hover {
background-color: rgba(0, 110, 255, 0.1);
/* stylelint-disable-next-line selector-class-pattern */
.TUI-profile-setting-item-children {
display: block;
}
}
&-label {
font-size: 14px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
flex: 1;
}
/* stylelint-disable-next-line no-descending-specificity */
&-children {
display: none;
position: absolute;
left: 100%;
min-width: 167px;
border-radius: 0 4px 4px 0;
z-index: 2;
background: #fff;
box-shadow: 2px 1px 6px 0 rgba(2, 16, 43, 0.15);
&-item {
height: 40px;
padding-left: 14px;
padding-right: 8px;
display: flex;
line-height: 40px;
text-align: center;
align-items: center;
justify-content: space-between;
cursor: pointer;
&:hover {
background-color: rgba(0, 110, 255, 0.1);
}
&-label {
font-size: 14px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
flex: 1;
padding-right: 5px;
}
}
}
}
}
}