fix: 修改bug

This commit is contained in:
100011797 2023-07-06 14:03:34 +08:00
parent 7f75c05f79
commit 8fc0d9f6d4
13 changed files with 274 additions and 197 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 B

After

Width:  |  Height:  |  Size: 898 B

View File

@ -23,12 +23,13 @@
@refresh="onRefresh(item.key)" @refresh="onRefresh(item.key)"
/> />
</template> </template>
<div v-if="list.length < 12" style="color: #666666; text-align: center; padding: 8px;">这是最后一条数据了</div>
</j-scrollbar> </j-scrollbar>
<div class="no-data" v-else> <div class="no-data" v-else>
<j-empty /> <j-empty />
</div> </div>
<div class="btns"> <div class="btns">
<span @click="onMore(item.key)">查看更多</span> <j-button type="link" @click="onMore(item.key)">查看更多</j-button>
</div> </div>
</div> </div>
</j-spin> </j-spin>
@ -192,17 +193,8 @@ const onMore = (key: string) => {
.btns { .btns {
display: flex; display: flex;
height: 46px; height: 46px;
line-height: 46px; justify-content: center;
span { align-items: center;
display: block;
width: 100%;
text-align: center;
cursor: pointer;
// &:first-child {
// border-right: 1px solid #f0f0f0;
// }
}
} }
} }
} }

View File

