x1ongzhu 1 rok temu
rodzic
commit
eccd275ba7
4 zmienionych plików z 207 dodań i 28 usunięć
  1. 7 0
      src/api/index.ts
  2. 22 0
      src/utils/request/index.ts
  3. 177 27
      src/views/page/PaperGen.vue
  4. 1 1
      yarn.lock

+ 7 - 0
src/api/index.ts

@@ -250,6 +250,13 @@ export function fetchPaperResults<T>(data: any) {
     })
 }
 
+export function fetchPaperAttachments<T>(data: any) {
+    return post<T>({
+        url: '/paper/attachments',
+        data
+    })
+}
+
 export function fetchCreatePaperOrder<T>(data: any) {
     return put<T>({
         url: '/paper/orders',

+ 22 - 0
src/utils/request/index.ts

@@ -114,6 +114,28 @@ export function put<T = any>({
     })
 }
 
+export function del<T = any>({
+    url,
+    data,
+    method = 'delete',
+    headers,
+    onDownloadProgress,
+    signal,
+    beforeRequest,
+    afterRequest
+}: HttpOption): Promise<T> {
+    return http<T>({
+        url,
+        method,
+        data,
+        headers,
+        onDownloadProgress,
+        signal,
+        beforeRequest,
+        afterRequest
+    })
+}
+
 export function patch<T = any>({
     url,
     data,

+ 177 - 27
src/views/page/PaperGen.vue

@@ -45,8 +45,18 @@
         </NLayoutContent>
     </NLayout>
     <n-modal v-model:show="showModal">
-        <n-card style="width: 800px" title="生成结果" :bordered="false" size="huge" role="dialog" aria-modal="true">
+        <n-card style="width: 800px" :bordered="false" role="dialog" aria-modal="true">
+            <NSpace class="mb-4 flex items-center">
+                <n-radio-group v-model:value="showResultType" name="radiobuttongroup2" size="small">
+                    <n-radio-button value="doc"> 生成结果 </n-radio-button>
+                    <n-radio-button value="attachment"> 附件 </n-radio-button>
+                </n-radio-group>
+                <NUpload :action="uploadUrl" :headers="uploadHeaders" :show-file-list="false" @finish="onUploaded">
+                    <NButton size="small" type="primary">上传附件</NButton>
+                </NUpload>
+            </NSpace>
             <n-data-table
+                v-if="showResultType === 'doc'"
                 remote
                 :columns="resultColumns"
                 :data="resultData"
@@ -55,6 +65,16 @@
                 @update:page="getResults"
                 @update:page-size="getResults"
             />
+            <n-data-table
+                v-else
+                remote
+                :columns="attachmentColumns"
+                :data="attachmentData"
+                :pagination="attachmentsPagination"
+                :bordered="false"
+                @update:page="getAttachments"
+                @update:page-size="getAttachments"
+            />
         </n-card>
     </n-modal>
     <n-modal v-model:show="showForm" :mask-closable="false">
@@ -120,7 +140,7 @@
                     <NInput v-model:value="model.paymentMethod" />
                 </NFormItem>
                 <NFormItem label="是否结稿费" path="paymentStatus">
-                    <NInput v-model:value="model.paymentStatus" />
+                    <NCheckbox v-model:checked="model.paymentStatus">已结</NCheckbox>
                 </NFormItem>
                 <div class="w-3/4"></div>
                 <NFormItem style="width: calc(100% - 18px)" label="备注" path="remark">
@@ -202,7 +222,7 @@
     </n-modal>
 </template>
 <script lang="ts" setup>
-import { h, defineComponent, ref, reactive, onMounted, Ref, computed } from 'vue'
+import { h, defineComponent, ref, reactive, onMounted, Ref, computed, VNode } from 'vue'
 import {
     NButton,
     NDataTable,
@@ -230,17 +250,26 @@ import {
     NSelect,
     NCheckbox,
     NRadio,
-    NDatePicker
+    NDatePicker,
+    NRadioGroup,
+    NRadioButton,
+    NIcon,
+    NUpload,
+    UploadFileInfo,
+    DropdownOption,
+    DropdownGroupOption
 } from 'naive-ui'
 import {
     fetchPaperOrders,
     fetchGenPaper,
     fetchPaperResults,
+    fetchPaperAttachments,
     fetchCreatePaperOrder,
     fetchUpdatePaperOrder,
     fetchGenChapters,
     fetchSearchReference
 } from '@/api'
+import { post, put, del } from '@/utils/request'
 import { format, parseISO } from 'date-fns'
 import { UserAvatar } from '@/components/common'
 import { LoginForm } from '@/components/common'
@@ -257,6 +286,9 @@ import OutlineEditor from '@/components/common/OutlineEditor.vue'
 import { useRouter } from 'vue-router'
 import { useClipboard } from '@vueuse/core'
 import { copyText } from '@/utils/format'
+import { Dots } from '@vicons/tabler'
+import resolveUrl from 'resolve-url'
+import { useAuthStore } from '@/store'
 const router = useRouter()
 const message = useMessage()
 const showLogin = ref(false)
@@ -375,15 +407,16 @@ const columns: DataTableColumn[] = [
         width: 180
     },
     {
-        title: '标题',
-        key: 'title'
+        title: '接单渠道',
+        key: 'orderChannel'
     },
     {
-        title: '描述',
-        key: 'description',
-        ellipsis: {
-            tooltip: true
-        }
+        title: '订单号',
+        key: 'orderNumber'
+    },
+    {
+        title: '标题',
+        key: 'title'
     },
     {
         title: '备注',
@@ -443,18 +476,16 @@ const columns: DataTableColumn[] = [
                     },
                     { default: () => '查看' }
                 ),
-                roles.value.includes('paperGen')
-                    ? h(
-                          NButton,
-                          {
-                              strong: true,
-                              tertiary: true,
-                              size: 'small',
-                              onClick: () => editRow(row)
-                          },
-                          { default: () => '编辑' }
-                      )
-                    : null
+                h(
+                    NButton,
+                    {
+                        strong: true,
+                        tertiary: true,
+                        size: 'small',
+                        onClick: () => editRow(row)
+                    },
+                    { default: () => '编辑' }
+                )
             ])
         }
     }
@@ -530,7 +561,9 @@ async function gen() {
 
 const orderId = ref<any>(null)
 const showModal = ref(false)
+const showResultType = ref('doc')
 const resultData = ref([])
+const attachmentData = ref([])
 const resultsPagination = reactive({
     page: 1,
     pageSize: 10,
@@ -545,11 +578,26 @@ const resultsPagination = reactive({
         resultsPagination.page = 1
     }
 })
+const attachmentsPagination = reactive({
+    page: 1,
+    pageSize: 10,
+    showSizePicker: false,
+    pageSizes: [10],
+    pageCount: 1,
+    onChange: (page: number) => {
+        attachmentsPagination.page = page
+    },
+    onUpdatePageSize: (pageSize: number) => {
+        attachmentsPagination.pageSize = pageSize
+        attachmentsPagination.page = 1
+    }
+})
 async function showResults(row: any) {
     orderId.value = row.id
     showModal.value = true
     resultData.value = []
     getResults()
+    getAttachments()
 }
 function getResults() {
     fetchPaperResults({
@@ -571,6 +619,26 @@ function getResults() {
         resultsPagination.pageCount = res.meta.totalPages
     })
 }
+function getAttachments() {
+    fetchPaperAttachments({
+        page: {
+            page: attachmentsPagination.page,
+            limit: attachmentsPagination.pageSize
+        },
+        search: {
+            order: {
+                createdAt: 'desc'
+            },
+            where: {
+                orderId: orderId.value
+            }
+        }
+    }).then((res: any) => {
+        console.log(res)
+        attachmentData.value = res.items
+        attachmentsPagination.pageCount = res.meta.totalPages
+    })
+}
 const resultColumns: DataTableColumn[] = [
     { title: '#', key: 'id' },
     { title: '生成时间', key: 'createdAt', render: timeFormatter },
@@ -636,6 +704,69 @@ const resultColumns: DataTableColumn[] = [
         }
     }
 ]
+const attachmentColumns: DataTableColumn[] = [
+    { title: '#', key: 'id' },
+    { title: '上传时间', key: 'createdAt', render: timeFormatter },
+    { title: '文件名', key: 'name' },
+    {
+        title: '操作',
+        key: 'action',
+        align: 'center',
+        width: '150px',
+        render(row: any) {
+            return h(
+                NDropdown,
+                {
+                    size: 'small',
+                    options: [
+                        {
+                            label: '下载',
+                            key: 'download'
+                        },
+                        {
+                            label: '删除',
+                            key: 'delete'
+                        }
+                    ],
+                    trigger: 'click',
+                    renderLabel: (option: DropdownOption) =>
+                        option.key === 'delete'
+                            ? h('span', { style: 'color: red' }, option.label as string)
+                            : h('span', {}, option.label as string),
+                    onSelect(key: string | number) {
+                        console.log(key)
+                        if (key === 'delete') {
+                            dialog.warning({
+                                title: 'Confirm',
+                                content: '确认删除?',
+                                positiveText: '确认',
+                                negativeText: '取消',
+                                onPositiveClick: async () => {
+                                    await del({
+                                        url: `/paper/attachments/${row.id}`
+                                    })
+                                    getAttachments()
+                                },
+                                onNegativeClick: () => {}
+                            })
+                        } else if (key === 'download') {
+                            const link = document.createElement('a')
+                            link.href = row.url
+                            link.download = encodeURIComponent(row.name)
+                            console.log(row.name)
+                            link.click()
+                        }
+                    }
+                },
+                () =>
+                    h(NButton, {
+                        size: 'small',
+                        renderIcon: () => h(NIcon, null, () => h(Dots))
+                    })
+            )
+        }
+    }
+]
 
 const showForm = ref(false)
 const genForm: Ref<FormInst | null> = ref(null)
@@ -699,10 +830,7 @@ async function submit(gen = false) {
 }
 function editRow(row: any) {
     model.value = {
-        major: row.major,
-        title: row.title,
-        description: row.description,
-        remark: row.remark,
+        ...row,
         chapters: row.chapters || []
     }
     orderId.value = row.id
@@ -892,6 +1020,28 @@ async function copyReference() {
     const { copy } = useClipboard({ legacy: true })
     await copy(text)
 }
+
+const uploadUrl = resolveUrl(import.meta.env.VITE_APP_API_BASE_URL, '/api/file/upload')
+const authStore = storeToRefs(useAuthStore())
+const uploadHeaders = computed(() => {
+    return {
+        Authorization: `Bearer ${authStore.token.value}`
+    }
+})
+function onUploaded(options: { file: UploadFileInfo; event?: ProgressEvent }) {
+    const res = (event?.target as XMLHttpRequest).response
+    console.log(JSON.parse(res).url)
+    put({
+        url: '/paper/attachments',
+        data: {
+            orderId: orderId.value,
+            name: options.file.name,
+            url: JSON.parse(res).url
+        }
+    }).then(() => {
+        getAttachments()
+    })
+}
 </script>
 <style lang="less" scoped>
 :deep(.edit-form) {

+ 1 - 1
yarn.lock

@@ -6942,7 +6942,7 @@ resolve-global@1.0.0, resolve-global@^1.0.0:
 
 resolve-url@^0.2.1:
   version "0.2.1"
-  resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz"
+  resolved "https://registry.npmmirror.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
   integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==
 
 resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1: