mirror of
https://gitee.com/log4j/pig-ui.git
synced 2024-12-23 05:40:20 +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加一个空格开头,以图标名称结尾。
|
168
package.json
168
package.json
@ -1,86 +1,86 @@
|
|||||||
{
|
{
|
||||||
"name": "pigx-ui-pro",
|
"name": "pigx-ui-pro",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "PIGCLOUD微服务开发平台",
|
"description": "PIGCLOUD微服务开发平台",
|
||||||
"author": "pig4cloud",
|
"author": "pig4cloud",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --force",
|
"dev": "vite --force",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
|
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
|
||||||
"prettier": "prettier --write ."
|
"prettier": "prettier --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chenfengyuan/vue-qrcode": "^2.0.0",
|
"@chenfengyuan/vue-qrcode": "^2.0.0",
|
||||||
"@element-plus/icons-vue": "^2.0.10",
|
"@element-plus/icons-vue": "^2.0.10",
|
||||||
"@highlightjs/vue-plugin": "^2.1.0",
|
"@highlightjs/vue-plugin": "^2.1.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.3.3",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"echarts": "^5.4.1",
|
"echarts": "^5.4.1",
|
||||||
"element-plus": "^2.2.26",
|
"element-plus": "^2.2.32",
|
||||||
"form-designer": "^0.0.2",
|
"form-designer": "^0.0.2",
|
||||||
"highlight.js": "^11.7.0",
|
"highlight.js": "^11.7.0",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.28",
|
"pinia": "^2.0.32",
|
||||||
"qrcode": "1.5.1",
|
"qrcode": "1.5.1",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"vue": "3.2.47",
|
"vue": "^3.2.47",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
"vxe-table": "^4.3.5",
|
"vxe-table": "^4.3.5",
|
||||||
"xe-utils": "^3.5.4"
|
"xe-utils": "^3.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.13",
|
"@types/node": "^18.14.0",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/nprogress": "^0.2.0",
|
||||||
"@types/sortablejs": "^1.15.0",
|
"@types/sortablejs": "^1.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.46.0",
|
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
||||||
"@typescript-eslint/parser": "^5.46.0",
|
"@typescript-eslint/parser": "^5.53.0",
|
||||||
"@vitejs/plugin-vue": "^4.0.0",
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
"@vue/compiler-sfc": "^3.2.45",
|
"@vue/compiler-sfc": "^3.2.47",
|
||||||
"consola": "^2.15.3",
|
"consola": "^2.15.3",
|
||||||
"eslint": "8.22.0",
|
"eslint": "^8.34.0",
|
||||||
"eslint-plugin-vue": "^9.8.0",
|
"eslint-plugin-vue": "^9.9.0",
|
||||||
"pinia-plugin-persist": "^1.0.0",
|
"pinia-plugin-persist": "^1.0.0",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "2.8.4",
|
||||||
"sass": "^1.56.2",
|
"sass": "^1.58.3",
|
||||||
"typescript": "^4.9.4",
|
"typescript": "^4.9.5",
|
||||||
"unplugin-auto-import": "^0.13.0",
|
"unplugin-auto-import": "^0.13.0",
|
||||||
"vite": "^4.0.0",
|
"vite": "^4.1.4",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-style-import": "^2.0.0",
|
"vite-plugin-style-import": "^2.0.0",
|
||||||
"vite-plugin-top-level-await": "^1.2.4",
|
"vite-plugin-top-level-await": "^1.2.4",
|
||||||
"vite-plugin-vue-setup-extend": "^0.4.0",
|
"vite-plugin-vue-setup-extend": "^0.4.0",
|
||||||
"vue-eslint-parser": "^9.1.0"
|
"vue-eslint-parser": "^9.1.0"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not dead"
|
"not dead"
|
||||||
],
|
],
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://pig4cloud.com"
|
"url": "https://pig4cloud.com"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.0.0",
|
||||||
"npm": ">= 7.0.0"
|
"npm": ">= 7.0.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"vue",
|
"vue",
|
||||||
"vue3",
|
"vue3",
|
||||||
"vuejs/vue-next",
|
"vuejs/vue-next",
|
||||||
"element-ui",
|
"element-ui",
|
||||||
"element-plus"
|
"element-plus"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitee.com/log4j/pig"
|
"url": "https://gitee.com/log4j/pig"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
src/App.vue
11
src/App.vue
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
|
<el-config-provider :size="getGlobalComponentSize" :locale="getGlobalI18n">
|
||||||
<router-view v-show="themeConfig.lockScreenTime > 1" />
|
<router-view v-show="setLockScreen" />
|
||||||
<LockScreen v-if="themeConfig.isLockScreen" />
|
<LockScreen v-if="themeConfig.isLockScreen" />
|
||||||
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||||||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||||||
@ -32,6 +32,15 @@ const stores = useTagsViewRoutes();
|
|||||||
const storesThemeConfig = useThemeConfig();
|
const storesThemeConfig = useThemeConfig();
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
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(() => {
|
const getGlobalComponentSize = computed(() => {
|
||||||
return other.globalComponentSize();
|
return other.globalComponentSize();
|
||||||
|
@ -10,7 +10,7 @@ const clearReturn = /(\r)|(\n)/g;
|
|||||||
const clearFill = /(fill="[^>+].*?")/g;
|
const clearFill = /(fill="[^>+].*?")/g;
|
||||||
|
|
||||||
function findSvgFile(dir: string): string[] {
|
function findSvgFile(dir: string): string[] {
|
||||||
const svgRes = [];
|
const svgRes = [] as any;
|
||||||
const dirents = readdirSync(dir, {
|
const dirents = readdirSync(dir, {
|
||||||
withFileTypes: true,
|
withFileTypes: true,
|
||||||
});
|
});
|
||||||
|
@ -1,317 +1,308 @@
|
|||||||
<template>
|
<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">
|
<el-tab-pane name="text" label="text">
|
||||||
<template #label><i class="el-icon-document"></i> 文本</template>
|
<template #label><i class="el-icon-document"></i> 文本</template>
|
||||||
<el-input
|
<el-input v-model="objData.repContent" type="textarea" :rows="5" placeholder="请输入内容"> </el-input>
|
||||||
v-model="objData.repContent"
|
</el-tab-pane>
|
||||||
type="textarea"
|
|
||||||
:rows="5"
|
|
||||||
placeholder="请输入内容">
|
|
||||||
</el-input>
|
|
||||||
</el-tab-pane>
|
|
||||||
|
|
||||||
<el-tab-pane name="image" label="image">
|
<el-tab-pane name="image" label="image">
|
||||||
<template #label><i class="el-icon-picture"></i> 图片</template>
|
<template #label><i class="el-icon-picture"></i> 图片</template>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div v-if="objData.repUrl" class="select-item">
|
<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>
|
<p v-if="objData.repName" class="item-name">{{ objData.repName }}</p>
|
||||||
<el-row class="ope-row">
|
<el-row class="ope-row">
|
||||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!objData.repUrl" style="width: 100%;">
|
<div v-if="!objData.repUrl" style="width: 100%">
|
||||||
<el-row style="text-align: center">
|
<el-row style="text-align: center">
|
||||||
<el-col :span="12" class="col-select">
|
<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 })"
|
||||||
</el-button>
|
>素材库选择<i class="fansel-icon--right"></i>
|
||||||
</el-col>
|
</el-button>
|
||||||
<el-col :span="12" class="col-add">
|
</el-col>
|
||||||
<wx-file-upload :data="uploadData" @success="handelUpload"></wx-file-upload>
|
<el-col :span="12" class="col-add">
|
||||||
</el-col>
|
<wx-file-upload :data="uploadData" @success="handelUpload"></wx-file-upload>
|
||||||
</el-row>
|
</el-col>
|
||||||
</div>
|
</el-row>
|
||||||
</el-row>
|
</div>
|
||||||
</el-tab-pane>
|
</el-row>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane name="voice" label="voice">
|
<el-tab-pane name="voice" label="voice">
|
||||||
<template #label><i class="el-icon-phone"></i> 语音</template>
|
<template #label><i class="el-icon-phone"></i> 语音</template>
|
||||||
<el-row>
|
<el-row>
|
||||||
<div v-if="objData.repName" class="select-item">
|
<div v-if="objData.repName" class="select-item">
|
||||||
<p class="item-name">{{ objData.repName }}</p>
|
<p class="item-name">{{ objData.repName }}</p>
|
||||||
<div class="item-infos">
|
<div class="item-infos">
|
||||||
<img :src="WxVoice" style="width: 100px" @click="loadVideo(item)">
|
<img :src="WxVoice" style="width: 100px" @click="loadVideo(item)" />
|
||||||
</div>
|
</div>
|
||||||
<el-row class="ope-row">
|
<el-row class="ope-row">
|
||||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!objData.repName" style="width: 100%;">
|
<div v-if="!objData.repName" style="width: 100%">
|
||||||
<el-row style="text-align: center">
|
<el-row style="text-align: center">
|
||||||
<el-col :span="12" class="col-select">
|
<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 })"
|
||||||
</el-button>
|
>素材库选择<i class="fansel-icon--right"></i>
|
||||||
</el-col>
|
</el-button>
|
||||||
<el-col :span="12" class="col-add">
|
</el-col>
|
||||||
<wx-file-upload :data="uploadData" @success="handelUpload"></wx-file-upload>
|
<el-col :span="12" class="col-add">
|
||||||
</el-col>
|
<wx-file-upload :data="uploadData" @success="handelUpload"></wx-file-upload>
|
||||||
</el-row>
|
</el-col>
|
||||||
</div>
|
</el-row>
|
||||||
</el-row>
|
</div>
|
||||||
</el-tab-pane>
|
</el-row>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<el-tab-pane name="video" label="video">
|
<el-tab-pane name="video" label="video">
|
||||||
<template #label><i class="el-icon-share"></i> 视频</template>
|
<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.repName" placeholder="请输入标题"></el-input>
|
||||||
<el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
|
<el-input v-model="objData.repDesc" placeholder="请输入描述"></el-input>
|
||||||
<div style="text-align: center;">
|
<div style="text-align: center">
|
||||||
<a v-if="objData.repUrl" target="_blank" :href="objData.repUrl"><i
|
<a v-if="objData.repUrl" target="_blank" :href="objData.repUrl"><i class="icon-bofang"> 播放视频</i></a>
|
||||||
class="icon-bofang"> 播放视频</i></a>
|
</div>
|
||||||
</div>
|
<div style="margin: 20px 0"></div>
|
||||||
<div style="margin: 20px 0;"></div>
|
<div style="text-align: center">
|
||||||
<div style="text-align: center">
|
<el-button type="success" @click="openMaterial({ type: 'video', accountId: props.objData.appId })"
|
||||||
<el-button type="success" @click="openMaterial({type: 'video',accountId: props.objData.appId})">素材库选择<i class="fansel-icon--right"></i>
|
>素材库选择<i class="fansel-icon--right"></i>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
</el-tab-pane>
|
<el-tab-pane name="news" label="news">
|
||||||
|
<template #label><i class="el-icon-news"></i> 图文</template>
|
||||||
<el-tab-pane name="news" label="news">
|
<el-row>
|
||||||
<template #label><i class="el-icon-news"></i> 图文</template>
|
<div v-if="objData.content" class="select-item">
|
||||||
<el-row>
|
<wx-news :obj-data="objData.content.newsItem"></wx-news>
|
||||||
<div v-if="objData.content" class="select-item">
|
<el-row class="ope-row">
|
||||||
<wx-news :obj-data="objData.content.newsItem"></wx-news>
|
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
||||||
<el-row class="ope-row">
|
</el-row>
|
||||||
<el-button type="danger" icon="el-icon-delete" circle @click="deleteObj"></el-button>
|
</div>
|
||||||
</el-row>
|
<div v-if="!objData.content" style="width: 100%">
|
||||||
</div>
|
<el-row style="text-align: center">
|
||||||
<div v-if="!objData.content" style="width: 100%;">
|
<el-col :span="24" class="col-select2">
|
||||||
<el-row style="text-align: center">
|
<el-button type="success" @click="openMaterial({ type: 'news', accountId: props.objData.appId })"
|
||||||
<el-col :span="24" class="col-select2">
|
>素材库选择<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-button>
|
</el-col>
|
||||||
</el-col>
|
</el-row>
|
||||||
</el-row>
|
</div>
|
||||||
</div>
|
</el-row>
|
||||||
</el-row>
|
</el-tab-pane>
|
||||||
</el-tab-pane>
|
</el-tabs>
|
||||||
</el-tabs>
|
|
||||||
|
|
||||||
<wx-material-select ref="dialogNewsRef" @selectMaterial="selectMaterial"></wx-material-select>
|
|
||||||
|
|
||||||
|
<wx-material-select ref="dialogNewsRef" @selectMaterial="selectMaterial"></wx-material-select>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="wx-reply">
|
<script setup lang="ts" name="wx-reply">
|
||||||
import {getMaterialVideo} from "/@/api/mp/wx-material";
|
import { getMaterialVideo } from '/@/api/mp/wx-material';
|
||||||
import {useMessage} from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import WxVideo from '/@/assets/icon/wx-video.svg'
|
import WxVideo from '/@/assets/icon/wx-video.svg';
|
||||||
import WxVoice from '/@/assets/icon/wx-voice.svg'
|
import WxVoice from '/@/assets/icon/wx-voice.svg';
|
||||||
const WxMaterialSelect = defineAsyncComponent(() => import("/@/components/wechart/wx-material-select/main.vue"))
|
const WxMaterialSelect = defineAsyncComponent(() => import('/@/components/wechart/wx-material-select/main.vue'));
|
||||||
|
|
||||||
const WxFileUpload = defineAsyncComponent(() => import("/@/components/wechart/fileUpload/index.vue"))
|
const WxFileUpload = defineAsyncComponent(() => import('/@/components/wechart/fileUpload/index.vue'));
|
||||||
|
|
||||||
const WxNews = defineAsyncComponent(() => import("/@/components/wechart/wx-news/index.vue"))
|
|
||||||
|
|
||||||
|
const WxNews = defineAsyncComponent(() => import('/@/components/wechart/wx-news/index.vue'));
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
objData: {
|
objData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => {
|
default: () => {
|
||||||
return {
|
return {
|
||||||
repType: '',
|
repType: '',
|
||||||
repContent: '',
|
repContent: '',
|
||||||
repName: '',
|
repName: '',
|
||||||
repDesc: '',
|
repDesc: '',
|
||||||
repUrl: ''
|
repUrl: '',
|
||||||
}
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const uploadData = reactive({
|
const uploadData = reactive({
|
||||||
mediaType: props.objData.repType,
|
mediaType: props.objData.repType,
|
||||||
title: '',
|
title: '',
|
||||||
introduction: '',
|
introduction: '',
|
||||||
appId: props.objData.appId
|
appId: props.objData.appId,
|
||||||
})
|
});
|
||||||
|
|
||||||
const tempObj = ref() as any
|
const tempObj = ref() as any;
|
||||||
|
|
||||||
const handleClick = (tab) => {
|
const handleClick = (tab) => {
|
||||||
uploadData.mediaType = tab.paneName
|
uploadData.mediaType = tab.paneName;
|
||||||
uploadData.appId = props.objData.appId
|
uploadData.appId = props.objData.appId;
|
||||||
|
|
||||||
const tempObjItem = tempObj.value[props.objData.repType]
|
const tempObjItem = tempObj.value[props.objData.repType];
|
||||||
if (tempObjItem) {
|
if (tempObjItem) {
|
||||||
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null
|
props.objData.repName = tempObjItem.repName ? tempObjItem.repName : null;
|
||||||
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null
|
props.objData.repMediaId = tempObjItem.repMediaId ? tempObjItem.repMediaId : null;
|
||||||
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null
|
props.objData.media_id = tempObjItem.media_id ? tempObjItem.media_id : null;
|
||||||
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null
|
props.objData.repUrl = tempObjItem.repUrl ? tempObjItem.repUrl : null;
|
||||||
props.objData.content = tempObjItem.content ? tempObjItem.content : null
|
props.objData.content = tempObjItem.content ? tempObjItem.content : null;
|
||||||
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null
|
props.objData.repDesc = tempObjItem.repDesc ? tempObjItem.repDesc : null;
|
||||||
} else {
|
} else {
|
||||||
props.objData.repName = ''
|
props.objData.repName = '';
|
||||||
props.objData.repMediaId = ''
|
props.objData.repMediaId = '';
|
||||||
props.objData.media_id = ''
|
props.objData.media_id = '';
|
||||||
props.objData.repUrl = ''
|
props.objData.repUrl = '';
|
||||||
props.objData.content = ''
|
props.objData.content = '';
|
||||||
props.objData.repDesc = ''
|
props.objData.repDesc = '';
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const deleteObj = () => {
|
const deleteObj = () => {
|
||||||
props.objData.repName = ''
|
props.objData.repName = '';
|
||||||
props.objData.repUrl = ''
|
props.objData.repUrl = '';
|
||||||
props.objData.content = ''
|
props.objData.content = '';
|
||||||
}
|
};
|
||||||
|
|
||||||
const openMaterial = (data: any) => {
|
const openMaterial = (data: any) => {
|
||||||
dialogNewsRef.value.openDialog(data)
|
dialogNewsRef.value.openDialog(data);
|
||||||
}
|
};
|
||||||
|
|
||||||
const dialogNewsRef = ref()
|
const dialogNewsRef = ref();
|
||||||
|
|
||||||
const selectMaterial = (item, appId) => {
|
const selectMaterial = (item, appId) => {
|
||||||
let tempObjItem = {
|
let tempObjItem = {
|
||||||
repType: '',
|
repType: '',
|
||||||
repMediaId: '',
|
repMediaId: '',
|
||||||
media_id: '',
|
media_id: '',
|
||||||
content: ''
|
content: '',
|
||||||
} as any
|
} as any;
|
||||||
tempObjItem.repType = props.objData.repType
|
tempObjItem.repType = props.objData.repType;
|
||||||
tempObjItem.repMediaId = item.mediaId
|
tempObjItem.repMediaId = item.mediaId;
|
||||||
tempObjItem.media_id = item.mediaId
|
tempObjItem.media_id = item.mediaId;
|
||||||
tempObjItem.content = item.content
|
tempObjItem.content = item.content;
|
||||||
|
|
||||||
props.objData.repMediaId = item.mediaId
|
props.objData.repMediaId = item.mediaId;
|
||||||
props.objData.media_id = item.mediaId
|
props.objData.media_id = item.mediaId;
|
||||||
props.objData.content = item.content
|
props.objData.content = item.content;
|
||||||
if (props.objData.repType === 'music') {
|
if (props.objData.repType === 'music') {
|
||||||
tempObjItem.repThumbMediaId = item.mediaId
|
tempObjItem.repThumbMediaId = item.mediaId;
|
||||||
tempObjItem.repThumbUrl = item.url
|
tempObjItem.repThumbUrl = item.url;
|
||||||
props.objData.repThumbMediaId = item.mediaId
|
props.objData.repThumbMediaId = item.mediaId;
|
||||||
props.objData.repThumbUrl = item.url
|
props.objData.repThumbUrl = item.url;
|
||||||
} else {
|
} else {
|
||||||
tempObjItem.repName = item.name
|
tempObjItem.repName = item.name;
|
||||||
tempObjItem.repUrl = item.url
|
tempObjItem.repUrl = item.url;
|
||||||
props.objData.repName = item.name
|
props.objData.repName = item.name;
|
||||||
props.objData.repUrl = item.url
|
props.objData.repUrl = item.url;
|
||||||
}
|
}
|
||||||
if (props.objData.repType === 'video') {
|
if (props.objData.repType === 'video') {
|
||||||
getMaterialVideo({
|
getMaterialVideo({
|
||||||
mediaId: item.mediaId,
|
mediaId: item.mediaId,
|
||||||
appId: appId
|
appId: appId,
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
const data = response.data
|
const data = response.data;
|
||||||
tempObjItem.repDesc = data.description || ''
|
tempObjItem.repDesc = data.description || '';
|
||||||
tempObjItem.repUrl = data.downUrl
|
tempObjItem.repUrl = data.downUrl;
|
||||||
props.objData.repName = data.title
|
props.objData.repName = data.title;
|
||||||
props.objData.repDesc = data.description || ''
|
props.objData.repDesc = data.description || '';
|
||||||
props.objData.repUrl = data.downUrl
|
props.objData.repUrl = data.downUrl;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
tempObj.value[props.objData.repType] = tempObjItem
|
tempObj.value[props.objData.repType] = tempObjItem;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handelUpload = (response) => {
|
const handelUpload = (response) => {
|
||||||
if (response.code === 0) {
|
if (response.code === 0) {
|
||||||
const item = response.data
|
const item = response.data;
|
||||||
selectMaterial(item,props.objData.appId)
|
selectMaterial(item, props.objData.appId);
|
||||||
} else {
|
} else {
|
||||||
useMessage().error("上传错误" + response.msg)
|
useMessage().error('上传错误' + response.msg);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const loadVideo = (item) => {
|
const loadVideo = (item) => {
|
||||||
getMaterialVideo({
|
getMaterialVideo({
|
||||||
mediaId: item.repMediaId,
|
mediaId: item.repMediaId,
|
||||||
appId: item.appId
|
appId: item.appId,
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
const data = response.data
|
const data = response.data;
|
||||||
window.open(data.downUrl,'target','');
|
window.open(data.downUrl, 'target', '');
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
||||||
.select-item {
|
.select-item {
|
||||||
width: 280px;
|
width: 280px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 0 auto 10px auto;
|
margin: 0 auto 10px auto;
|
||||||
border: 1px solid #eaeaea;
|
border: 1px solid #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-item2 {
|
.select-item2 {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 0 auto 10px auto;
|
margin: 0 auto 10px auto;
|
||||||
border: 1px solid #eaeaea;
|
border: 1px solid #eaeaea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ope-row {
|
.ope-row {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name {
|
.item-name {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-form-item__content {
|
.el-form-item__content {
|
||||||
line-height: unset !important;
|
line-height: unset !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-select {
|
.col-select {
|
||||||
border: 1px solid rgb(234, 234, 234);
|
border: 1px solid rgb(234, 234, 234);
|
||||||
padding: 50px 0px;
|
padding: 50px 0px;
|
||||||
height: 160px;
|
height: 160px;
|
||||||
width: 49.5%;
|
width: 49.5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-select2 {
|
.col-select2 {
|
||||||
border: 1px solid rgb(234, 234, 234);
|
border: 1px solid rgb(234, 234, 234);
|
||||||
padding: 50px 0px;
|
padding: 50px 0px;
|
||||||
height: 160px;
|
height: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-add {
|
.col-add {
|
||||||
border: 1px solid rgb(234, 234, 234);
|
border: 1px solid rgb(234, 234, 234);
|
||||||
padding: 50px 0px;
|
padding: 50px 0px;
|
||||||
height: 160px;
|
height: 160px;
|
||||||
width: 49.5%;
|
width: 49.5%;
|
||||||
float: right
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-uploader-icon {
|
.avatar-uploader-icon {
|
||||||
border: 1px solid #d9d9d9;
|
border: 1px solid #d9d9d9;
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
color: #8c939d;
|
color: #8c939d;
|
||||||
width: 100px !important;
|
width: 100px !important;
|
||||||
height: 100px !important;
|
height: 100px !important;
|
||||||
line-height: 100px !important;
|
line-height: 100px !important;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.material-img {
|
.material-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumb-div {
|
.thumb-div {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-infos {
|
.item-infos {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
margin: auto
|
margin: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,7 +2,7 @@ import { createI18n } from 'vue-i18n';
|
|||||||
import pinia from '/@/stores/index';
|
import pinia from '/@/stores/index';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
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 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 itemize = { en: [] as any[], 'zh-cn': [] as any[] };
|
||||||
const modules: Record<string, any> = import.meta.glob('./**/*.ts', { eager: true });
|
const modules: Record<string, any> = import.meta.glob('./**/*.ts', { eager: true });
|
||||||
const pages: Record<string, any> = import.meta.glob('./../../**/**/**/i18n/*.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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 远程获取i18n
|
// 远程获取i18n
|
||||||
const infoI18n = await info()
|
try {
|
||||||
|
const infoI18n = await info();
|
||||||
itemize["zh-cn"].push(...infoI18n.data['zh-cn'])
|
itemize['zh-cn'].push(...infoI18n.data['zh-cn']);
|
||||||
itemize.en.push(...infoI18n.data.en)
|
itemize.en.push(...infoI18n.data.en);
|
||||||
|
} catch (e) {
|
||||||
|
// 考虑请求不过去没有后台的情况下导致的i18n失效
|
||||||
|
}
|
||||||
|
|
||||||
for (const key in itemize) {
|
for (const key in itemize) {
|
||||||
messages[key] = {
|
messages[key] = {
|
||||||
@ -61,7 +63,6 @@ for (const key in itemize) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 读取 pinia 默认语言
|
// 读取 pinia 默认语言
|
||||||
const stores = useThemeConfig(pinia);
|
const stores = useThemeConfig(pinia);
|
||||||
const { themeConfig } = storeToRefs(stores);
|
const { themeConfig } = storeToRefs(stores);
|
||||||
|
@ -8,10 +8,10 @@ import { useThemeConfig } from '/@/stores/themeConfig';
|
|||||||
import { i18n } from '/@/i18n/index';
|
import { i18n } from '/@/i18n/index';
|
||||||
import { Local } from '/@/utils/storage';
|
import { Local } from '/@/utils/storage';
|
||||||
import { verifyUrl } from '/@/utils/toolsValidate';
|
import { verifyUrl } from '/@/utils/toolsValidate';
|
||||||
import request from "/@/utils/request";
|
import request from '/@/utils/request';
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as CryptoJS from "crypto-js";
|
import * as CryptoJS from 'crypto-js';
|
||||||
|
|
||||||
// 引入组件
|
// 引入组件
|
||||||
const SvgIcon = defineAsyncComponent(() => import('/@/components/svgIcon/index.vue'));
|
const SvgIcon = defineAsyncComponent(() => import('/@/components/svgIcon/index.vue'));
|
||||||
@ -57,8 +57,10 @@ export function useTitle() {
|
|||||||
export function setTagsViewNameI18n(item: any) {
|
export function setTagsViewNameI18n(item: any) {
|
||||||
let tagsViewName: string = '';
|
let tagsViewName: string = '';
|
||||||
const { query, params, meta } = item;
|
const { query, params, meta } = item;
|
||||||
|
//修复tagsViewName匹配到其他含下列单词的路由
|
||||||
|
const pattern = /^\{("(zh-cn|en|zh-tw)":"[^,]+",?){1,3}}$/;
|
||||||
if (query?.tagsViewName || params?.tagsViewName) {
|
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));
|
const urlTagsParams = (query?.tagsViewName && JSON.parse(query?.tagsViewName)) || (params?.tagsViewName && JSON.parse(params?.tagsViewName));
|
||||||
tagsViewName = urlTagsParams[i18n.global.locale.value];
|
tagsViewName = urlTagsParams[i18n.global.locale.value];
|
||||||
@ -180,35 +182,29 @@ export function handleOpenLink(val: RouteItem) {
|
|||||||
*/
|
*/
|
||||||
export const openWindow = (url: string, title: string, w: number, h: number) => {
|
export const openWindow = (url: string, title: string, w: number, h: number) => {
|
||||||
// Fixes dual-screen position Most browsers Firefox
|
// Fixes dual-screen position Most browsers Firefox
|
||||||
const dualScreenLeft =
|
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left;
|
||||||
window.screenLeft !== undefined ? window.screenLeft : screen.left;
|
const dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top;
|
||||||
const dualScreenTop =
|
|
||||||
window.screenTop !== undefined ? window.screenTop : screen.top;
|
|
||||||
|
|
||||||
const width = window.innerWidth
|
const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width;
|
||||||
? window.innerWidth
|
|
||||||
: document.documentElement.clientWidth
|
|
||||||
? document.documentElement.clientWidth
|
|
||||||
: screen.width;
|
|
||||||
const height = window.innerHeight
|
const height = window.innerHeight
|
||||||
? window.innerHeight
|
? window.innerHeight
|
||||||
: document.documentElement.clientHeight
|
: document.documentElement.clientHeight
|
||||||
? document.documentElement.clientHeight
|
? document.documentElement.clientHeight
|
||||||
: screen.height;
|
: screen.height;
|
||||||
|
|
||||||
const left = width / 2 - w / 2 + dualScreenLeft;
|
const left = width / 2 - w / 2 + dualScreenLeft;
|
||||||
const top = height / 2 - h / 2 + dualScreenTop;
|
const top = height / 2 - h / 2 + dualScreenTop;
|
||||||
return window.open(
|
return window.open(
|
||||||
url,
|
url,
|
||||||
title,
|
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 +
|
w +
|
||||||
", height=" +
|
', height=' +
|
||||||
h +
|
h +
|
||||||
", top=" +
|
', top=' +
|
||||||
top +
|
top +
|
||||||
", left=" +
|
', left=' +
|
||||||
left
|
left
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -217,7 +213,7 @@ export const openWindow = (url: string, title: string, w: number, h: number) =>
|
|||||||
export function encryption(params: any) {
|
export function encryption(params: any) {
|
||||||
let { data, type, param, key } = params;
|
let { data, type, param, key } = params;
|
||||||
const result = JSON.parse(JSON.stringify(data));
|
const result = JSON.parse(JSON.stringify(data));
|
||||||
if (type === "Base64") {
|
if (type === 'Base64') {
|
||||||
param.forEach((ele: any) => {
|
param.forEach((ele: any) => {
|
||||||
result[ele] = btoa(result[ele]);
|
result[ele] = btoa(result[ele]);
|
||||||
});
|
});
|
||||||
@ -230,7 +226,7 @@ export function encryption(params: any) {
|
|||||||
var encrypted = CryptoJS.AES.encrypt(data, key, {
|
var encrypted = CryptoJS.AES.encrypt(data, key, {
|
||||||
iv: iv,
|
iv: iv,
|
||||||
mode: CryptoJS.mode.CFB,
|
mode: CryptoJS.mode.CFB,
|
||||||
padding: CryptoJS.pad.NoPadding
|
padding: CryptoJS.pad.NoPadding,
|
||||||
});
|
});
|
||||||
result[ele] = encrypted.toString();
|
result[ele] = encrypted.toString();
|
||||||
});
|
});
|
||||||
@ -248,11 +244,11 @@ export function encryption(params: any) {
|
|||||||
export function downBlobFile(url: any, query: any, fileName: string) {
|
export function downBlobFile(url: any, query: any, fileName: string) {
|
||||||
return request({
|
return request({
|
||||||
url: url,
|
url: url,
|
||||||
method: "get",
|
method: 'get',
|
||||||
responseType: "blob",
|
responseType: 'blob',
|
||||||
params: query
|
params: query,
|
||||||
}).then(response => {
|
}).then((response) => {
|
||||||
handleBlobFile(response, fileName)
|
handleBlobFile(response, fileName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,10 +261,10 @@ export function handleBlobFile(response: any, fileName: string) {
|
|||||||
// 处理返回的文件流
|
// 处理返回的文件流
|
||||||
const blob = response;
|
const blob = response;
|
||||||
if (blob && blob.size === 0) {
|
if (blob && blob.size === 0) {
|
||||||
useMessage().error("内容为空,无法下载");
|
useMessage().error('内容为空,无法下载');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const link = document.createElement("a");
|
const link = document.createElement('a');
|
||||||
|
|
||||||
// 兼容一下 入参不是 File Blob 类型情况
|
// 兼容一下 入参不是 File Blob 类型情况
|
||||||
var binaryData = [] as any;
|
var binaryData = [] as any;
|
||||||
@ -325,37 +321,37 @@ const other = {
|
|||||||
handleOpenLink(val);
|
handleOpenLink(val);
|
||||||
},
|
},
|
||||||
encryption: (data: any) => {
|
encryption: (data: any) => {
|
||||||
return encryption(data)
|
return encryption(data);
|
||||||
},
|
},
|
||||||
downBlobFile: (url: any, query: any, fileName: string) => {
|
downBlobFile: (url: any, query: any, fileName: string) => {
|
||||||
return downBlobFile(url, query, fileName)
|
return downBlobFile(url, query, fileName);
|
||||||
},
|
},
|
||||||
toUnderline: (str: string) => {
|
toUnderline: (str: string) => {
|
||||||
return toUnderline(str)
|
return toUnderline(str);
|
||||||
},
|
},
|
||||||
openWindow: (url: string, title: string, w: number, h: number) => {
|
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) => {
|
getQueryString: (url: string, paraName: string) => {
|
||||||
return getQueryString(url, paraName)
|
return getQueryString(url, paraName);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getQueryString(url: string, paraName: string) {
|
export function getQueryString(url: string, paraName: string) {
|
||||||
const arrObj = url.split("?");
|
const arrObj = url.split('?');
|
||||||
if (arrObj.length > 1) {
|
if (arrObj.length > 1) {
|
||||||
const arrPara = arrObj[1].split("&");
|
const arrPara = arrObj[1].split('&');
|
||||||
let arr;
|
let arr;
|
||||||
for (let i = 0; i < arrPara.length; i++) {
|
for (let i = 0; i < arrPara.length; i++) {
|
||||||
arr = arrPara[i].split("=");
|
arr = arrPara[i].split('=');
|
||||||
// eslint-disable-next-line eqeqeq
|
// eslint-disable-next-line eqeqeq
|
||||||
if (arr != null && arr[0] == paraName) {
|
if (arr != null && arr[0] == paraName) {
|
||||||
return arr[1];
|
return arr[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return '';
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,25 +365,31 @@ export function getQueryString(url: string, paraName: string) {
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function handleTree(data, id, parentId, children, rootId) {
|
export function handleTree(data, id, parentId, children, rootId) {
|
||||||
id = id || 'id'
|
id = id || 'id';
|
||||||
parentId = parentId || 'parentId'
|
parentId = parentId || 'parentId';
|
||||||
children = children || 'children'
|
children = children || 'children';
|
||||||
rootId = rootId || Math.min.apply(Math, data.map(item => {
|
rootId =
|
||||||
return item[parentId]
|
rootId ||
|
||||||
})) || 0
|
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 treeData = cloneData.filter((father) => {
|
||||||
const branchArr = cloneData.filter(child => {
|
const branchArr = cloneData.filter((child) => {
|
||||||
//返回每一项的子级数组
|
//返回每一项的子级数组
|
||||||
return father[id] === child[parentId]
|
return father[id] === child[parentId];
|
||||||
})
|
});
|
||||||
branchArr.length > 0 ? father[children] = branchArr : ''
|
branchArr.length > 0 ? (father[children] = branchArr) : '';
|
||||||
//返回第一层
|
//返回第一层
|
||||||
return father[parentId] === rootId
|
return father[parentId] === rootId;
|
||||||
})
|
});
|
||||||
return treeData !== '' ? treeData : data
|
return treeData !== '' ? treeData : data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -396,9 +398,8 @@ export function handleTree(data, id, parentId, children, rootId) {
|
|||||||
* @returns 下划线
|
* @returns 下划线
|
||||||
*/
|
*/
|
||||||
export function toUnderline(str: string) {
|
export function toUnderline(str: string) {
|
||||||
return str.replace(/([A-Z])/g, "_$1").toLowerCase()
|
return str.replace(/([A-Z])/g, '_$1').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 统一批量导出
|
// 统一批量导出
|
||||||
export default other;
|
export default other;
|
||||||
|
@ -5,68 +5,70 @@ import qs from 'qs';
|
|||||||
|
|
||||||
// 配置新建一个 axios 实例
|
// 配置新建一个 axios 实例
|
||||||
const service: AxiosInstance = axios.create({
|
const service: AxiosInstance = axios.create({
|
||||||
baseURL: import.meta.env.VITE_API_URL,
|
baseURL: import.meta.env.VITE_API_URL,
|
||||||
timeout: 50000,
|
timeout: 5000,
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
paramsSerializer: {
|
paramsSerializer: {
|
||||||
serialize(params) {
|
serialize(params) {
|
||||||
return qs.stringify(params, { allowDots: true });
|
return qs.stringify(params, { allowDots: true });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加请求拦截器
|
// 添加请求拦截器
|
||||||
service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
|
service.interceptors.request.use(
|
||||||
// get查询参数序列化
|
(config: InternalAxiosRequestConfig) => {
|
||||||
if (config.method === 'get') {
|
// get查询参数序列化
|
||||||
// @ts-ignore
|
if (config.method === 'get') {
|
||||||
config.paramsSerializer = (params: any) => {
|
// @ts-ignore
|
||||||
return qs.stringify(params, { arrayFormat: 'repeat' })
|
config.paramsSerializer = (params: any) => {
|
||||||
}
|
return qs.stringify(params, { arrayFormat: 'repeat' });
|
||||||
}
|
};
|
||||||
// 统一增加 token
|
}
|
||||||
const isToken = (config.headers || {}).isToken === false
|
// 统一增加 token
|
||||||
if (Session.get('token') && !isToken) {
|
const isToken = (config.headers || {}).isToken === false;
|
||||||
config.headers!['Authorization'] = `Bearer ${Session.get('token')}`;
|
if (Session.get('token') && !isToken) {
|
||||||
}
|
config.headers!['Authorization'] = `Bearer ${Session.get('token')}`;
|
||||||
|
}
|
||||||
|
|
||||||
// 统一增加租户信息
|
// 统一增加租户信息
|
||||||
if (Local.get('tenantId')) {
|
if (Local.get('tenantId')) {
|
||||||
config.headers!['TENANT-ID'] = Local.get('tenantId');
|
config.headers!['TENANT-ID'] = Local.get('tenantId');
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
// 对请求错误做些什么
|
// 对请求错误做些什么
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// 添加响应拦截器
|
// 添加响应拦截器
|
||||||
service.interceptors.response.use((res: any) => {
|
service.interceptors.response.use(
|
||||||
if (res.data.code === 1) {
|
(res: any) => {
|
||||||
throw res.data
|
if (res.data.code === 1) {
|
||||||
}
|
throw res.data;
|
||||||
return res.data;
|
}
|
||||||
}, error => {
|
return res.data;
|
||||||
const status = Number(error.response.status) || 200
|
},
|
||||||
if (status === 424) {
|
(error) => {
|
||||||
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {
|
console.log(error, 'rrrrr');
|
||||||
confirmButtonText: '重新登录',
|
const status = Number(error.response.status) || 200;
|
||||||
cancelButtonText: '取消',
|
if (status === 424) {
|
||||||
type: 'warning'
|
ElMessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {
|
||||||
})
|
confirmButtonText: '重新登录',
|
||||||
.then(() => {
|
cancelButtonText: '取消',
|
||||||
Session.clear(); // 清除浏览器全部临时缓存
|
type: 'warning',
|
||||||
window.location.href = '/'; // 去登录页
|
}).then(() => {
|
||||||
return
|
Session.clear(); // 清除浏览器全部临时缓存
|
||||||
})
|
window.location.href = '/'; // 去登录页
|
||||||
}
|
return;
|
||||||
|
});
|
||||||
return Promise.reject(error.response.data);
|
}
|
||||||
})
|
return Promise.reject(error.response.data);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 导出 axios 实例
|
// 导出 axios 实例
|
||||||
export default service;
|
export default service;
|
||||||
|
@ -8,18 +8,23 @@ import Cookies from 'js-cookie';
|
|||||||
* @method clear 移除全部永久缓存
|
* @method clear 移除全部永久缓存
|
||||||
*/
|
*/
|
||||||
export const Local = {
|
export const Local = {
|
||||||
|
// 查看 v2.4.3版本更新日志
|
||||||
|
setKey(key: string) {
|
||||||
|
// @ts-ignore
|
||||||
|
return `${__NEXT_NAME__}:${key}`;
|
||||||
|
},
|
||||||
// 设置永久缓存
|
// 设置永久缓存
|
||||||
set(key: string, val: any) {
|
set<T>(key: string, val: T) {
|
||||||
window.localStorage.setItem(key, JSON.stringify(val));
|
window.localStorage.setItem(Local.setKey(key), JSON.stringify(val));
|
||||||
},
|
},
|
||||||
// 获取永久缓存
|
// 获取永久缓存
|
||||||
get(key: string) {
|
get(key: string) {
|
||||||
let json = <string>window.localStorage.getItem(key);
|
let json = <string>window.localStorage.getItem(Local.setKey(key));
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
},
|
},
|
||||||
// 移除永久缓存
|
// 移除永久缓存
|
||||||
remove(key: string) {
|
remove(key: string) {
|
||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(Local.setKey(key));
|
||||||
},
|
},
|
||||||
// 移除全部永久缓存
|
// 移除全部永久缓存
|
||||||
clear() {
|
clear() {
|
||||||
|
@ -1,130 +1,124 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer v-model="visible" :title="$t('personal.name')" size="50%">
|
<el-drawer v-model="visible" :title="$t('personal.name')" size="50%">
|
||||||
<el-tabs style="height: 200px" class="demo-tabs">
|
<el-tabs style="height: 200px" class="demo-tabs">
|
||||||
<el-tab-pane label="基本信息">
|
<el-tab-pane label="基本信息">
|
||||||
<el-card shadow="hover" class="layout-padding-auto">
|
<el-card shadow="hover" class="layout-padding-auto">
|
||||||
<el-form :model="formData" :rules="ruleForm" label-width="100px" class="mt35 mb35" ref="formdataRef">
|
<el-form :model="formData" :rules="ruleForm" label-width="100px" class="mt35 mb35" ref="formdataRef">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="用户名" prop="avatar">
|
<el-form-item label="用户名" prop="avatar">
|
||||||
<image-upload class="h100 personal-user-left-upload" @change="handleAvatarSuccess">
|
<image-upload class="h100 personal-user-left-upload" @change="handleAvatarSuccess">
|
||||||
<img v-if="formData.avatar" :src="formData.avatar" class="avatar" />
|
<img v-if="formData.avatar" :src="formData.avatar" class="avatar" />
|
||||||
<el-icon v-else class="avatar-uploader-icon">
|
<el-icon v-else class="avatar-uploader-icon">
|
||||||
<Plus />
|
<Plus />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</image-upload>
|
</image-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="用户名" prop="username">
|
<el-form-item label="用户名" prop="username">
|
||||||
<el-input v-model="formData.username" clearable disabled></el-input>
|
<el-input v-model="formData.username" clearable disabled></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="手机" prop="phone">
|
<el-form-item label="手机" prop="phone">
|
||||||
<el-input v-model="formData.phone" placeholder="请输入手机" clearable></el-input>
|
<el-input v-model="formData.phone" placeholder="请输入手机" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="邮箱" prop="email">
|
<el-form-item label="邮箱" prop="email">
|
||||||
<el-input v-model="formData.email" placeholder="请输入邮箱" clearable></el-input>
|
<el-input v-model="formData.email" placeholder="请输入邮箱" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="昵称" prop="nickname">
|
<el-form-item label="昵称" prop="nickname">
|
||||||
<el-input v-model="formData.nickname" placeholder="请输入昵称" clearable></el-input>
|
<el-input v-model="formData.nickname" placeholder="请输入昵称" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="姓名" prop="name">
|
<el-form-item label="姓名" prop="name">
|
||||||
<el-input v-model="formData.name" placeholder="请输入姓名" clearable></el-input>
|
<el-input v-model="formData.name" placeholder="请输入姓名" clearable></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item label="社交登录" prop="social" >
|
<el-form-item label="社交登录" prop="social">
|
||||||
<a-row style="display: flex;justify-content: space-between;width: 300px">
|
<el-row style="display: flex; justify-content: space-between; width: 300px">
|
||||||
<div @click="handleClick('wechat')" class="item">
|
<div @click="handleClick('wechat')" class="item">
|
||||||
<SvgIcon name="local-wechat" :size="20"/>
|
<SvgIcon name="local-wechat" :size="20" />
|
||||||
<p class="title">微信</p>
|
<p class="title">微信</p>
|
||||||
</div>
|
</div>
|
||||||
<div @click="handleClick('tencent')" class="item">
|
<div @click="handleClick('tencent')" class="item">
|
||||||
<SvgIcon name="local-qq" :size="20"/>
|
<SvgIcon name="local-qq" :size="20" />
|
||||||
<p class="title">QQ</p>
|
<p class="title">QQ</p>
|
||||||
</div>
|
</div>
|
||||||
<div @click="handleClick('gitee')" class="item">
|
<div @click="handleClick('gitee')" class="item">
|
||||||
<SvgIcon name="local-gitee" :size="20"/>
|
<SvgIcon name="local-gitee" :size="20" />
|
||||||
<p class="title">Gitee</p>
|
<p class="title">Gitee</p>
|
||||||
</div>
|
</div>
|
||||||
<div @click="handleClick('osc')" class="item">
|
<div @click="handleClick('osc')" class="item">
|
||||||
<SvgIcon name="local-oschina" :size="20"/>
|
<SvgIcon name="local-oschina" :size="20" />
|
||||||
<p class="title">开源中国</p>
|
<p class="title">开源中国</p>
|
||||||
</div>
|
</div>
|
||||||
</a-row>
|
</el-row>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :span="24" class="mb20">
|
<el-col :span="24" class="mb20">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="handleSaveUser">
|
<el-button type="primary" @click="handleSaveUser"> 更新个人信息 </el-button>
|
||||||
更新个人信息
|
</el-form-item>
|
||||||
</el-button>
|
</el-col>
|
||||||
</el-form-item>
|
</el-row>
|
||||||
</el-col>
|
</el-form>
|
||||||
</el-row>
|
</el-card>
|
||||||
</el-form>
|
</el-tab-pane>
|
||||||
</el-card>
|
<el-tab-pane label="安全信息">
|
||||||
</el-tab-pane>
|
<el-card shadow="hover" class="layout-padding-auto">
|
||||||
<el-tab-pane label="安全信息">
|
<el-form :model="passwordFormData" :rules="passwordRuleForm" label-width="100px" class="mt35 mb35" ref="passwordFormdataRef">
|
||||||
<el-card shadow="hover" class="layout-padding-auto">
|
<el-row :gutter="20">
|
||||||
<el-form :model="passwordFormData" :rules="passwordRuleForm" label-width="100px" class="mt35 mb35" ref="passwordFormdataRef">
|
<el-col :span="24" class="mb20">
|
||||||
<el-row :gutter="20">
|
<el-form-item label="原密码" prop="password">
|
||||||
<el-col :span="24" class="mb20">
|
<el-input v-model="passwordFormData.password" placeholder="请输入密码" clearable type="password"></el-input>
|
||||||
<el-form-item label="原密码" prop="password">
|
</el-form-item>
|
||||||
<el-input v-model="passwordFormData.password" placeholder="请输入密码" clearable
|
</el-col>
|
||||||
type="password"></el-input>
|
<el-col :span="24" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item label="新密码" prop="newpassword1">
|
||||||
</el-col>
|
<el-input v-model="passwordFormData.newpassword1" clearable type="password"></el-input>
|
||||||
<el-col :span="24" class="mb20">
|
</el-form-item>
|
||||||
<el-form-item label="新密码" prop="newpassword1">
|
</el-col>
|
||||||
<el-input v-model="passwordFormData.newpassword1" clearable type="password"></el-input>
|
<el-col :span="24" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item label="确认密码" prop="newpassword2">
|
||||||
</el-col>
|
<el-input v-model="passwordFormData.newpassword2" clearable type="password"></el-input>
|
||||||
<el-col :span="24" class="mb20">
|
</el-form-item>
|
||||||
<el-form-item label="确认密码" prop="newpassword2">
|
</el-col>
|
||||||
<el-input v-model="passwordFormData.newpassword2" clearable type="password"></el-input>
|
<el-col :span="24" class="mb20">
|
||||||
</el-form-item>
|
<el-form-item>
|
||||||
</el-col>
|
<el-button type="primary" @click="handleChangePassword"> 修改密码 </el-button>
|
||||||
<el-col :span="24" class="mb20">
|
</el-form-item>
|
||||||
<el-form-item>
|
</el-col>
|
||||||
<el-button type="primary" @click="handleChangePassword">
|
</el-row>
|
||||||
修改密码
|
</el-form>
|
||||||
</el-button>
|
</el-card>
|
||||||
</el-form-item>
|
</el-tab-pane>
|
||||||
</el-col>
|
</el-tabs>
|
||||||
</el-row>
|
</el-drawer>
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="personal">
|
<script setup lang="ts" name="personal">
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
import { useUserInfo } from '/@/stores/userInfo';
|
||||||
import { editInfo, password } from '/@/api/admin/user'
|
import { editInfo, password } from '/@/api/admin/user';
|
||||||
import { useMessage } from "/@/hooks/message";
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { rule } from "/@/utils/validate";
|
import { rule } from '/@/utils/validate';
|
||||||
import other from '/@/utils/other';
|
import other from '/@/utils/other';
|
||||||
import {Session} from "/@/utils/storage";
|
import { Session } from '/@/utils/storage';
|
||||||
import { useI18n } from "vue-i18n";
|
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({
|
const formData = reactive({
|
||||||
@ -137,122 +131,124 @@ const formData = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const passwordFormData = reactive({
|
const passwordFormData = reactive({
|
||||||
password: '',
|
password: '',
|
||||||
newpassword1: '',
|
newpassword1: '',
|
||||||
newpassword2: ''
|
newpassword2: '',
|
||||||
})
|
});
|
||||||
|
|
||||||
const formdataRef = ref()
|
const formdataRef = ref();
|
||||||
const passwordFormdataRef = ref()
|
const passwordFormdataRef = ref();
|
||||||
|
|
||||||
const ruleForm = reactive({
|
const ruleForm = reactive({
|
||||||
|
phone: [
|
||||||
phone: [{ required: true, message: "手机号不能为空", trigger: "blur" }, { validator: rule.validatePhone, trigger: 'blur' }],
|
{ required: true, message: '手机号不能为空', trigger: 'blur' },
|
||||||
nickname: [{ required: true, message: "昵称不能为空", trigger: "blur" }],
|
{ validator: rule.validatePhone, trigger: 'blur' },
|
||||||
email: [{ required: true, message: "邮箱不能为空", trigger: "blur" }],
|
],
|
||||||
name: [{ required: true, message: "姓名不能为空", 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){
|
const validatorPassword2 = (rule: any, value: any, callback: any) => {
|
||||||
callback(new Error(t('personal.passwordRule')))
|
if (value !== passwordFormData.newpassword1) {
|
||||||
}else{
|
callback(new Error(t('personal.passwordRule')));
|
||||||
callback()
|
} else {
|
||||||
}
|
callback();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const passwordRuleForm = reactive({
|
const passwordRuleForm = reactive({
|
||||||
password: [{ required: true, message: "密码不能为空", trigger: "blur" }],
|
password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
|
||||||
newpassword1: [{
|
newpassword1: [
|
||||||
min: 6,
|
{
|
||||||
max: 20,
|
min: 6,
|
||||||
message: "用户密码长度必须介于 6 和 20 之间",
|
max: 20,
|
||||||
trigger: "blur"
|
message: '用户密码长度必须介于 6 和 20 之间',
|
||||||
}],
|
trigger: 'blur',
|
||||||
newpassword2: [
|
},
|
||||||
{
|
],
|
||||||
min: 6,
|
newpassword2: [
|
||||||
max: 20,
|
{
|
||||||
message: "用户密码长度必须介于 6 和 20 之间",
|
min: 6,
|
||||||
trigger: "blur"
|
max: 20,
|
||||||
},{ validator: validatorPassword2, trigger: 'blur' }
|
message: '用户密码长度必须介于 6 和 20 之间',
|
||||||
]
|
trigger: 'blur',
|
||||||
})
|
},
|
||||||
|
{ validator: validatorPassword2, trigger: 'blur' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
// 头像上传成功
|
// 头像上传成功
|
||||||
const handleAvatarSuccess = (url: any) => {
|
const handleAvatarSuccess = (url: any) => {
|
||||||
formData.avatar = url;
|
formData.avatar = url;
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleChangePassword = () => {
|
const handleChangePassword = () => {
|
||||||
passwordFormdataRef.value.validate((valid: boolean) => {
|
passwordFormdataRef.value.validate((valid: boolean) => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
password(passwordFormData).then(() => {
|
password(passwordFormData)
|
||||||
useMessage().success("修改成功")
|
.then(() => {
|
||||||
// 需要重新登录
|
useMessage().success('修改成功');
|
||||||
// 清除缓存/token等
|
// 需要重新登录
|
||||||
Session.clear();
|
// 清除缓存/token等
|
||||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
Session.clear();
|
||||||
window.location.reload();
|
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
||||||
}).catch(err => {
|
window.location.reload();
|
||||||
useMessage().error(err.msg)
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
})
|
useMessage().error(err.msg);
|
||||||
}
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 保存用户
|
// 保存用户
|
||||||
const handleSaveUser = () => {
|
const handleSaveUser = () => {
|
||||||
formdataRef.value.validate((valid: boolean) => {
|
formdataRef.value.validate((valid: boolean) => {
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
editInfo(formData).then(() => {
|
editInfo(formData)
|
||||||
useMessage().success("修改成功")
|
.then(() => {
|
||||||
// 更新上下文的 user信息
|
useMessage().success('修改成功');
|
||||||
useUserInfo().setUserInfos()
|
// 更新上下文的 user信息
|
||||||
}).catch(err => {
|
useUserInfo().setUserInfos();
|
||||||
useMessage().error(err.msg)
|
})
|
||||||
})
|
.catch((err) => {
|
||||||
})
|
useMessage().error(err.msg);
|
||||||
|
});
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleClick = (thirdpart: string) => {
|
const handleClick = (thirdpart: string) => {
|
||||||
let appid, client_id, redirect_uri, url;
|
let appid, client_id, redirect_uri, url;
|
||||||
redirect_uri = encodeURIComponent(
|
redirect_uri = encodeURIComponent(window.location.origin + '/#/authredirect');
|
||||||
window.location.origin + "/#/authredirect"
|
if (thirdpart === 'wechat') {
|
||||||
);
|
appid = 'wxd1678d3f83b1d83a';
|
||||||
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`;
|
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") {
|
} else if (thirdpart === 'tencent') {
|
||||||
client_id = "101322838";
|
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}`;
|
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") {
|
} else if (thirdpart === 'gitee') {
|
||||||
client_id = '0c29cfd9cb1e0037fc837521bc08c1a7483d8fd9b3e123d46beec59a5544a881'
|
client_id = '0c29cfd9cb1e0037fc837521bc08c1a7483d8fd9b3e123d46beec59a5544a881';
|
||||||
url = `https://gitee.com/oauth/authorize?response_type=code&state=GITEE-BIND&client_id=${client_id}&redirect_uri=${redirect_uri}`;
|
url = `https://gitee.com/oauth/authorize?response_type=code&state=GITEE-BIND&client_id=${client_id}&redirect_uri=${redirect_uri}`;
|
||||||
} else if (thirdpart === "osc") {
|
} else if (thirdpart === 'osc') {
|
||||||
client_id = "neIIqlwGsjsfsA6uxNqD";
|
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}`;
|
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 = () => {
|
const open = () => {
|
||||||
visible.value = true
|
visible.value = true;
|
||||||
const data = useUserInfo().userInfos
|
const data = useUserInfo().userInfos;
|
||||||
Object.assign(formData, data.user)
|
Object.assign(formData, data.user);
|
||||||
}
|
};
|
||||||
|
|
||||||
// 暴露变量
|
// 暴露变量
|
||||||
defineExpose({
|
defineExpose({
|
||||||
open,
|
open,
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@ -461,9 +457,9 @@ defineExpose({
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item{
|
.item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -90,6 +90,7 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
|
|||||||
__VUE_I18N_FULL_INSTALL__: JSON.stringify(false),
|
__VUE_I18N_FULL_INSTALL__: JSON.stringify(false),
|
||||||
__INTLIFY_PROD_DEVTOOLS__: JSON.stringify(false),
|
__INTLIFY_PROD_DEVTOOLS__: JSON.stringify(false),
|
||||||
__VERSION__: JSON.stringify(process.env.npm_package_version),
|
__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