feat:增加docker部署
This commit is contained in:
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM nginx:1.27.0
|
||||
COPY dist/ /usr/share/nginx/html/
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
RUN echo 'Asia/Shanghai' > /etc/timezone
|
||||
RUN chmod -R 755 /usr/share/nginx/html/
|
||||
25
nginx.conf
Normal file
25
nginx.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
index index.html;
|
||||
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 500M;
|
||||
|
||||
location /study-agent/ {
|
||||
alias /usr/share/nginx/html/;
|
||||
try_files $uri $uri/ /study-agent/index.html;
|
||||
}
|
||||
|
||||
location /study-api/ {
|
||||
proxy_pass http://host.docker.internal:8001/;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,13 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc -b && vite build",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vueup/vue-quill": "^1.5.5",
|
||||
"axios": "^1.18.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.21",
|
||||
"element-plus": "^2.14.3",
|
||||
"filesize": "^11.0.22",
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -14,6 +14,9 @@ importers:
|
||||
axios:
|
||||
specifier: ^1.18.1
|
||||
version: 1.18.1
|
||||
crypto-js:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
dayjs:
|
||||
specifier: ^1.11.21
|
||||
version: 1.11.21
|
||||
@@ -734,6 +737,9 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -2817,6 +2823,8 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
crypto-js@4.2.0: {}
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
@@ -121,6 +121,7 @@ import { QuillEditor } from '@vueup/vue-quill'
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css'
|
||||
import { uploadLibraryFileApi } from '@/apis/library.ts'
|
||||
import { getModuleOptions } from '@/utils/libraryUtil.ts'
|
||||
import { getFileExtension, getFileHashName } from '@/utils/file.ts'
|
||||
|
||||
const libraryStore = useLibraryStore()
|
||||
const libraryFileFormRef = ref<FormInstance>()
|
||||
@@ -166,9 +167,11 @@ const upload = async (options: UploadRequestOptions) => {
|
||||
const { file } = options
|
||||
libraryStore.currentFile.size = file.size
|
||||
libraryStore.currentFile.type = 'image'
|
||||
const fileName = `${getFileHashName(file)}.${getFileExtension(file.name)}`
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('filename', fileName)
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-empty v-if="!filterLibraryFileList.length" description="暂无文件" :image-size="80" />
|
||||
<el-empty v-if="!filterLibraryFileList.length" description="暂无数据"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { usePracticeStore } from '@/stores/practice.ts'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ElLoading, ElMessage } from 'element-plus'
|
||||
|
||||
const practiceStore = usePracticeStore()
|
||||
|
||||
@@ -65,7 +65,20 @@ const submitAnswerClick = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
await practiceStore.checkQuestion()
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '答案提交中 请等待',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
try {
|
||||
await practiceStore.checkQuestion()
|
||||
ElMessage.success('提交成功')
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
ElMessage.error('提交失败 请联系管理员')
|
||||
} finally {
|
||||
loading.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import Layout from '../layout/index.vue'
|
||||
|
||||
const routes = [
|
||||
@@ -42,7 +42,7 @@ const routes = [
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
})
|
||||
|
||||
|
||||
@@ -42,9 +42,12 @@ export const useLibraryStore = defineStore('library', {
|
||||
this.fileList = await queryLibraryFileListApi()
|
||||
this.subjectTree = getSubjectTree(this.fileList)
|
||||
this.subjectOptions = getSubjectOptions(this.subjectTree)
|
||||
this.selectedSubject = this.subjectOptions[0].value
|
||||
this.moduleOptions = getModuleOptions(this.subjectTree, this.selectedSubject)
|
||||
this.selectedModule = this.moduleOptions[0].value
|
||||
|
||||
if (this.subjectOptions.length > 0) {
|
||||
this.selectedSubject = this.subjectOptions[0].value
|
||||
this.moduleOptions = getModuleOptions(this.subjectTree, this.selectedSubject)
|
||||
this.selectedModule = this.moduleOptions[0].value
|
||||
}
|
||||
},
|
||||
async queryFileById(id: number) {
|
||||
this.currentFile = await queryLibraryFileByIdApi(id)
|
||||
|
||||
13
src/utils/file.ts
Normal file
13
src/utils/file.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import * as CryptoJS from 'crypto-js'
|
||||
|
||||
const hashSHA256 = (message: string) => {
|
||||
return CryptoJS.SHA256(message).toString(CryptoJS.enc.Hex)
|
||||
}
|
||||
|
||||
export const getFileHashName = (file: File) => {
|
||||
return hashSHA256(`${file.name}_${file.lastModified}`)
|
||||
}
|
||||
|
||||
export const getFileExtension = (name: string) => {
|
||||
return name.substring(name.lastIndexOf('.') + 1).toLowerCase()
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mistake-record">
|
||||
<div class="mistake-list">
|
||||
<div v-if="mistakeStore.mistakeList.length" class="mistake-list">
|
||||
<el-card
|
||||
v-for="item in mistakeStore.mistakeList"
|
||||
:key="item.id"
|
||||
@@ -30,6 +30,8 @@
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<el-empty v-else description="暂无数据"></el-empty>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<library-filter />
|
||||
<library-filter v-if="libraryStore.fileList.length" />
|
||||
|
||||
<practice-question v-if="practiceStore.hasStart"/>
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ export default defineConfig({
|
||||
}
|
||||
}
|
||||
},
|
||||
base: '/study-agent/',
|
||||
resolve: {
|
||||
// 配置路径别名
|
||||
alias: {
|
||||
|
||||
Reference in New Issue
Block a user