Merge branch 'main' into zhuhao_dev

This commit is contained in:
朱浩 2024-07-18 15:17:45 +08:00
commit e8d48d8bd9
13 changed files with 127 additions and 51 deletions

15
.env.production Normal file
View File

@ -0,0 +1,15 @@
# 页面标题
VITE_APP_TITLE = AIx数字平台
# 生产环境配置
VITE_APP_ENV = 'production'
# AIx融合数字管理系统/生产环境
VITE_APP_BASE_API = 'http://192.168.2.52:7863'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
VITE_APP_RES_FILE_PATH = 'https://prev.ysaix.com:7868/src/assets/textbook/booktxt/'
VITE_APP_BUILD_BASE_PATH = 'https://prev.ysaix.com:7868/'

View File

@ -59,10 +59,72 @@ $ npm run build:linux
├── .prettierrc.yaml //prettier代码格式化配置文件 ├── .prettierrc.yaml //prettier代码格式化配置文件
├── dev-app-update.yml ├── dev-app-update.yml
├── electron-builder.yml //打包配置文件 ├── electron-builder.yml //打包配置文件
├──electron.vite.config.mjs //electron-vite配置文件 ├── electron.vite.config.mjs //electron-vite配置文件
├── package-lock.json ├── package-lock.json
├── package.json ├── package.json
└──README.md //项目说明 └── README.md //项目说明
``` ```
### electron-builder.yml配置说明
```json
appId: com.electron.test //appid 包名
productName: 测试程序 //安装程序的名字
directories:
buildResources: build
files:
- '!**/.vscode/*'
- '!src/*'
- '!electron.vite.config.{js,ts,mjs,cjs}'
- '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}'
- '!{.env,.env.*,.npmrc,pnpm-lock.yaml}'
- '!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}'
asarUnpack:
- resources
win:
executableName: 测试程序
icon: build/icon/favicon.ico //程序图标
nsis:
oneClick: false //是否一键安装
allowElevation: true //允许请求提升。若为false则用户必须使用提升的权限重新启动安装程序。
allowToChangeInstallationDirectory: true //是否允许修改安装目录
createDesktopShortcut: true //卸载时图标
createStartMenuShortcut: true // 是否创建开始菜单图标
runAfterFinish: false //是否安装完成后运行
include: ../build/script/installer.nsh //我这里放的是将应用程序默认安装在哪个路径
artifactName: ${name}-${version}-setup.${ext}
uninstallDisplayName: ${productName}
installerIcon: ./build/icon.ico // 安装时图标
uninstallerIcon: ./build/icon.ico
mac:
entitlementsInherit: build/entitlements.mac.plist
extendInfo:
- NSCameraUsageDescription: Application requests access to the device's camera.
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
notarize: false
dmg:
artifactName: ${name}-${version}.${ext}
linux:
target:
- AppImage
- snap
- deb
maintainer: electronjs.org
category: Utility
appImage:
artifactName: ${name}-${version}.${ext}
npmRebuild: false
publish:
provider: generic
url: https://example.com/auto-updates //程序升级的验证地址
electronDownload:
mirror: https://npmmirror.com/mirrors/electron/
```

View File

