Compare commits

...

6 Commits

Author SHA1 Message Date
C.D.Y
6e3dce010a
Merge fc28dd1111 into 2ddf0449cf 2024-09-22 11:44:59 +00:00
CY-1
fc28dd1111 Merge remote-tracking branch 'origin/dev' into dev
# Conflicts:
#	blossom-editor/src/renderer/src/views/todo/TodoStat.vue
2024-09-22 19:44:08 +08:00
CY-1
6c12ba9a9d 1.完成上传图片/替换图片自动刷新
2.完成todoList改变统计信息改变
2024-09-22 19:42:53 +08:00
C.D.Y
89b13fb7b5
Merge branch 'blossom-editor:dev' into dev 2024-09-22 14:33:37 +08:00
CY-1
2f775287e8 1.完成上传图片/替换图片自动刷新
2.完成todoList改变统计信息改变
2024-09-22 04:22:47 +08:00
Tianjiu
2ddf0449cf
Merge pull request #142 from CY-1/dev
修复代码bug
2024-07-28 16:33:03 +08:00
8 changed files with 193 additions and 44 deletions

View File

@ -164,3 +164,45 @@ export const useConfigStore = defineStore('configStore', {
}
}
})
// 上传文件后通知刷新List
export const onUploadAfter = defineStore('onUploadAfter', {
state: () => ({
response: {
isSuccess: false,
msg: ''
}
}),
actions: {
setResponse(response: { isSuccess: boolean; msg: string }): void {
this.response = response;
}
},
getters: {
getResponse(state) {
return state.response;
}
}
});
// 修改todo状态后 通知刷新统计
export const onTodoChange = defineStore('onTodoChange', {
state: () => ({
response: {
isSuccess: false,
msg: ''
}
}),
actions: {
setResponse(response: { isSuccess: boolean; msg: string }): void {
this.response = response;
}
},
getters: {
getResponse(state) {
return state.response;
}
}
});

View File