@ -1,32 +1,50 @@
<template> <template>
<div class="list-items"> <div class="list-items">
<div <div class="list-box">
class="list-item" <div
@click="onMove" class="list-item"
:style="{ @click="onMove"
transform: `translate(${num}px, 0)`, :style="{
}" transform: `translate(${num}px, 0)`,
> }"
<div class="list-item-left"> >
<div class="header"> <div class="list-item-left">
<div class="title"> <div class="header">
<div>{{ props.data?.topicName }}</div> <div class="title">
<span :style="{color: state === 'unread' ? 'red' : '#AAAAAA'}">{{ state === 'unread' ? '未读' : '已读' }}</span> <span>{{ props.data?.topicName }}</span>
<span style="margin-left: 5px">
{{
dayjs(props.data?.notifyTime).format(
'YYYY-MM-DD HH:mm:ss',
)
}}
</span>
</div>
<div :class="[state === 'unread' ? 'unread' : 'read']">
{{ state === 'unread' ? '未读' : '已读' }}
</div>
</div> </div>
<div class="time"> <div class="message">
{{ <j-ellipsis :lineClamp="2">{{ props.data?.message }}</j-ellipsis>
dayjs(props.data?.notifyTime).format(
'YYYY-MM-DD HH:mm:ss',
)
}}
</div> </div>
</div> </div>
<div class="message">{{ props.data?.message }}</div> <div class="list-item-right">
</div> <j-button
<div class="list-item-right"> size="small"
<j-button @click.stop="detail">查看详情</j-button> @click.stop="detail"
<j-button v-if="state === 'unread'" @click.stop="read('_read')">标为已读</j-button> style="margin-bottom: 5px"
<j-button v-else @click.stop="read('_unread')">标为未读</j-button> >查看详情</j-button
>
<j-button
size="small"
v-if="state === 'unread'"
@click.stop="read('_read')"
>标为已读</j-button
>
<j-button size="small" v-else @click.stop="read('_unread')"
>标为未读</j-button
>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -55,11 +73,11 @@ const props = defineProps({
const num = ref<-100 | 0>(0); const num = ref<-100 | 0>(0);
const state = ref(props.data.state?.value) const state = ref(props.data.state?.value);
watchEffect(() => { watchEffect(() => {
state.value = props.data.state?.value state.value = props.data.state?.value;
}) });
const onMove = () => { const onMove = () => {
num.value = num.value === 0 ? -100 : 0; num.value = num.value === 0 ? -100 : 0;
@ -82,15 +100,15 @@ const detail = () => {
const read = (type: '_read' | '_unread') => { const read = (type: '_read' | '_unread') => {
changeStatus_api(type, [props.data.id]).then((resp: any) => { changeStatus_api(type, [props.data.id]).then((resp: any) => {
if (resp.status === 200) { if (resp.status === 200) {
if(type === '_read') { if (type === '_read') {
userInfo.alarmUpdateCount -= 1; userInfo.alarmUpdateCount -= 1;
} else { } else {
userInfo.alarmUpdateCount += 1; userInfo.alarmUpdateCount += 1;
} }
num.value = 0; num.value = 0;
state.value = type === '_read' ? 'read' : 'unread' state.value = type === '_read' ? 'read' : 'unread';
onlyMessage('操作成功!'); onlyMessage('操作成功!');
emits('refresh') emits('refresh');
} }
}); });
}; };
@ -98,63 +116,72 @@ const read = (type: '_read' | '_unread') => {
<style lang="less" scoped> <style lang="less" scoped>
.list-items { .list-items {
width: 312px; width: 100%;
overflow: hidden;
height: 80px;
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid #f0f0f0;
margin: 0 24px; padding: 0 16px;
box-sizing: content-box;
&:hover {
background-color: #f9faff;
}
}
.list-box {
overflow: hidden;
width: 100%;
} }
.list-item { .list-item {
list-style: none; list-style: none;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
width: 412px; width: calc(100% + 124px);
transition: all 0.3s; transition: all 0.3s;
gap: 24px;
.list-item-left { .list-item-left {
padding: 12px 0; padding: 12px 0;
width: 312px; margin-right: 16px;
height: 80px; width: calc(100% - 124px);
.header { .header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-bottom: 10px;
.title { .title {
display: flex; display: flex;
align-items: center; align-items: center;
div { color: #333333;
color: rgba(0, 0, 0, 0.85);
font-size: 14px;
font-weight: bold;
margin-right: 10px;
}
span {
color: red;
font-size: 13px;
}
} }
.time {
.unread {
color: #666666;
width: 40px;
height: 22px;
text-align: center;
font-size: 12px; font-size: 12px;
color: rgba(0, 0, 0, 0.45); background-color: #f2f3f5;
line-height: 22px;
}
.read {
color: @primary-color;
width: 40px;
height: 22px;
text-align: center;
line-height: 22px;
font-size: 12px;
background-color: #f1f4ff;
} }
} }
.message { .message {
font-size: 12px; color: #666666;
} }
} }
.list-item-right { .list-item-right {
width: 100px; width: 84px;
padding: 6px 12px 6px 0; padding: 5px 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: center;
} }
} }
</style> </style>

View File

@ -6,34 +6,24 @@
<!-- 已登录-绑定三方账号 --> <!-- 已登录-绑定三方账号 -->
<template v-if='!!token'> <template v-if='!!token'>
<div class='info'> <div class='info'>
<j-card style='width: 280px'> <div class='info-body'>
<template #title> <j-avatar
<div class='info-head'> :size="86"
<img :src="getImage('/bind/Rectangle.png')" /> style="margin-bottom: 16px;"
<span>个人信息</span>
</div>
</template>
<div class='info-body'>
<img
:src=" :src="
user?.avatar || user?.avatar ||
getImage('/bind/jetlinksLogo.png') getImage('/bind/jetlinksLogo.png')
" "
/> />
<p>账号{{ user?.username }}</p> <div class="info-body-item"><span>账号</span><j-ellipsis :lineClamp="2">{{ user?.username || '-' }}</j-ellipsis></div>
<p>用户名{{ user?.name }}</p> <div class="info-body-item"><span>用户名</span><j-ellipsis :lineClamp="2">{{ user?.name || "-" }}</j-ellipsis></div>
</div> </div>
</j-card>
<img :src="getImage('/bind/Vector.png')" /> <img :src="getImage('/bind/Vector.png')" />
<j-card style='width: 280px'> <div class='info-body'>
<template #title> <j-avatar
<div class='info-head'> :size="86"
<img :src="getImage('/bind/Rectangle.png')" /> shape="square"
<span>三方账户信息</span> style="margin-bottom: 16px;"
</div>
</template>
<div class='info-body'>
<img
:src=" :src="
bindUser?.avatar || bindUser?.avatar ||
iconMap.get( iconMap.get(
@ -41,10 +31,9 @@
) || getImage('/apply/internal-standalone.png') ) || getImage('/apply/internal-standalone.png')
" "
/> />
<p>账号{{ bindUser?.result?.userId || '-' }}</p> <div class="info-body-item"><span>账号</span><j-ellipsis :lineClamp="2">{{ bindUser?.result?.userId || '' }}</j-ellipsis></div>
<p>用户名{{ bindUser?.result?.name || '-' }}</p> <div class="info-body-item"><span>用户名</span><j-ellipsis :lineClamp="2">{{ bindUser?.result?.name || '' }}</j-ellipsis></div>
</div> </div>
</j-card>
</div> </div>
<div class='btn'> <div class='btn'>
<j-button type='primary' @click='handleBind' <j-button type='primary' @click='handleBind'
@ -331,17 +320,17 @@ getDetail()
.content { .content {
box-sizing: border-box; box-sizing: border-box;
width: 850px; width: 928px;
min-height: 510px; min-height: 510px;
background: #fff; background: #fff;
border: 1px solid #e0e4e8; border-radius: 22px;
border-radius: 2px; padding: 40px;
.title { .title {
margin: 30px 0; margin-bottom: 30px;
color: #0f1222; color: #333333;
font-weight: 400; font-weight: 400;
font-size: 20px; font-size: 22px;
font-family: 'PingFang SC'; font-family: 'PingFang SC';
font-style: normal; font-style: normal;
line-height: 25px; line-height: 25px;
@ -352,24 +341,28 @@ getDetail()
.info { .info {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-between;
gap: 20px; padding: 86px 0;
&-head { img {
display: flex; width: 69px;
align-items: baseline;
gap: 10px;
} }
&-body { &-body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 10px; gap: 8px;
width: 317px;
img { &-item {
width: 70px; display: flex;
height: 70px; color: #333333;
span {
color: #666666;
white-space: nowrap;
}
} }
} }
} }

View File

@ -17,7 +17,11 @@
progress-dot progress-dot
@change="onChange" @change="onChange"
> >
<j-step :title="item" v-for="(item, index) in list" :key="item"> <j-step
:title="item"
v-for="(item, index) in list"
:key="item"
>
<template #description> <template #description>
<span v-if="current === index">进行中</span> <span v-if="current === index">进行中</span>
<span v-if="current < index">未开始</span> <span v-if="current < index">未开始</span>
@ -96,6 +100,8 @@ import {
validateField_api, validateField_api,
} from '@/api/account/center'; } from '@/api/account/center';
import { onlyMessage } from '@/utils/comm'; import { onlyMessage } from '@/utils/comm';
import { Modal } from 'jetlinks-ui-components';
import { LoginPath } from '@/router/menu';
type formType = { type formType = {
oldPassword: string; oldPassword: string;
@ -103,9 +109,10 @@ type formType = {
confirmPassword: string; confirmPassword: string;
}; };
const emits = defineEmits(['save', 'close']); const emits = defineEmits(['close']);
const router = useRouter();
const list = ['验证密码', '设置密码', '二次确认'] const list = ['验证密码', '设置密码', '二次确认'];
const loading = ref(false); const loading = ref(false);
const formRef = ref<any>(); const formRef = ref<any>();
@ -191,7 +198,15 @@ const handleOk = () => {
.then((resp) => { .then((resp) => {
if (resp.status === 200) { if (resp.status === 200) {
onlyMessage('保存成功', 'success'); onlyMessage('保存成功', 'success');
emits('save'); emits('close')
Modal.warning({
content: '密码已重置,请重新登录',
okText: '确定',
onOk() {
localStorage.clear();
router.push(LoginPath);
},
});
} }
}) })
.finally(() => (loading.value = false)); .finally(() => (loading.value = false));

View File

@ -69,7 +69,6 @@
<EditPassword <EditPassword
v-if="editPasswordVisible" v-if="editPasswordVisible"
@close="editPasswordVisible = false" @close="editPasswordVisible = false"
@save="onPasswordSave"
/> />
</div> </div>
</template> </template>
@ -148,9 +147,9 @@ const onSave = () => {
editInfoVisible.value = false; editInfoVisible.value = false;
}; };
const onPasswordSave = () => { // const onPasswordSave = () => {
editPasswordVisible.value = false; // editPasswordVisible.value = false;
}; // };
const onAvatarChange = (url: string) => { const onAvatarChange = (url: string) => {
updateMeInfo_api({ updateMeInfo_api({

View File

@ -212,17 +212,19 @@ const getMetadataMapData = () => {
const customRow = (record: any) => { const customRow = (record: any) => {
return { return {
id: record.id, id: record.id,
class: _value.value === record.name ? 'metadata-search-row' : '', class: _value.value === record?.name ? 'metadata-search-row' : '',
}; };
}; };
const search = (value: string) => { const search = (value: string) => {
if (value) { if (value) {
const _item: any = dataSourceCache.value.find((item: any) => { const _item: any = dataSourceCache.value.find((item: any) => {
return value === item.name; return value === item?.name;
}); });
_value.value = _item.name; if(_item) {
document.getElementById(_item?.id)?.scrollIntoView(); // _value.value = _item?.name;
document.getElementById(_item?.id)?.scrollIntoView(); //
}
} else { } else {
_value.value = undefined; _value.value = undefined;
} }
@ -239,7 +241,7 @@ const getDefaultMetadata = async () => {
targetOptions.value = _properties.map((item) => ({ targetOptions.value = _properties.map((item) => ({
...item, ...item,
label: item.name, label: item?.name,
value: item.id, value: item.id,
})); }));
@ -260,7 +262,7 @@ const getDefaultMetadata = async () => {
return { return {
index: index + 1, index: index + 1,
id: item.id, // id id: item.id, // id
name: item.name, name: item?.name,
type: item.valueType?.type, type: item.valueType?.type,
original: _m?.originalId, // id original: _m?.originalId, // id
}; };

View File

@ -1,14 +1,14 @@
<template> <template>
<div class="file"> <div class="file">
<j-form layout="vertical"> <j-form layout="vertical">
<j-form-item label="下载模板"> <j-form-item>
<div class="file-download"> <template #label>
<j-button @click="downFile('xlsx')">模板格式.xlsx</j-button> <div>
<j-button @click="downFile('csv')">模板格式.csv</j-button> 文件上传
</div> <div class="alert"><AIcon style="margin-right: 5px;" type="InfoCircleOutlined" />导入系统已存在的设备数据不会更改已存在设备的所属产品信息</div>
</j-form-item> </div>
<j-form-item label="文件上传"> </template>
<!-- 导入系统已存在的设备数据不会更改已存在设备的所属产品信息 -->
<a-upload-dragger <a-upload-dragger
v-model:fileList="modelRef.upload" v-model:fileList="modelRef.upload"
name="file" name="file"
@ -28,15 +28,10 @@
:disabled="disabled" :disabled="disabled"
@drop="handleDrop" @drop="handleDrop"
> >
<div <div class="dragger-box">
style=" <AIcon class="icon" type="PlusCircleFilled" />
height: 115px; <span style="margin: 16px 0 8px 0">点击或拖拽上传文件</span>
line-height: 115px; <span>格式.xlsx, .csv</span>
color: #666666;
"
>
<!-- <AIcon style="font-size: 20px;" type="PlusCircleOutlined" /> -->
点击或拖拽上传文件
</div> </div>
</a-upload-dragger> </a-upload-dragger>
</j-form-item> </j-form-item>
@ -45,23 +40,38 @@
>导入并启用</j-checkbox >导入并启用</j-checkbox
> >
</div> </div>
<div v-if="importLoading" class="result">
<div v-if="flag">
<j-spin size="small" style="margin-right: 10px" />正在导入
</div>
<div v-else>
<AIcon
style="
color: #08e21e;
margin-right: 10px;
font-size: 16px;
"
type="CheckCircleOutlined"
/>
</div>
<div>导入成功{{ count }} </div>
<div>
导入失败<span style="color: #ff595e">{{ errCount }}</span>
<a
v-if="errMessage && !flag && errCount > 0"
style="margin-left: 20px"
@click="downError"
>下载</a
>
</div>
</div>
<j-form-item label="下载模板">
<div class="file-download">
<j-button class="btn" @click="downFile('xlsx')">模板格式.xlsx</j-button>
<j-button class="btn" @click="downFile('csv')">模板格式.csv</j-button>
</div>
</j-form-item>
</j-form> </j-form>
<div v-if="importLoading" class="result">
<div v-if="flag">
<j-spin size="small" style="margin-right: 10px" />正在导入
</div>
<div v-else>
<AIcon
style="color: #08e21e; margin-right: 10px; font-size: 16px"
type="CheckCircleOutlined"
/>
</div>
<div>导入成功{{ count }} </div>
<div>
导入失败<span style="color: #ff595e">{{ errCount }}</span>
<a v-if="errMessage && !flag && errCount > 0" style="margin-left: 20px" @click="downError">下载</a>
</div>
</div>
</div> </div>
</template> </template>
@ -125,8 +135,8 @@ const beforeUpload = (_file: any) => {
const handleDrop = () => {}; const handleDrop = () => {};
const downError = () => { const downError = () => {
window.open(errMessage.value) window.open(errMessage.value);
} };
const submitData = async (fileUrl: string) => { const submitData = async (fileUrl: string) => {
if (!!fileUrl) { if (!!fileUrl) {
@ -147,7 +157,7 @@ const submitData = async (fileUrl: string) => {
count.value = dt; count.value = dt;
} else { } else {
if (res.detailFile) { if (res.detailFile) {
errMessage.value = res.detailFile errMessage.value = res.detailFile;
} else { } else {
et += 1; et += 1;
errCount.value = et; errCount.value = et;
@ -196,9 +206,23 @@ const uploadChange = async (info: Record<string, any>) => {
.file-download { .file-download {
display: flex; display: flex;
gap: 16px; gap: 16px;
> button { .btn {
flex: 1; border: none;
min-width: 0; background-color: #ECECF0;
width: 152px;
color: #666666;
}
}
.dragger-box {
margin: 46px 0;
display: flex;
flex-direction: column;
color: #666666;
.icon {
font-size: 30px;
color: @primary-color;
} }
} }
@ -208,5 +232,21 @@ const uploadChange = async (info: Record<string, any>) => {
color: #605e5c; color: #605e5c;
} }
} }
.alert {
height: 40px;
width: 100%;
padding: 0 20px 0 10px;
color: rgba(0, 0, 0, 0.55);
line-height: 40px;
background-color: #f6f6f6;
}
:deep(.ant-form-item) {
.ant-upload.ant-upload-drag {
background: #F8F9FC;
border: 1px dashed rgba(212, 219, 243, 0.7);
}
}
} }
</style> </style>

View File

@ -223,17 +223,20 @@ const getMetadataMapData = () => {
const customRow = (record: any) => { const customRow = (record: any) => {
return { return {
id: record.id, id: record.id,
class: _value.value === record.name ? 'metadata-search-row' : '', class: _value.value === record?.name ? 'metadata-search-row' : '',
}; };
}; };
const search = (value: string) => { const search = (value: string) => {
if (value) { if (value) {
const _item: any = dataSourceCache.value.find((item: any) => { const _item: any = dataSourceCache.value.find((item: any) => {
return value === item.name; return value === item?.name;
}); });
_value.value = _item.name; if(_item) {
document.getElementById(_item?.id)?.scrollIntoView(); // _value.value = _item?.name;
document.getElementById(_item?.id)?.scrollIntoView(); //
}
} else { } else {
_value.value = undefined; _value.value = undefined;
} }
@ -247,7 +250,7 @@ const getDefaultMetadata = async () => {
const metadataMap: any = await getMetadataMapData(); const metadataMap: any = await getMetadataMapData();
pluginOptions.value = pluginProperties.map((item) => ({ pluginOptions.value = pluginProperties.map((item) => ({
...item, ...item,
label: item.name, label: item?.name,
value: item.id, value: item.id,
})); }));
@ -269,7 +272,7 @@ const getDefaultMetadata = async () => {
return { return {
index: index + 1, index: index + 1,
id: item.id, // id id: item.id, // id
name: item.name, name: item?.name,
type: item.valueType?.type, type: item.valueType?.type,
plugin: _m?.pluginId, // id plugin: _m?.pluginId, // id
}; };

View File

@ -6,7 +6,7 @@
@cancel="emit('close')" @cancel="emit('close')"
@ok="onSave" @ok="onSave"
> >
<ApplyList v-model:photoUrl="photoUrl" :options="typeOptions" v-model:value="type" /> <ApplyList type="add" :options="typeOptions" v-model:value="type" />
</j-modal> </j-modal>
</template> </template>
@ -21,12 +21,11 @@ const emit = defineEmits(['close']);
const menuStory = useMenuStore(); const menuStory = useMenuStore();
const type = ref(''); const type = ref('');
const photoUrl = ref('');
const typeOptions = ref<any[]>([]); const typeOptions = ref<any[]>([]);
const onSave = () => { const onSave = () => {
if(type.value){ if(type.value){
menuStory.jumpPage('system/Apply/Save', {}, { provider: type.value, photoUrl: photoUrl.value }); menuStory.jumpPage('system/Apply/Save', {}, { provider: type.value });
} else { } else {
onlyMessage('请先选择应用类型', 'error') onlyMessage('请先选择应用类型', 'error')
} }

View File

@ -8,7 +8,7 @@
@click="onChange(item.value)" @click="onChange(item.value)"
:class="{ active: item.value === _value }" :class="{ active: item.value === _value }"
> >
<div> <div v-if="type === 'edit'">
<MUpload <MUpload
:defaultValue="defaultImg[item.value]" :defaultValue="defaultImg[item.value]"
:borderStyle="{ :borderStyle="{
@ -22,6 +22,9 @@
@change="(_url) => onImgChange(_url, item.value)" @change="(_url) => onImgChange(_url, item.value)"
/> />
</div> </div>
<div v-else>
<j-avatar :src="urlValue[item.value] || defaultImg[item.value]" shape="square" :size="64" />
</div>
<span>{{ item.label }}</span> <span>{{ item.label }}</span>
</div> </div>
</div> </div>
@ -49,6 +52,10 @@ const props = defineProps({
type: Array as PropType<any[]>, type: Array as PropType<any[]>,
default: () => [], default: () => [],
}, },
type: {
type: String,
default: 'edit'
}
}); });
const emit = defineEmits(['update:value', 'update:photoUrl']); const emit = defineEmits(['update:value', 'update:photoUrl']);

View File

@ -43,23 +43,26 @@
:disabled="!!routeQuery.id || !!routeQuery?.provider" :disabled="!!routeQuery.id || !!routeQuery?.provider"
/> />
</j-form-item> </j-form-item>
<j-form-item <j-row>
label="接入方式" <j-col :span="joinOptions.length >= 3 ? 24 : 6 * joinOptions.length">
name="integrationModes" <j-form-item
:rules="[ label="接入方式"
{ name="integrationModes"
required: true, :rules="[
message: '请选择接入方式', {
}, required: true,
]" message: '请选择接入方式',
> },
<j-check-button ]"
v-model:value="form.data.integrationModes" >
:options="joinOptions" <j-check-button
:multiple="true" v-model:value="form.data.integrationModes"
/> :options="joinOptions"
</j-form-item> :multiple="true"
/>
</j-form-item>
</j-col>
</j-row>
<j-collapse style="margin-bottom: 20px;"> <j-collapse style="margin-bottom: 20px;">
<j-collapse-panel <j-collapse-panel
v-for="(item, index) in form.data.integrationModes" v-for="(item, index) in form.data.integrationModes"
@ -1581,9 +1584,6 @@ onMounted(async () => {
} }
if(routeQuery.provider){ if(routeQuery.provider){
form.data.provider = routeQuery?.provider as applyType; form.data.provider = routeQuery?.provider as applyType;
if(routeQuery.photoUrl) {
form.data.logoUrl = routeQuery?.photoUrl as string;
}
typeOptions.value = typeOptions.value.filter((i: any) => { typeOptions.value = typeOptions.value.filter((i: any) => {
return i.value === routeQuery.provider; return i.value === routeQuery.provider;
}); });

View File

@ -231,7 +231,7 @@ watch(
); );
</script> </script>
<style lang="less"> <style lang="less" scoped>
.action-search { .action-search {
padding: 0; padding: 0;
} }