@ -1,5 +1,5 @@
appId: com.electron.app appId: com.electron.app
productName: electron-app productName: AIx
directories: directories:
buildResources: build buildResources: build
files: files:
@ -11,7 +11,7 @@ files:
asarUnpack: asarUnpack:
- resources/** - resources/**
win: win:
executableName: electron-app executableName: AIx
nsis: nsis:
oneClick: false oneClick: false
allowToChangeInstallationDirectory: true allowToChangeInstallationDirectory: true

View File

@ -34,6 +34,9 @@ export function getUserProfile() {
export function uploadAvatar(data) { export function uploadAvatar(data) {
return request({ return request({
url: '/system/user/profile/avatar', url: '/system/user/profile/avatar',
headers: {
'Content-Type': 'multipart/form-data'
},
method: 'post', method: 'post',
data: data data: data
}) })

View File

@ -1,13 +0,0 @@
<script setup>
import { reactive } from 'vue'
const versions = reactive({ ...window.electron.process.versions })
</script>
<template>
<ul class="versions">
<li class="electron-version">Electron v{{ versions.electron }}</li>
<li class="chrome-version">Chromium v{{ versions.chrome }}</li>
<li class="node-version">Node v{{ versions.node }}</li>
</ul>
</template>

View File

@ -54,7 +54,7 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, toRaw, onMounted, nextTick, watch, defineProps, defineEmits } from 'vue' import { ref, reactive, toRaw, onMounted, nextTick, watch } from 'vue'
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {

View File

@ -33,7 +33,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, watch, defineProps, defineEmits } from 'vue' import { ref, onMounted, watch } from 'vue'
import { listEvaluation } from '@/api/subject' import { listEvaluation } from '@/api/subject'
import { updateUserInfo } from '@/api/system/user' import { updateUserInfo } from '@/api/system/user'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'

View File

@ -45,7 +45,7 @@
</template> </template>
<script setup> <script setup>
import { ref, defineProps, defineEmits, watch } from 'vue' import { ref, watch } from 'vue'
import FileImage from '@/components/file-image/index.vue' import FileImage from '@/components/file-image/index.vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { resourceType } from '@/utils/resourceDict' import { resourceType } from '@/utils/resourceDict'

View File

@ -18,13 +18,13 @@
<span title="最小化" @click="minimizeWindow"><i class="iconfont">&#xe650;</i></span> <span title="最小化" @click="minimizeWindow"><i class="iconfont">&#xe650;</i></span>
<span :title="isMaxSize ? '向下还原' : '最大化'" @click="maximizeWindow"><i class="iconfont">{{ isMaxSize ? '&#xe600' : <span :title="isMaxSize ? '向下还原' : '最大化'" @click="maximizeWindow"><i class="iconfont">{{ isMaxSize ? '&#xe600' :
'&#xe695' }}</i></span> '&#xe695' }}</i></span>
<span title="关闭" @click="closeWindow"><i class="iconfont">&#xe608;</i></span> <span class="close" title="关闭" @click="closeWindow"><i class="iconfont">&#xe608;</i></span>
</div> </div>
<div class="user flex"> <div class="user flex">
<div class="avatar-container"> <div class="avatar-container">
<el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click"> <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper"> <div class="avatar-wrapper">
<img :src="userStore.user.avatar" class="user-avatar" style="float: left;" /> <img :src="userImg" class="user-avatar" style="float: left;" />
<div style="margin-top: 18px; font-size: 0.8em;"> {{ userStore.user.nickName }}</div> <div style="margin-top: 18px; font-size: 0.8em;"> {{ userStore.user.nickName }}</div>
</div> </div>
<template #dropdown> <template #dropdown>
@ -54,7 +54,7 @@ const { ipcRenderer } = window.electron || {}
const isMaxSize = ref(false) const isMaxSize = ref(false)
const router = useRouter() const router = useRouter()
const currentRoute = ref('') const currentRoute = ref('')
const userImg = new URL(userStore.user.avatar, import.meta.url)
const menus = ref([ const menus = ref([
{ {
@ -209,19 +209,21 @@ function setLayout() {
flex-direction: column; flex-direction: column;
.header-tool { .header-tool {
padding-top: 5px;
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
span { span {
border-radius: 3px; border-radius: 3px;
cursor: pointer; cursor: pointer;
padding: 2px 10px;
&:hover { &:hover {
background-color: #c4c4c4; background-color: #c4c4c4;
} }
}
.iconfont { .close{
margin: 0 10px; &:hover{
background-color: #fb4a3e;
.iconfont{
color: #fff;
}
} }
} }
} }

View File

@ -3,13 +3,13 @@ import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token' const TokenKey = 'Admin-Token'
export function getToken() { export function getToken() {
return Cookies.get(TokenKey) return localStorage.getItem(TokenKey)
} }
export function setToken(token) { export function setToken(token) {
return Cookies.set(TokenKey, token) return localStorage.setItem(TokenKey, token)
} }
export function removeToken() { export function removeToken() {
return Cookies.remove(TokenKey) return localStorage.removeItem(TokenKey)
} }

View File

@ -55,7 +55,7 @@ service.interceptors.request.use(config => {
const s_url = sessionObj.url; // 请求地址 const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据 const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间 const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 const interval = 2000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交'; const message = '数据正在处理,请勿重复提交';
console.warn(`[${s_url}]: ` + message) console.warn(`[${s_url}]: ` + message)

View File

@ -26,7 +26,7 @@
</el-col> </el-col>
<el-col :xs="24" :md="12" :style="{ height: '350px' }"> <el-col :xs="24" :md="12" :style="{ height: '350px' }">
<div class="avatar-upload-preview"> <div class="avatar-upload-preview">
<img :src="options.previews.url" :style="options.previews.img" /> <el-image style="width: 100px; height: 100px" :src="options.previews.url" :style="options.previews.img"/>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -72,6 +72,7 @@ import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper' import { VueCropper } from 'vue-cropper'
import { uploadAvatar } from '@/api/system/user' import { uploadAvatar } from '@/api/system/user'
import useUserStore from '@/store/modules/user' import useUserStore from '@/store/modules/user'
import { ElMessage } from 'element-plus'
const userStore = useUserStore() const userStore = useUserStore()
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
@ -117,7 +118,10 @@ function changeScale(num) {
/** 上传预处理 */ /** 上传预处理 */
function beforeUpload(file) { function beforeUpload(file) {
if (file.type.indexOf('image/') == -1) { if (file.type.indexOf('image/') == -1) {
proxy.$modal.msgError('文件格式错误,请上传图片类型,如JPGPNG后缀的文件。') ElMessage({
message: '文件格式错误,请上传图片类型,如JPGPNG后缀的文件。',
type: 'error',
})
} else { } else {
const reader = new FileReader() const reader = new FileReader()
reader.readAsDataURL(file) reader.readAsDataURL(file)
@ -135,7 +139,10 @@ function uploadImg() {
open.value = false open.value = false
options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl
userStore.avatar = options.img userStore.avatar = options.img
proxy.$modal.msgSuccess('修改成功') ElMessage({
message: '上传成功',
type: 'success',
})
visible.value = false visible.value = false
}) })
}) })

View File

@ -11,16 +11,16 @@
</el-form-item> </el-form-item>
<el-form-item label="性别"> <el-form-item label="性别">
<el-radio-group v-model="user.sex"> <el-radio-group v-model="user.sex">
<el-radio label="0"></el-radio> <el-radio value="0"></el-radio>
<el-radio label="1"></el-radio> <el-radio value="1"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="任教学科"> <el-form-item label="任教学科">
<el-radio-group v-model="user.edusubject"> <el-radio-group v-model="user.edusubject">
<template v-for="item in subjectList"> <template v-for="(item,index) in subjectList" :key="index">
<el-radio v-if="item.edustage == user.edustage" :label="item.itemtitle">{{ <el-radio v-if="item.edustage == user.edustage" :value="item.itemtitle">
item.itemtitle {{item.itemtitle }}
}}</el-radio> </el-radio>
</template> </template>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>