@ -199,7 +199,7 @@ import PictureBatchDel from './PictureBatchDel.vue'
import PictureTransfer from './PictureTransfer.vue'
import errorImg from '@renderer/assets/imgs/img_error.png'
import Notify from '@renderer/scripts/notify'
import {onUploadAfter} from '@renderer/stores/config'
const userStore = useUserStore()
useLifecycle(
@ -278,6 +278,16 @@ const clickCurFolder = (tree: DocTree) => {
getPictureStat(curFolder.value.id)
}
/**
* 订阅文件上传通知
*/
const uploadResult = onUploadAfter()
uploadResult.$subscribe((mutation, state)=>{
if(state.response.isSuccess){
refresh()
}
})
/**
* 刷新
*/
@ -423,11 +433,14 @@ const deletePicture = (pic: Picture) => {
pic.delTime = 2
getPictureStat(curFolder.value?.id)
getPictureStat()
// list
refresh()
})
.catch((_) => {
pic.delTime = 0
pic.url = urlBak
})
})
}
@ -524,6 +537,8 @@ const delBatchIgnoreCheck = () => {
}
delIgnoreCheck.value = true
isShowBatchDelDialog.value = true
//
refresh()
}
const deleted = (ids: Array<string>) => {

View File

@ -8,17 +8,18 @@
multiple
:disabled="!curFolder || !curFolder?.id"
:action="serverStore.serverUrl + uploadFileApiUrl"
:data="(f: UploadRawFile) => uploadDate(f, curFolder!.id, porps.repeatUpload)"
:data="(f: UploadRawFile) => uploadDate(f, curFolder!.id, prop.repeatUpload)"
:headers="{ Authorization: 'Bearer ' + userStore.auth.token }"
:show-file-list="true"
:before-upload="beforeUpload"
:on-success="onUploadSeccess"
:on-success="onUploadSuccess"
:on-error="onError">
<bl-row v-if="!curFolder || !curFolder?.id" just="center" align="center" height="100%" style="font-size: 12px"
>请先选择文件夹再上传文件</bl-row
>请先选择文件夹再上传文件
</bl-row
>
<bl-row v-else just="center" align="center" height="100%" style="font-size: 12px">
点击或拖拽上传至<br />
点击或拖拽上传至<br/>
{{ curFolder?.name }}
</bl-row>
</el-upload>
@ -26,15 +27,16 @@
</template>
<script setup lang="ts">
import { inject } from 'vue'
import { UploadRawFile } from 'element-plus'
import { uploadFileApiUrl } from '@renderer/api/blossom'
import { useUserStore } from '@renderer/stores/user'
import { useServerStore } from '@renderer/stores/server'
import { provideKeyDocInfo } from '@renderer/views/doc/doc'
import { beforeUpload, onUploadSeccess, onError, uploadDate } from '@renderer/views/picture/scripts/picture'
import {inject} from 'vue'
import {UploadRawFile} from 'element-plus'
import {uploadFileApiUrl} from '@renderer/api/blossom'
import {useUserStore} from '@renderer/stores/user'
import {useServerStore} from '@renderer/stores/server'
import {provideKeyDocInfo} from '@renderer/views/doc/doc'
import {beforeUpload, onUploadSeccess, onError, uploadDate} from '@renderer/views/picture/scripts/picture'
import {onUploadAfter} from '@renderer/stores/config'
const porps = defineProps({
const prop = defineProps({
repeatUpload: {
type: Boolean,
default: false
@ -48,6 +50,21 @@ const curFolder = inject(provideKeyDocInfo)
const userStore = useUserStore()
const serverStore = useServerStore()
//#endregion
/**
* 上传成功后通知组件刷新
* @param data
*/
const uploadResult = onUploadAfter()
const onUploadSuccess = (resp: any, file: any, fileList: any) => {
uploadResult.setResponse({
isSuccess: true,
msg: "upload success"
})
onUploadSeccess(resp, file, fileList)
}
</script>
<style scoped lang="scss">

View File

@ -81,6 +81,7 @@ import { isNotNull } from '@renderer/assets/utils/obj'
import { isEmpty } from 'lodash'
import { download, writeText } from '@renderer/assets/utils/electron'
import Notify from '@renderer/scripts/notify'
import {onUploadAfter} from '@renderer/stores/config'
const userStore = useUserStore()
const serverStore = useServerStore()
@ -127,7 +128,8 @@ const deletePicture = () => {
})
})
}
//
const uploadResult = onUploadAfter()
/**
* 替换上传成功
*/
@ -137,6 +139,12 @@ const onUploadSeccess: UploadProps['onSuccess'] = (resp, _file?) => {
emits('saved')
closePicInfo()
picCacheRefresh()
//
uploadResult.setResponse({
isSuccess: true,
msg: "upload success"
})
return true
} else {
Notify.error(resp.msg, '图片替换失败')

View File

@ -301,6 +301,7 @@ import { isEmpty } from 'lodash'
import Notify from '@renderer/scripts/notify'
import TaskInfoComponent from './TaskInfo.vue'
import { dayjs, ElMessageBox } from 'element-plus'
import {onTodoChange} from '@renderer/stores/config'
onMounted(() => {
document.addEventListener('dragover', preventDefaultDragover, false)
@ -324,7 +325,19 @@ const countProc = computed<number>(() => taskProcComputed.value.filter((t) => t.
const countComp = computed<number>(() => taskCompComputed.value.filter((t) => t.todoType != 99).length)
const countTotal = computed(() => countWait.value + countProc.value + countComp.value)
// todo status
const onTodoResult = onTodoChange()
//
const publicTodoChangeMsg = () => {
onTodoResult.setResponse({
isSuccess: true,
msg: curTodo.value.todoName
})
}
const taskWaitComputed = computed<TaskInfo[]>(() => {
publicTodoChangeMsg()
if (queryTags.value.length == 0) {
return taskWait.value
}
@ -332,6 +345,7 @@ const taskWaitComputed = computed<TaskInfo[]>(() => {
})
const taskProcComputed = computed<TaskInfo[]>(() => {
publicTodoChangeMsg()
if (queryTags.value.length == 0) {
return taskProc.value
}
@ -339,6 +353,7 @@ const taskProcComputed = computed<TaskInfo[]>(() => {
})
const taskCompComputed = computed<TaskInfo[]>(() => {
publicTodoChangeMsg()
if (queryTags.value.length == 0) {
return taskComp.value
}

View File

@ -16,6 +16,8 @@ import { UniversalTransition } from 'echarts/features'
import { LabelLayout } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import { getPrimaryColor } from '@renderer/scripts/global-theme'
import {onTodoChange} from '@renderer/stores/config'
echarts.use([
TitleComponent,
TooltipComponent,
@ -171,6 +173,22 @@ const reload = (dates: any, rates: any) => {
const windowResize = () => {
chartLineLog.resize()
}
/**
* todoList改变后刷新统计信息
* @param data
*/
const todoChangeResult = onTodoChange()
/**
* 订阅todoList改变
*/
todoChangeResult.$subscribe((mutation, state)=>{
if(state.response.isSuccess){
chartLineLog = echarts.init(ChartLineLogRef.value)
}
})
defineExpose({ reload, windowResize })
</script>

View File

@ -30,7 +30,8 @@
</el-collapse-item>
<el-collapse-item title="阶段性事项" name="2">
<div v-for="phased in todoPhased" class="task-phased" @click="toTask(phased.todoId, phased.todoName, phased.todoType)">
<div v-for="phased in todoPhased" class="task-phased"
@click="toTask(phased.todoId, phased.todoName, phased.todoType)">
<el-input
v-if="phased.updTodoName"
v-model="phased.todoName"
@ -55,7 +56,8 @@
</el-collapse-item>
<el-collapse-item title="阶段性事项 已完成" name="3">
<div v-for="phased in todoPhasedClose" class="task-phased" @click="toTask(phased.todoId, phased.todoName, phased.todoType)">
<div v-for="phased in todoPhasedClose" class="task-phased"
@click="toTask(phased.todoId, phased.todoName, phased.todoType)">
<div class="phased-stat">{{ phased.taskCountStat }}</div>
<div class="phase-name">{{ phased.todoName }}</div>
</div>
@ -75,23 +77,24 @@
</template>
<script setup lang="ts">
import { useConfigStore } from '@renderer/stores/config'
import { nextTick, ref } from 'vue'
import type { CalendarDateType, CalendarInstance } from 'element-plus'
import { TodoList, TodoType } from './scripts/types'
import { todosApi, addPhasedApi, updTodoNameApi } from '@renderer/api/todo'
import { isNotBlank } from '@renderer/assets/utils/obj'
import { getDateFormat } from '@renderer/assets/utils/util'
import { useLifecycle } from '@renderer/scripts/lifecycle'
import {useConfigStore} from '@renderer/stores/config'
import {nextTick, ref} from 'vue'
import type {CalendarDateType, CalendarInstance} from 'element-plus'
import {TodoList, TodoType} from './scripts/types'
import {todoStatApi, todosApi, addPhasedApi, updTodoNameApi} from '@renderer/api/todo'
import {isNotBlank} from '@renderer/assets/utils/obj'
import {getDateFormat} from '@renderer/assets/utils/util'
import {useLifecycle} from '@renderer/scripts/lifecycle'
import TaskProgress from './TaskProgress.vue'
import TodoStat from './TodoStat.vue'
const { viewStyle } = useConfigStore()
const {viewStyle} = useConfigStore()
useLifecycle(
() => {
getTodos()
let today = getDateFormat()
currentDate.value = today
toTask(today, today, 10)
},
() => {
@ -108,6 +111,13 @@ const selectDate = (val: CalendarDateType) => {
//#endregion
//
const currentDate = ref()
const refreshTodoStat = () => {
if (!CalendarRef.value) return
TodoStatRef.value.reload(currentDate.value)
}
//
const TaskProgressRef = ref()
const TodoStatRef = ref()
@ -129,6 +139,7 @@ const getTodos = () => {
taskCountStat: '0|0|0',
updTodoName: false
})
refreshTodoStat()
}
todoPhased.value = resp.data.taskPhased
todoPhasedClose.value = resp.data.taskPhasedClose
@ -146,6 +157,7 @@ const getCount = (day: string): number => {
if (!todoDayMaps.value.has(day)) {
return 0
}
currentDate.value = day
return todoDayMaps.value.get(day)!.taskCount
}
@ -179,7 +191,7 @@ const showPhasedAddHandle = () => {
const blurPhasedAddHandle = () => {
showPhasedAdd.value = false
if (isNotBlank(phasedAddName.value)) {
addPhasedApi({ todoName: phasedAddName.value }).then((_) => {
addPhasedApi({todoName: phasedAddName.value}).then((_) => {
getTodos()
})
}
@ -207,7 +219,7 @@ const blurPhasedUpdHandle = (todoId: string) => {
let todo = todoPhased.value[index]
if (todo.todoId === todoId) {
todo.updTodoName = false
updTodoNameApi({ todoId: todoId, todoName: todo.todoName })
updTodoNameApi({todoId: todoId, todoName: todo.todoName})
break
}
}
@ -264,20 +276,19 @@ const blurPhasedUpdHandle = (todoId: string) => {
}
:deep(.el-collapse-item__content) {
box-shadow:
inset -1px 3px 5px #dfdfdf,
inset -1px -3px 5px #dfdfdf;
box-shadow: inset -1px 3px 5px #dfdfdf,
inset -1px -3px 5px #dfdfdf;
height: calc(100% - #{$item-height});
padding: 0 5px 0 15px;
overflow-x: hidden;
overflow-y: scroll;
[class='dark'] & {
box-shadow:
inset -1px 3px 5px #0f0f0f,
inset -1px -3px 5px #0f0f0f;
box-shadow: inset -1px 3px 5px #0f0f0f,
inset -1px -3px 5px #0f0f0f;
}
}
.collapse-item {
:deep(.el-collapse-item__content) {
padding: 0;
@ -296,9 +307,11 @@ const blurPhasedUpdHandle = (todoId: string) => {
:deep(.el-calendar__body) {
padding: 0;
th {
padding: 6px 0;
}
.el-calendar-table__row {
.prev,
.current,
@ -306,14 +319,17 @@ const blurPhasedUpdHandle = (todoId: string) => {
.el-calendar-day {
padding: 0;
height: 50px;
.cell-wrapper {
@include box(100%, 100%);
.day {
@include font(14px, 300);
text-align: center;
}
}
}
&:last-child {
border-right: none;
}
@ -346,9 +362,8 @@ const blurPhasedUpdHandle = (todoId: string) => {
border-radius: 3px;
position: relative;
overflow: hidden;
transition:
box-shadow 0.3s,
border-color 0.3s;
transition: box-shadow 0.3s,
border-color 0.3s;
cursor: pointer;
&:hover {

View File

@ -53,16 +53,34 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { todoStatApi, taskStatApi, completedTodoApi, openTodoApi } from '@renderer/api/todo'
import {ref} from 'vue'
import {todoStatApi, taskStatApi, completedTodoApi, openTodoApi} from '@renderer/api/todo'
import TodoChartCompleted from './TodoChartCompleted.vue'
import { useLifecycle } from '@renderer/scripts/lifecycle'
import {useLifecycle} from '@renderer/scripts/lifecycle'
import {onTodoChange} from '@renderer/stores/config'
import {getDateFormat} from '@renderer/assets/utils/util'
useLifecycle(
() => getTaskStat(),
() => getTaskStat()
)
/**
* todoList改变后刷新统计信息
* @param data
*/
const todoChangeResult = onTodoChange()
/**
* 订阅todoList改变
*/
todoChangeResult.$subscribe((mutation, state) => {
if (state.response.isSuccess) {
getTaskStat()
}
})
//
const getTaskStat = () => {
taskStatApi().then((resp) => {
taskStat.value = {
@ -72,6 +90,7 @@ const getTaskStat = () => {
total: resp.data.total
}
TodoChartCompletedRef.value.reload(resp.data.dates, resp.data.rates)
})
}
@ -84,13 +103,13 @@ const taskStat = ref({
})
const openTodo = () => {
openTodoApi({ todoId: todoStat.value.todoId }).then((_resp) => {
openTodoApi({todoId: todoStat.value.todoId}).then((_resp) => {
emits('refreshTodo')
})
}
const completedTodo = () => {
completedTodoApi({ todoId: todoStat.value.todoId }).then((_resp) => {
completedTodoApi({todoId: todoStat.value.todoId}).then((_resp) => {
emits('refreshTodo')
})
}
@ -106,12 +125,12 @@ const todoStat = ref({
})
const reload = (todoId: string) => {
todoStatApi({ todoId: todoId }).then((resp) => {
todoStatApi({todoId: todoId}).then((resp) => {
todoStat.value = resp.data
})
}
defineExpose({ reload })
defineExpose({reload})
const emits = defineEmits(['refreshTodo'])
</script>