modifySet.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <a-modal
  3. v-model:visible="visible"
  4. :width="560"
  5. title-align="start"
  6. top="10px"
  7. :align-center="false"
  8. :mask-closable="false"
  9. :esc-to-close="false"
  10. @before-open="modalBeforeOpen"
  11. >
  12. <template #title> 下载设置 </template>
  13. <a-form ref="formRef" :model="formData" :rules="rules" auto-label-width>
  14. <a-form-item field="pictureType" label="下载文件">
  15. <a-checkbox-group v-model="formData.pictureType" direction="vertical">
  16. <template v-for="(option, index) in pictureOptions" :key="index">
  17. <a-checkbox :value="option.value">
  18. {{ option.label }}
  19. </a-checkbox>
  20. <div class="tips-info" style="padding-left: 27px">
  21. {{ pictureDesc[option.value as PictureTypeEnum] }}
  22. </div>
  23. </template>
  24. </a-checkbox-group>
  25. </a-form-item>
  26. <a-form-item field="outputDir" label="保存目录" :content-flex="false">
  27. <a-input-search
  28. v-model.trim="formData.outputDir"
  29. :style="{ width: '420px' }"
  30. readonly
  31. search-button
  32. button-text="浏览"
  33. @search="toSelectDir"
  34. >
  35. </a-input-search>
  36. <a-checkbox
  37. v-model="formData.outputDirIsDefault"
  38. :style="{ marginTop: '5px' }"
  39. >设为默认下载路径</a-checkbox
  40. >
  41. </a-form-item>
  42. <a-form-item field="trackColorType" label="轨迹颜色">
  43. <a-radio-group v-model="formData.trackColorType">
  44. <a-radio
  45. v-for="(val, key) in TRACK_COLOR_TYPE"
  46. :key="key"
  47. :value="key"
  48. >{{ val }}</a-radio
  49. >
  50. </a-radio-group>
  51. </a-form-item>
  52. <a-form-item field="studentFileRule" label="文件名规则">
  53. <a-radio-group v-model="formData.studentFileRule">
  54. <a-radio
  55. v-for="(val, key) in STUDENT_FILE_RULE"
  56. :key="key"
  57. :value="key"
  58. >{{ val }}</a-radio
  59. >
  60. </a-radio-group>
  61. </a-form-item>
  62. </a-form>
  63. <template #footer>
  64. <a-button @click="close">取消</a-button>
  65. <a-button type="primary" :disabled="loading" @click="confirm"
  66. >确认</a-button
  67. >
  68. </template>
  69. </a-modal>
  70. </template>
  71. <script setup lang="ts">
  72. import { nextTick, reactive, ref } from 'vue';
  73. import { Message } from '@arco-design/web-vue';
  74. import type { FormInstance } from '@arco-design/web-vue/es/form';
  75. import useLoading from '@/hooks/loading';
  76. import useModal from '@/hooks/modal';
  77. import { objAssign, objModifyAssign } from '@/utils/utils';
  78. import { FormRules } from '@/types/global';
  79. import useDictOption from '@/hooks/dict-option';
  80. import { useAppStore } from '@/store';
  81. import { TrackConfigType } from '@/store/modules/app/types';
  82. import {
  83. PictureTypeEnum,
  84. TRACK_COLOR_TYPE,
  85. TrackColorTypeEnum,
  86. STUDENT_FILE_RULE,
  87. StudentFileRuleEnum,
  88. } from '@/constants/enumerate';
  89. defineOptions({
  90. name: 'ModifySet',
  91. });
  92. /* modal */
  93. const { visible, open, close } = useModal();
  94. defineExpose({ open, close });
  95. const appStore = useAppStore();
  96. const { optionList: pictureOptions } = useDictOption('PICTURE_TYPE');
  97. const pictureDesc: Record<PictureTypeEnum, string> = {
  98. track: '批阅后图片',
  99. origin: '学生作答原图',
  100. pdf: '将学生批阅后的图片合并成一个PDF,一个学生一个PDF',
  101. };
  102. const defaultFormData = {
  103. pictureType: ['track'] as PictureTypeEnum[],
  104. outputDir: '',
  105. curOutputDir: '',
  106. outputDirIsDefault: true,
  107. trackColorType: 'DEFAULT' as TrackColorTypeEnum,
  108. studentFileRule: 'CODE' as StudentFileRuleEnum,
  109. };
  110. const emit = defineEmits(['modified']);
  111. const formRef = ref<FormInstance>();
  112. const formData = reactive<TrackConfigType>({ ...defaultFormData });
  113. const rules: FormRules<keyof TrackConfigType> = {
  114. pictureType: [
  115. {
  116. required: true,
  117. message: '请选择图片类型',
  118. },
  119. ],
  120. outputDir: [
  121. {
  122. required: true,
  123. message: '请选择保存目录',
  124. },
  125. ],
  126. };
  127. async function toSelectDir() {
  128. const result = await window.electron.dialogSelectFile({
  129. title: '选择保存目录',
  130. properties: ['openDirectory'],
  131. });
  132. if (result.canceled) return;
  133. formData.outputDir = result.filePaths[0];
  134. formRef.value?.validateField('outputDir');
  135. }
  136. /* confirm */
  137. const { loading, setLoading } = useLoading();
  138. async function confirm() {
  139. const err = await formRef.value?.validate();
  140. if (err) return;
  141. setLoading(true);
  142. const datas = objAssign(formData, {});
  143. if (datas.outputDirIsDefault) datas.curOutputDir = datas.outputDir;
  144. let res = true;
  145. await window.db
  146. .updateDict({ key: 'trackConfig', val: JSON.stringify(datas) })
  147. .catch(() => {
  148. res = false;
  149. });
  150. setLoading(false);
  151. if (!res) return;
  152. appStore.setInfo({ trackConfig: datas });
  153. Message.success('修改成功!');
  154. emit('modified', datas);
  155. close();
  156. }
  157. /* init modal */
  158. async function modalBeforeOpen() {
  159. const res = await window.db.getDict('trackConfig');
  160. if (res) {
  161. const config = JSON.parse(res);
  162. objModifyAssign(formData, config);
  163. } else {
  164. objModifyAssign(formData, defaultFormData);
  165. }
  166. nextTick(() => {
  167. formRef.value?.clearValidate();
  168. });
  169. }
  170. </script>