mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-22 21:22:33 +08:00
Merge remote-tracking branch 'origin/lei_dev' into leng_dev
# Conflicts: # package.json
This commit is contained in:
commit
b68eaadfb4
48
doc/SvgIcon.md
Normal file
48
doc/SvgIcon.md
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
## 全局组件
|
||||
- 组件支持`四种`svg图标
|
||||
- `四种`图标均支持 color 和 size 属性,使用示例见下文:
|
||||
|
||||
```mermaid
|
||||
# font-awesome的图标,使用 fa 作为前缀(带个空格)
|
||||
<SvgIcon name="fa fa-pencil" />
|
||||
|
||||
# element-plus 的图标,使用 el-icon 作为前缀,图标名称请使用:首字母大写的驼峰语法
|
||||
<SvgIcon name="ele-icon-Close" color="#8595F4" size="20" />
|
||||
|
||||
# 本地`/src/assets/icons`文件夹内的SVG图标,使用 local 作为前缀,文件名作为后缀
|
||||
# 文件自动加载,新增请重新编译
|
||||
<SvgIcon name="local-logo" />
|
||||
|
||||
# 阿里iconfont的图标,使用 iconfont 作为前缀(带个空格)
|
||||
<SvgIcon name="iconfont icon-user" size="20" />
|
||||
```
|
||||
|
||||
有时,Icon组件会覆盖不了图标的原有颜色或大小,请检查SVG文件的源代码。
|
||||
|
||||
|
||||
## 图标添加与配置
|
||||
### 本地图标
|
||||
1. 将SVG图标文件,放入本地`/src/assets/icons`文件夹,然后重新编译项目。
|
||||
2. 系统会自动加载该目录下的所有图标文件备用,现在你可以使用`Icon`组件来显示图标了。
|
||||
3. 示例:`<SvgIcon name="local-SVG的文件名" />`
|
||||
4. 不建议在此文件夹放置`非常大、非常多`的文件,可能会影响系统加载速度,当确有此方面需求时,请将文件放置到其他位置,并单独导入和使用图标。
|
||||
|
||||
### font-awesome 图标
|
||||
|
||||
1. 此图标库目前 `pigx-ui` 已经默认加载。加载代码在 `/src/utils/setIconfont.ts`中的cssUrls中。
|
||||
2. 你可以直接使用font-awesome 4.7.0的所有图标,这些图标可以在这里 https://fontawesome.com.cn/faicons/ 找到,当然你也可以直接使用图标选择器寻找图标。
|
||||
3. 示例:<SvgIcon name="fa fa-pencil" />,注意图标名称一定是以fa加一个空格开头
|
||||
|
||||
|
||||
|
||||
### element-plus 图标
|
||||
1. 此图标库目前 `pigx-ui` 已经默认加载,加载代码在 `/src/main.ts` 执行的 elementIcons 方法中。
|
||||
2. 你可以直接使用 `element-plus/icons-vue ^2.0.10` 的所有图标,在使用 `element-plus` 图标时,请使用`ele` 作为前缀,图标名称请使用:首字母大写的驼峰语法。
|
||||
3. 示例:<SvgIcon name="ele-RefreshRight" />
|
||||
|
||||
|
||||
### iconfont 图标
|
||||
|
||||
1. 目前系统未使用任何iconfont图标,你可以获取iconfont图标库项目的Font class链接后,设置到 `/src/utils/setIconfont.ts` 中的 `cssUrls` 中,系统会自动加载链接中的所有图标以供使用。
|
||||
2. 示例:`<SvgIcon name="iconfont icon-user" />`,注意图标名称一定是以iconfont加一个空格开头,以图标名称结尾。
|
28
package.json
28
package.json
@ -16,21 +16,21 @@
|
||||
"@highlightjs/vue-plugin": "^2.1.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"axios": "^1.2.1",
|
||||
"axios": "^1.3.3",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"echarts": "^5.4.1",
|
||||
"element-plus": "^2.2.26",
|
||||
"element-plus": "^2.2.32",
|
||||
"form-designer": "^0.0.2",
|
||||
"highlight.js": "^11.7.0",
|
||||
"js-cookie": "^3.0.1",
|
||||
"mitt": "^3.0.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.0.28",
|
||||
"pinia": "^2.0.32",
|
||||
"qrcode": "1.5.1",
|
||||
"qs": "^6.11.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"sortablejs": "^1.15.0",
|
||||
"vue": "3.2.47",
|
||||
"vue": "^3.2.47",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-router": "^4.1.6",
|
||||
@ -38,22 +38,22 @@
|
||||
"xe-utils": "^3.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.13",
|
||||
"@types/node": "^18.14.0",
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@types/sortablejs": "^1.15.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.46.0",
|
||||
"@typescript-eslint/parser": "^5.46.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
||||
"@typescript-eslint/parser": "^5.53.0",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vue/compiler-sfc": "^3.2.45",
|
||||
"@vue/compiler-sfc": "^3.2.47",
|
||||
"consola": "^2.15.3",
|
||||
"eslint": "8.22.0",
|
||||
"eslint-plugin-vue": "^9.8.0",
|
||||
"eslint": "^8.34.0",
|
||||
"eslint-plugin-vue": "^9.9.0",
|
||||
"pinia-plugin-persist": "^1.0.0",
|
||||
"prettier": "^2.8.4",
|
||||
"sass": "^1.56.2",
|
||||
"typescript": "^4.9.4",
|
||||
"prettier": "2.8.4",
|
||||
"sass": "^1.58.3",
|
||||
"typescript": "^4.9.5",
|
||||
"unplugin-auto-import": "^0.13.0",
|
||||
"vite": "^4.0.0",
|
||||
"vite": "^4.1.4",
|
||||
"vite-plugin-compression": "^0.5.1",
|
||||
"vite-plugin-style-import": "^2.0.0",
|
||||
"vite-plugin-top-level-await": "^1.2.4",
|
||||
|
11
src/App.vue
11
src/App.vue
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
|
||||
<router-view v-show="themeConfig.lockScreenTime > 1" />
|
||||
<router-view v-show="setLockScreen" />
|
||||
<LockScreen v-if="themeConfig.isLockScreen" />
|
||||
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||||
@ -32,6 +32,15 @@ const stores = useTagsViewRoutes();
|
||||
const storesThemeConfig = useThemeConfig();
|
||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||
|
||||
// 设置锁屏时组件显示隐藏
|
||||
const setLockScreen = computed(() => {
|
||||
// 防止锁屏后,刷新出现不相关界面
|
||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I6AF8P
|
||||
return themeConfig.value.isLockScreen ? themeConfig.value.lockScreenTime > 1 : themeConfig.value.lockScreenTime >= 0;
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 获取全局组件大小
|
||||
const getGlobalComponentSize = computed(() => {
|
||||
return other.globalComponentSize();
|
||||
|
@ -10,7 +10,7 @@ const clearReturn = /(\r)|(\n)/g;
|
||||
const clearFill = /(fill="[^>+].*?")/g;
|
||||
|
||||
function findSvgFile(dir: string): string[] {
|
||||
const svgRes = [];
|
||||
const svgRes = [] as any;
|
||||
const dirents = readdirSync(dir, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
|
@ -1,29 +1,25 @@
|
||||
<template>
|
||||
<el-tabs v-model="objData.repType" type="border-card" @tab-click="handleClick" style="width: 100%;">
|
||||
<el-tabs v-model="objData.repType" type="border-card" @tab-click="handleClick" style="width: 100%">
|
||||
<el-tab-pane name="text" label="text">
|
||||
<template #label><i class="el-icon-document"></i> 文本</template>
|
||||
<el-input
|
||||
v-model="objData.repContent"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
placeholder="请输入内容">
|
||||
</el-input>
|
||||
<el-input v-model="objData.repContent" type="textarea" :rows="5" placeholder="请输入内容"> </el-input>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="image" label="image">
|
||||
<template #label><i class="el-icon-picture"></i> 图片</template>
|
||||
<el-row>
|
||||
<div v-if="objData.repUrl" class="select-item">
|
||||
<img class="material-img" :src="objData.repUrl">
|
||||
<img class="material-img" :src="objData.repUrl" />
|
||||
<p v-if="objData.repName" class="item-name">{{ objData.repName }}</p>
|
||||
<el-row class="ope-row">
|
||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="!objData.repUrl" style="width: 100%;">
|
||||
<div v-if="!objData.repUrl" style="width: 100%">
|
||||
<el-row style="text-align: center">
|
||||
<el-col :span="12" class="col-select">
|
||||
<el-button type="success" @click="openMaterial({type: 'image',accountId: props.objData.appId})">素材库选择<i class="fansel-icon--right"></i>
|
||||
<el-button type="success" @click="openMaterial({ type: 'image', accountId: props.objData.appId })"
|
||||
>素材库选择<i class="fansel-icon--right"></i>
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12" class="col-add">
|
||||
@ -40,16 +36,17 @@
|
||||
<div v-if="objData.repName" class="select-item">
|
||||
<p class="item-name">{{ objData.repName }}</p>
|
||||
<div class="item-infos">
|
||||
<img :src="WxVoice" style="width: 100px" @click="loadVideo(item)">
|
||||
<img :src="WxVoice" style="width: 100px" @click="loadVideo(item)" />
|
||||
</div>
|
||||
<el-row class="ope-row">
|
||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="!objData.repName" style="width: 100%;">
|
||||
<div v-if="!objData.repName" style="width: 100%">
|
||||
<el-row style="text-align: center">
|
||||
<el-col :span="12" class="col-select">
|
||||
<el-button type="success" @click="openMaterial({type: 'voice',accountId: props.objData.appId})">素材库选择<i class="fansel-icon--right"></i>
|
||||
<el-button type="success" @click="openMaterial({ type: 'voice', accountId: props.objData.appId })"
|
||||
>素材库选择<i class="fansel-icon--right"></i>
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="12" class="col-add">
|
||||
@ -62,20 +59,19 @@
|
||||
|
||||
<el-tab-pane name="video" label="video">
|
||||
<template #label><i class="el-icon-share"></i> 视频</template>
|
||||
<el-row style="text-align: center;flex: 1">
|
||||
<el-row style="text-align: center; flex: 1">
|
||||
<el-input v-model="objData.repName" placeholder="请输入标题"></el-input>
|
||||
<el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
|
||||
<div style="text-align: center;">
|
||||
<a v-if="objData.repUrl" target="_blank" :href="objData.repUrl"><i
|
||||
class="icon-bofang"> 播放视频</i></a>
|
||||
</div>
|
||||
<div style="margin: 20px 0;"></div>
|
||||
<div style="text-align: center">
|
||||
<el-button type="success" @click="openMaterial({type: 'video',accountId: props.objData.appId})">素材库选择<i class="fansel-icon--right"></i>
|
||||
<a v-if="objData.repUrl" target="_blank" :href="objData.repUrl"><i class="icon-bofang"> 播放视频</i></a>
|
||||
</div>
|
||||
<div style="margin: 20px 0"></div>
|
||||
<div style="text-align: center">
|
||||
<el-button type="success" @click="openMaterial({ type: 'video', accountId: props.objData.appId })"
|
||||
>素材库选择<i class="fansel-icon--right"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane name="news" label="news">
|
||||
@ -87,10 +83,11 @@
|
||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="!objData.content" style="width: 100%;">
|
||||
<div v-if="!objData.content" style="width: 100%">
|
||||
<el-row style="text-align: center">
|
||||
<el-col :span="24" class="col-select2">
|
||||
<el-button type="success" @click="openMaterial({type: 'news',accountId: props.objData.appId})">素材库选择<i class="fansel-icon--right"></i>
|
||||
<el-button type="success" @click="openMaterial({ type: 'news', accountId: props.objData.appId })"
|
||||
>素材库选择<i class="fansel-icon--right"></i>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -100,20 +97,18 @@
|
||||
</el-tabs>
|
||||
|
||||
<wx-material-select ref="dialogNewsRef" @selectMaterial="selectMaterial"></wx-material-select>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="wx-reply">
|
||||
import {getMaterialVideo} from "/@/api/mp/wx-material";
|
||||
import {useMessage} from "/@/hooks/message";
|
||||
import WxVideo from '/@/assets/icon/wx-video.svg'
|
||||
import WxVoice from '/@/assets/icon/wx-voice.svg'
|
||||
const WxMaterialSelect = defineAsyncComponent(() => import("/@/components/wechart/wx-material-select/main.vue"))
|
||||
import { getMaterialVideo } from '/@/api/mp/wx-material';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import WxVideo from '/@/assets/icon/wx-video.svg';
|
||||
import WxVoice from '/@/assets/icon/wx-voice.svg';
|
||||
const WxMaterialSelect = defineAsyncComponent(() => import('/@/components/wechart/wx-material-select/main.vue'));
|
||||
|
||||
const WxFileUpload = defineAsyncComponent(() => import("/@/components/wechart/fileUpload/index.vue"))
|
||||
|
||||
const WxNews = defineAsyncComponent(() => import("/@/components/wechart/wx-news/index.vue"))
|
||||
const WxFileUpload = defineAsyncComponent(() => import('/@/components/wechart/fileUpload/index.vue'));
|
||||
|
||||
const WxNews = defineAsyncComponent(() => import('/@/components/wechart/wx-news/index.vue'));
|
||||
|
||||
const props = defineProps({
|
||||
objData: {
|
||||
@ -124,122 +119,118 @@ const props = defineProps({
|
||||
repContent: '',
|
||||
repName: '',
|
||||
repDesc: '',
|
||||
repUrl: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
repUrl: '',
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const uploadData = reactive({
|
||||
mediaType: props.objData.repType,
|
||||
title: '',
|
||||
introduction: '',
|
||||
appId: props.objData.appId
|
||||
})
|
||||
appId: props.objData.appId,
|
||||
});
|
||||
|
||||
const tempObj = ref() as any
|
||||
const tempObj = ref() as any;
|
||||
|
||||
const handleClick = (tab) => {
|
||||
uploadData.mediaType = tab.paneName
|
||||
uploadData.appId = props.objData.appId
|
||||
uploadData.mediaType = tab.paneName;
|
||||
uploadData.appId = props.objData.appId;
|
||||
|
||||
const tempObjItem = tempObj.value[props.objData.repType]
|
||||
const tempObjItem = tempObj.value[props.objData.repType];
|
||||
if (tempObjItem) {
|
||||
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null
|
||||
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null
|
||||
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null
|
||||
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null
|
||||
props.objData.content = tempObjItem.content ? tempObjItem.content : null
|
||||
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null
|
||||
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null;
|
||||
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null;
|
||||
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null;
|
||||
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null;
|
||||
props.objData.content = tempObjItem.content ? tempObjItem.content : null;
|
||||
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null;
|
||||
} else {
|
||||
props.objData.repName = ''
|
||||
props.objData.repMediaId = ''
|
||||
props.objData.media_id = ''
|
||||
props.objData.repUrl = ''
|
||||
props.objData.content = ''
|
||||
props.objData.repDesc = ''
|
||||
props.objData.repName = '';
|
||||
props.objData.repMediaId = '';
|
||||
props.objData.media_id = '';
|
||||
props.objData.repUrl = '';
|
||||
props.objData.content = '';
|
||||
props.objData.repDesc = '';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
const deleteObj = () => {
|
||||
props.objData.repName = ''
|
||||
props.objData.repUrl = ''
|
||||
props.objData.content = ''
|
||||
}
|
||||
props.objData.repName = '';
|
||||
props.objData.repUrl = '';
|
||||
props.objData.content = '';
|
||||
};
|
||||
|
||||
const openMaterial = (data: any) => {
|
||||
dialogNewsRef.value.openDialog(data)
|
||||
}
|
||||
dialogNewsRef.value.openDialog(data);
|
||||
};
|
||||
|
||||
const dialogNewsRef = ref()
|
||||
const dialogNewsRef = ref();
|
||||
|
||||
const selectMaterial = (item, appId) => {
|
||||
let tempObjItem = {
|
||||
repType: '',
|
||||
repMediaId: '',
|
||||
media_id: '',
|
||||
content: ''
|
||||
} as any
|
||||
tempObjItem.repType = props.objData.repType
|
||||
tempObjItem.repMediaId = item.mediaId
|
||||
tempObjItem.media_id = item.mediaId
|
||||
tempObjItem.content = item.content
|
||||
content: '',
|
||||
} as any;
|
||||
tempObjItem.repType = props.objData.repType;
|
||||
tempObjItem.repMediaId = item.mediaId;
|
||||
tempObjItem.media_id = item.mediaId;
|
||||
tempObjItem.content = item.content;
|
||||
|
||||
props.objData.repMediaId = item.mediaId
|
||||
props.objData.media_id = item.mediaId
|
||||
props.objData.content = item.content
|
||||
props.objData.repMediaId = item.mediaId;
|
||||
props.objData.media_id = item.mediaId;
|
||||
props.objData.content = item.content;
|
||||
if (props.objData.repType === 'music') {
|
||||
tempObjItem.repThumbMediaId = item.mediaId
|
||||
tempObjItem.repThumbUrl = item.url
|
||||
props.objData.repThumbMediaId = item.mediaId
|
||||
props.objData.repThumbUrl = item.url
|
||||
tempObjItem.repThumbMediaId = item.mediaId;
|
||||
tempObjItem.repThumbUrl = item.url;
|
||||
props.objData.repThumbMediaId = item.mediaId;
|
||||
props.objData.repThumbUrl = item.url;
|
||||
} else {
|
||||
tempObjItem.repName = item.name
|
||||
tempObjItem.repUrl = item.url
|
||||
props.objData.repName = item.name
|
||||
props.objData.repUrl = item.url
|
||||
tempObjItem.repName = item.name;
|
||||
tempObjItem.repUrl = item.url;
|
||||
props.objData.repName = item.name;
|
||||
props.objData.repUrl = item.url;
|
||||
}
|
||||
if (props.objData.repType === 'video') {
|
||||
getMaterialVideo({
|
||||
mediaId: item.mediaId,
|
||||
appId: appId
|
||||
}).then(response => {
|
||||
const data = response.data
|
||||
tempObjItem.repDesc = data.description || ''
|
||||
tempObjItem.repUrl = data.downUrl
|
||||
props.objData.repName = data.title
|
||||
props.objData.repDesc = data.description || ''
|
||||
props.objData.repUrl = data.downUrl
|
||||
})
|
||||
appId: appId,
|
||||
}).then((response) => {
|
||||
const data = response.data;
|
||||
tempObjItem.repDesc = data.description || '';
|
||||
tempObjItem.repUrl = data.downUrl;
|
||||
props.objData.repName = data.title;
|
||||
props.objData.repDesc = data.description || '';
|
||||
props.objData.repUrl = data.downUrl;
|
||||
});
|
||||
}
|
||||
tempObj.value[props.objData.repType] = tempObjItem
|
||||
}
|
||||
tempObj.value[props.objData.repType] = tempObjItem;
|
||||
};
|
||||
|
||||
const handelUpload = (response) => {
|
||||
if (response.code === 0) {
|
||||
const item = response.data
|
||||
selectMaterial(item,props.objData.appId)
|
||||
const item = response.data;
|
||||
selectMaterial(item, props.objData.appId);
|
||||
} else {
|
||||
useMessage().error("上传错误" + response.msg)
|
||||
useMessage().error('上传错误' + response.msg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const loadVideo = (item) => {
|
||||
getMaterialVideo({
|
||||
mediaId: item.repMediaId,
|
||||
appId: item.appId
|
||||
}).then(response => {
|
||||
const data = response.data
|
||||
window.open(data.downUrl,'target','');
|
||||
})
|
||||
}
|
||||
|
||||
appId: item.appId,
|
||||
}).then((response) => {
|
||||
const data = response.data;
|
||||
window.open(data.downUrl, 'target', '');
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.select-item {
|
||||
width: 280px;
|
||||
padding: 10px;
|
||||
@ -288,7 +279,7 @@ const loadVideo = (item) => {
|
||||
padding: 50px 0px;
|
||||
height: 160px;
|
||||
width: 49.5%;
|
||||
float: right
|
||||
float: right;
|
||||
}
|
||||
|
||||
.avatar-uploader-icon {
|
||||
@ -312,6 +303,6 @@ const loadVideo = (item) => {
|
||||
|
||||
.item-infos {
|
||||
width: 30%;
|
||||
margin: auto
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
|
@ -2,7 +2,7 @@ import { createI18n } from 'vue-i18n';
|
||||
import pinia from '/@/stores/index';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||
import { info } from '/@/api/admin/i18n'
|
||||
import { info } from '/@/api/admin/i18n';
|
||||
|
||||
// 定义语言国际化内容
|
||||
|
||||
@ -20,7 +20,7 @@ import zhcnLocale from 'element-plus/lib/locale/lang/zh-cn';
|
||||
|
||||
// 定义变量内容
|
||||
const messages = {};
|
||||
const element = { en: enLocale, 'zh-cn': zhcnLocale};
|
||||
const element = { en: enLocale, 'zh-cn': zhcnLocale };
|
||||
const itemize = { en: [] as any[], 'zh-cn': [] as any[] };
|
||||
const modules: Record<string, any> = import.meta.glob('./**/*.ts', { eager: true });
|
||||
const pages: Record<string, any> = import.meta.glob('./../../**/**/**/i18n/*.ts', { eager: true });
|
||||
@ -46,12 +46,14 @@ function mergeArrObj<T>(list: T, key: string) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
// 远程获取i18n
|
||||
const infoI18n = await info()
|
||||
|
||||
itemize["zh-cn"].push(...infoI18n.data['zh-cn'])
|
||||
itemize.en.push(...infoI18n.data.en)
|
||||
try {
|
||||
const infoI18n = await info();
|
||||
itemize['zh-cn'].push(...infoI18n.data['zh-cn']);
|
||||
itemize.en.push(...infoI18n.data.en);
|
||||
} catch (e) {
|
||||
// 考虑请求不过去没有后台的情况下导致的i18n失效
|
||||
}
|
||||
|
||||
for (const key in itemize) {
|
||||
messages[key] = {
|
||||
@ -61,7 +63,6 @@ for (const key in itemize) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// 读取 pinia 默认语言
|
||||
const stores = useThemeConfig(pinia);
|
||||
const { themeConfig } = storeToRefs(stores);
|
||||
|
@ -8,10 +8,10 @@ import { useThemeConfig } from '/@/stores/themeConfig';
|
||||
import { i18n } from '/@/i18n/index';
|
||||
import { Local } from '/@/utils/storage';
|
||||
import { verifyUrl } from '/@/utils/toolsValidate';
|
||||
import request from "/@/utils/request";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import request from '/@/utils/request';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
// @ts-ignore
|
||||
import * as CryptoJS from "crypto-js";
|
||||
import * as CryptoJS from 'crypto-js';
|
||||
|
||||
// 引入组件
|
||||
const SvgIcon = defineAsyncComponent(() => import('/@/components/svgIcon/index.vue'));
|
||||
@ -57,8 +57,10 @@ export function useTitle() {
|
||||
export function setTagsViewNameI18n(item: any) {
|
||||
let tagsViewName: string = '';
|
||||
const { query, params, meta } = item;
|
||||
//修复tagsViewName匹配到其他含下列单词的路由
|
||||
const pattern = /^\{("(zh-cn|en|zh-tw)":"[^,]+",?){1,3}}$/;
|
||||
if (query?.tagsViewName || params?.tagsViewName) {
|
||||
if (/\/zh-cn|en|zh-tw\//.test(query?.tagsViewName) || /\/zh-cn|en|zh-tw\//.test(params?.tagsViewName)) {
|
||||
if (pattern.test(query?.tagsViewName) || pattern.test(params?.tagsViewName)) {
|
||||
// 国际化
|
||||
const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName));
|
||||
tagsViewName = urlTagsParams[i18n.global.locale.value];
|
||||
@ -180,16 +182,10 @@ export function handleOpenLink(val: RouteItem) {
|
||||
*/
|
||||
export const openWindow = (url: string, title: string, w: number, h: number) => {
|
||||
// Fixes dual-screen position Most browsers Firefox
|
||||
const dualScreenLeft =
|
||||
window.screenLeft !== undefined ? window.screenLeft : screen.left;
|
||||
const dualScreenTop =
|
||||
window.screenTop !== undefined ? window.screenTop : screen.top;
|
||||
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
|
||||
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
|
||||
|
||||
const width = window.innerWidth
|
||||
? window.innerWidth
|
||||
: document.documentElement.clientWidth
|
||||
? document.documentElement.clientWidth
|
||||
: screen.width;
|
||||
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
|
||||
const height = window.innerHeight
|
||||
? window.innerHeight
|
||||
: document.documentElement.clientHeight
|
||||
@ -201,13 +197,13 @@ export const openWindow = (url: string, title: string, w: number, h: number) =>
|
||||
return window.open(
|
||||
url,
|
||||
title,
|
||||
"toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=" +
|
||||
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' +
|
||||
w +
|
||||
", height=" +
|
||||
', height=' +
|
||||
h +
|
||||
", top=" +
|
||||
', top=' +
|
||||
top +
|
||||
", left=" +
|
||||
', left=' +
|
||||
left
|
||||
);
|
||||
};
|
||||
@ -217,7 +213,7 @@ export const openWindow = (url: string, title: string, w: number, h: number) =>
|
||||
export function encryption(params: any) {
|
||||
let { data, type, param, key } = params;
|
||||
const result = JSON.parse(JSON.stringify(data));
|
||||
if (type === "Base64") {
|
||||
if (type === 'Base64') {
|
||||
param.forEach((ele: any) => {
|
||||
result[ele] = btoa(result[ele]);
|
||||
});
|
||||
@ -230,7 +226,7 @@ export function encryption(params: any) {
|
||||
var encrypted = CryptoJS.AES.encrypt(data, key, {
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CFB,
|
||||
padding: CryptoJS.pad.NoPadding
|
||||
padding: CryptoJS.pad.NoPadding,
|
||||
});
|
||||
result[ele] = encrypted.toString();
|
||||
});
|
||||
@ -248,11 +244,11 @@ export function encryption(params: any) {
|
||||
export function downBlobFile(url: any, query: any, fileName: string) {
|
||||
return request({
|
||||
url: url,
|
||||
method: "get",
|
||||
responseType: "blob",
|
||||
params: query
|
||||
}).then(response => {
|
||||
handleBlobFile(response, fileName)
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
params: query,
|
||||
}).then((response) => {
|
||||
handleBlobFile(response, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
@ -265,10 +261,10 @@ export function handleBlobFile(response: any, fileName: string) {
|
||||
// 处理返回的文件流
|
||||
const blob = response;
|
||||
if (blob && blob.size === 0) {
|
||||
useMessage().error("内容为空,无法下载");
|
||||
useMessage().error('内容为空,无法下载');
|
||||
return;
|
||||
}
|
||||
const link = document.createElement("a");
|
||||
const link = document.createElement('a');
|
||||
|
||||
// 兼容一下 入参不是 File Blob 类型情况
|
||||
var binaryData = [] as any;
|
||||
@ -325,37 +321,37 @@ const other = {
|
||||
handleOpenLink(val);
|
||||
},
|
||||
encryption: (data: any) => {
|
||||
return encryption(data)
|
||||
return encryption(data);
|
||||
},
|
||||
downBlobFile: (url: any, query: any, fileName: string) => {
|
||||
return downBlobFile(url, query, fileName)
|
||||
return downBlobFile(url, query, fileName);
|
||||
},
|
||||
toUnderline: (str: string) => {
|
||||
return toUnderline(str)
|
||||
return toUnderline(str);
|
||||
},
|
||||
openWindow: (url: string, title: string, w: number, h: number) => {
|
||||
return openWindow(url, title, w, h)
|
||||
return openWindow(url, title, w, h);
|
||||
},
|
||||
getQueryString: (url: string, paraName: string) => {
|
||||
return getQueryString(url, paraName)
|
||||
}
|
||||
return getQueryString(url, paraName);
|
||||
},
|
||||
};
|
||||
|
||||
export function getQueryString(url: string, paraName: string) {
|
||||
const arrObj = url.split("?");
|
||||
const arrObj = url.split('?');
|
||||
if (arrObj.length > 1) {
|
||||
const arrPara = arrObj[1].split("&");
|
||||
const arrPara = arrObj[1].split('&');
|
||||
let arr;
|
||||
for (let i = 0; i < arrPara.length; i++) {
|
||||
arr = arrPara[i].split("=");
|
||||
arr = arrPara[i].split('=');
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (arr != null && arr[0] == paraName) {
|
||||
return arr[1];
|
||||
}
|
||||
}
|
||||
return "";
|
||||
return '';
|
||||
} else {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,25 +365,31 @@ export function getQueryString(url: string, paraName: string) {
|
||||
* @returns {*}
|
||||
*/
|
||||
export function handleTree(data, id, parentId, children, rootId) {
|
||||
id = id || 'id'
|
||||
parentId = parentId || 'parentId'
|
||||
children = children || 'children'
|
||||
rootId = rootId || Math.min.apply(Math, data.map(item => {
|
||||
return item[parentId]
|
||||
})) || 0
|
||||
id = id || 'id';
|
||||
parentId = parentId || 'parentId';
|
||||
children = children || 'children';
|
||||
rootId =
|
||||
rootId ||
|
||||
Math.min.apply(
|
||||
Math,
|
||||
data.map((item) => {
|
||||
return item[parentId];
|
||||
})
|
||||
) ||
|
||||
0;
|
||||
//对源数据深度克隆
|
||||
const cloneData = JSON.parse(JSON.stringify(data))
|
||||
const cloneData = JSON.parse(JSON.stringify(data));
|
||||
//循环所有项
|
||||
const treeData = cloneData.filter(father => {
|
||||
const branchArr = cloneData.filter(child => {
|
||||
const treeData = cloneData.filter((father) => {
|
||||
const branchArr = cloneData.filter((child) => {
|
||||
//返回每一项的子级数组
|
||||
return father[id] === child[parentId]
|
||||
})
|
||||
branchArr.length > 0 ? father[children] = branchArr : ''
|
||||
return father[id] === child[parentId];
|
||||
});
|
||||
branchArr.length > 0 ? (father[children] = branchArr) : '';
|
||||
//返回第一层
|
||||
return father[parentId] === rootId
|
||||
})
|
||||
return treeData !== '' ? treeData : data
|
||||
return father[parentId] === rootId;
|
||||
});
|
||||
return treeData !== '' ? treeData : data;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -396,9 +398,8 @@ export function handleTree(data, id, parentId, children, rootId) {
|
||||
* @returns 下划线
|
||||
*/
|
||||
export function toUnderline(str: string) {
|
||||
return str.replace(/([A-Z])/g, "_$1").toLowerCase()
|
||||
return str.replace(/([A-Z])/g, '_$1').toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
// 统一批量导出
|
||||
export default other;
|
||||
|
@ -6,7 +6,7 @@ import qs from 'qs';
|
||||
// 配置新建一个 axios 实例
|
||||
const service: AxiosInstance = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_URL,
|
||||
timeout: 50000,
|
||||
timeout: 5000,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
paramsSerializer: {
|
||||
serialize(params) {
|
||||
@ -16,16 +16,17 @@ const service: AxiosInstance = axios.create({
|
||||
});
|
||||
|
||||
// 添加请求拦截器
|
||||
service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
|
||||
service.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
// get查询参数序列化
|
||||
if (config.method === 'get') {
|
||||
// @ts-ignore
|
||||
config.paramsSerializer = (params: any) => {
|
||||
return qs.stringify(params, { arrayFormat: 'repeat' })
|
||||
}
|
||||
return qs.stringify(params, { arrayFormat: 'repeat' });
|
||||
};
|
||||
}
|
||||
// 统一增加 token
|
||||
const isToken = (config.headers || {}).isToken === false
|
||||
const isToken = (config.headers || {}).isToken === false;
|
||||
if (Session.get('token') && !isToken) {
|
||||
config.headers!['Authorization'] = `Bearer ${Session.get('token')}`;
|
||||
}
|
||||
@ -36,7 +37,7 @@ service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
},
|
||||
(error) => {
|
||||
// 对请求错误做些什么
|
||||
return Promise.reject(error);
|
||||
@ -44,29 +45,30 @@ service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
|
||||
);
|
||||
|
||||
// 添加响应拦截器
|
||||
service.interceptors.response.use((res: any) => {
|
||||
service.interceptors.response.use(
|
||||
(res: any) => {
|
||||
if (res.data.code === 1) {
|
||||
throw res.data
|
||||
throw res.data;
|
||||
}
|
||||
return res.data;
|
||||
}, error => {
|
||||
const status = Number(error.response.status) || 200
|
||||
},
|
||||
(error) => {
|
||||
console.log(error, 'rrrrr');
|
||||
const status = Number(error.response.status) || 200;
|
||||
if (status === 424) {
|
||||
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
type: 'warning',
|
||||
}).then(() => {
|
||||
Session.clear(); // 清除浏览器全部临时缓存
|
||||
window.location.href = '/'; // 去登录页
|
||||
return
|
||||
})
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(error.response.data);
|
||||
})
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
// 导出 axios 实例
|
||||
export default service;
|
||||
|
@ -8,18 +8,23 @@ import Cookies from 'js-cookie';
|
||||
* @method clear 移除全部永久缓存
|
||||
*/
|
||||
export const Local = {
|
||||
// 查看 v2.4.3版本更新日志
|
||||
setKey(key: string) {
|
||||
// @ts-ignore
|
||||
return `${__NEXT_NAME__}:${key}`;
|
||||
},
|
||||
// 设置永久缓存
|
||||
set(key: string, val: any) {
|
||||
window.localStorage.setItem(key, JSON.stringify(val));
|
||||
set<T>(key: string, val: T) {
|
||||
window.localStorage.setItem(Local.setKey(key), JSON.stringify(val));
|
||||
},
|
||||
// 获取永久缓存
|
||||
get(key: string) {
|
||||
let json = <string>window.localStorage.getItem(key);
|
||||
let json = <string>window.localStorage.getItem(Local.setKey(key));
|
||||
return JSON.parse(json);
|
||||
},
|
||||
// 移除永久缓存
|
||||
remove(key: string) {
|
||||
window.localStorage.removeItem(key);
|
||||
window.localStorage.removeItem(Local.setKey(key));
|
||||
},
|
||||
// 移除全部永久缓存
|
||||
clear() {
|
||||
|
@ -42,33 +42,31 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="社交登录" prop="social" >
|
||||
<a-row style="display: flex;justify-content: space-between;width: 300px">
|
||||
<el-form-item label="社交登录" prop="social">
|
||||
<el-row style="display: flex; justify-content: space-between; width: 300px">
|
||||
<div @click="handleClick('wechat')" class="item">
|
||||
<SvgIcon name="local-wechat" :size="20"/>
|
||||
<SvgIcon name="local-wechat" :size="20" />
|
||||
<p class="title">微信</p>
|
||||
</div>
|
||||
<div @click="handleClick('tencent')" class="item">
|
||||
<SvgIcon name="local-qq" :size="20"/>
|
||||
<SvgIcon name="local-qq" :size="20" />
|
||||
<p class="title">QQ</p>
|
||||
</div>
|
||||
<div @click="handleClick('gitee')" class="item">
|
||||
<SvgIcon name="local-gitee" :size="20"/>
|
||||
<SvgIcon name="local-gitee" :size="20" />
|
||||
<p class="title">Gitee</p>
|
||||
</div>
|
||||
<div @click="handleClick('osc')" class="item">
|
||||
<SvgIcon name="local-oschina" :size="20"/>
|
||||
<SvgIcon name="local-oschina" :size="20" />
|
||||
<p class="title">开源中国</p>
|
||||
</div>
|
||||
</a-row>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSaveUser">
|
||||
更新个人信息
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleSaveUser"> 更新个人信息 </el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -81,8 +79,7 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="原密码" prop="password">
|
||||
<el-input v-model="passwordFormData.password" placeholder="请输入密码" clearable
|
||||
type="password"></el-input>
|
||||
<el-input v-model="passwordFormData.password" placeholder="请输入密码" clearable type="password"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
@ -97,9 +94,7 @@
|
||||
</el-col>
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleChangePassword">
|
||||
修改密码
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleChangePassword"> 修改密码 </el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -112,19 +107,18 @@
|
||||
|
||||
<script setup lang="ts" name="personal">
|
||||
import { useUserInfo } from '/@/stores/userInfo';
|
||||
import { editInfo, password } from '/@/api/admin/user'
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { rule } from "/@/utils/validate";
|
||||
import { editInfo, password } from '/@/api/admin/user';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { rule } from '/@/utils/validate';
|
||||
import other from '/@/utils/other';
|
||||
import {Session} from "/@/utils/storage";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Session } from '/@/utils/storage';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
const { t } = useI18n()
|
||||
const { t } = useI18n();
|
||||
|
||||
const ImageUpload = defineAsyncComponent(() => import('/@/components/Upload/Image.vue'));
|
||||
|
||||
const ImageUpload = defineAsyncComponent(() => import('/@/components/Upload/Image.vue'))
|
||||
|
||||
const visible = ref(false)
|
||||
const visible = ref(false);
|
||||
|
||||
// 定义变量内容
|
||||
const formData = reactive({
|
||||
@ -139,120 +133,122 @@ const formData = reactive({
|
||||
const passwordFormData = reactive({
|
||||
password: '',
|
||||
newpassword1: '',
|
||||
newpassword2: ''
|
||||
})
|
||||
newpassword2: '',
|
||||
});
|
||||
|
||||
const formdataRef = ref()
|
||||
const passwordFormdataRef = ref()
|
||||
const formdataRef = ref();
|
||||
const passwordFormdataRef = ref();
|
||||
|
||||
const ruleForm = reactive({
|
||||
|
||||
phone: [{ required: true, message: "手机号不能为空", trigger: "blur" }, { validator: rule.validatePhone, trigger: 'blur' }],
|
||||
nickname: [{ required: true, message: "昵称不能为空", trigger: "blur" }],
|
||||
email: [{ required: true, message: "邮箱不能为空", trigger: "blur" }],
|
||||
name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
|
||||
|
||||
})
|
||||
phone: [
|
||||
{ required: true, message: '手机号不能为空', trigger: 'blur' },
|
||||
{ validator: rule.validatePhone, trigger: 'blur' },
|
||||
],
|
||||
nickname: [{ required: true, message: '昵称不能为空', trigger: 'blur' }],
|
||||
email: [{ required: true, message: '邮箱不能为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
|
||||
});
|
||||
const validatorPassword2 = (rule: any, value: any, callback: any) => {
|
||||
if(value !== passwordFormData.newpassword1){
|
||||
callback(new Error(t('personal.passwordRule')))
|
||||
}else{
|
||||
callback()
|
||||
if (value !== passwordFormData.newpassword1) {
|
||||
callback(new Error(t('personal.passwordRule')));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const passwordRuleForm = reactive({
|
||||
password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
|
||||
newpassword1: [{
|
||||
password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
|
||||
newpassword1: [
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: "用户密码长度必须介于 6 和 20 之间",
|
||||
trigger: "blur"
|
||||
}],
|
||||
message: '用户密码长度必须介于 6 和 20 之间',
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
newpassword2: [
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: "用户密码长度必须介于 6 和 20 之间",
|
||||
trigger: "blur"
|
||||
},{ validator: validatorPassword2, trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
|
||||
message: '用户密码长度必须介于 6 和 20 之间',
|
||||
trigger: 'blur',
|
||||
},
|
||||
{ validator: validatorPassword2, trigger: 'blur' },
|
||||
],
|
||||
});
|
||||
|
||||
// 头像上传成功
|
||||
const handleAvatarSuccess = (url: any) => {
|
||||
formData.avatar = url;
|
||||
}
|
||||
};
|
||||
|
||||
const handleChangePassword = () => {
|
||||
passwordFormdataRef.value.validate((valid: boolean) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
password(passwordFormData).then(() => {
|
||||
useMessage().success("修改成功")
|
||||
password(passwordFormData)
|
||||
.then(() => {
|
||||
useMessage().success('修改成功');
|
||||
// 需要重新登录
|
||||
// 清除缓存/token等
|
||||
Session.clear();
|
||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||
window.location.reload();
|
||||
}).catch(err => {
|
||||
useMessage().error(err.msg)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
.catch((err) => {
|
||||
useMessage().error(err.msg);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 保存用户
|
||||
const handleSaveUser = () => {
|
||||
formdataRef.value.validate((valid: boolean) => {
|
||||
if (!valid) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
editInfo(formData).then(() => {
|
||||
useMessage().success("修改成功")
|
||||
editInfo(formData)
|
||||
.then(() => {
|
||||
useMessage().success('修改成功');
|
||||
// 更新上下文的 user信息
|
||||
useUserInfo().setUserInfos()
|
||||
}).catch(err => {
|
||||
useMessage().error(err.msg)
|
||||
useUserInfo().setUserInfos();
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
.catch((err) => {
|
||||
useMessage().error(err.msg);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleClick = (thirdpart: string) => {
|
||||
let appid, client_id, redirect_uri, url;
|
||||
redirect_uri = encodeURIComponent(
|
||||
window.location.origin + "/#/authredirect"
|
||||
);
|
||||
if (thirdpart === "wechat") {
|
||||
appid = "wxd1678d3f83b1d83a";
|
||||
redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect');
|
||||
if (thirdpart === 'wechat') {
|
||||
appid = 'wxd1678d3f83b1d83a';
|
||||
url = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${redirect_uri}&state=WX-BIND&response_type=code&scope=snsapi_login#wechat_redirect`;
|
||||
} else if (thirdpart === "tencent") {
|
||||
client_id = "101322838";
|
||||
} else if (thirdpart === 'tencent') {
|
||||
client_id = '101322838';
|
||||
url = `https://graph.qq.com/oauth2.0/authorize?response_type=code&state=QQ-BIND&client_id=${client_id}&redirect_uri=${redirect_uri}`;
|
||||
} else if (thirdpart === "gitee") {
|
||||
client_id = '0c29cfd9cb1e0037fc837521bc08c1a7483d8fd9b3e123d46beec59a5544a881'
|
||||
} else if (thirdpart === 'gitee') {
|
||||
client_id = '0c29cfd9cb1e0037fc837521bc08c1a7483d8fd9b3e123d46beec59a5544a881';
|
||||
url = `https://gitee.com/oauth/authorize?response_type=code&state=GITEE-BIND&client_id=${client_id}&redirect_uri=${redirect_uri}`;
|
||||
} else if (thirdpart === "osc") {
|
||||
client_id = "neIIqlwGsjsfsA6uxNqD";
|
||||
} else if (thirdpart === 'osc') {
|
||||
client_id = 'neIIqlwGsjsfsA6uxNqD';
|
||||
url = `https://www.oschina.net/action/oauth2/authorize?response_type=code&client_id=${client_id}&state=OSC-BIND&redirect_uri=${redirect_uri}`;
|
||||
}
|
||||
other.openWindow(url, thirdpart, 540, 540)
|
||||
}
|
||||
other.openWindow(url, thirdpart, 540, 540);
|
||||
};
|
||||
|
||||
const open = () => {
|
||||
visible.value = true
|
||||
const data = useUserInfo().userInfos
|
||||
Object.assign(formData, data.user)
|
||||
}
|
||||
visible.value = true;
|
||||
const data = useUserInfo().userInfos;
|
||||
Object.assign(formData, data.user);
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@ -461,7 +457,7 @@ defineExpose({
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.item{
|
||||
.item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
@ -90,6 +90,7 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||
__VUE_I18N_FULL_INSTALL__: JSON.stringify(false),
|
||||
__INTLIFY_PROD_DEVTOOLS__: JSON.stringify(false),
|
||||
__VERSION__: JSON.stringify(process.env.npm_package_version),
|
||||
__NEXT_NAME__: JSON.stringify(process.env.npm_package_name),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user