li.shaoyi преди 3 години
родител
ревизия
d93ff58b30
променени са 49 файла, в които са добавени 1280 реда и са изтрити 243 реда
  1. 9 9
      package-lock.json
  2. 1 1
      package.json
  3. 2 2
      src/business/bank/index.ts
  4. 5 4
      src/business/customs/bonded.ts
  5. 11 9
      src/business/customs/exit.ts
  6. 3 3
      src/business/goods/index.ts
  7. 2 2
      src/business/order/index.ts
  8. 289 0
      src/business/report/index.ts
  9. 99 56
      src/business/table/index.ts
  10. 12 12
      src/business/trade/list.ts
  11. 0 41
      src/components/base/upload/index.vue
  12. 19 2
      src/constants/customs.ts
  13. 13 3
      src/filters/index.ts
  14. 132 0
      src/hooks/datatable/index.next.ts
  15. 6 6
      src/hooks/datatable/index.ts
  16. 2 2
      src/hooks/datatable/interface.ts
  17. 1 1
      src/mock/index.ts
  18. 3 0
      src/packages/pc/components/base/upload/index.less
  19. 140 21
      src/packages/pc/components/base/upload/index.vue
  20. 8 1
      src/packages/pc/views/customs/bonded/components/download/index.vue
  21. 39 7
      src/packages/pc/views/customs/bonded/components/upload-bill/index.vue
  22. 72 0
      src/packages/pc/views/customs/bonded/components/upload-seal/index.vue
  23. 2 2
      src/packages/pc/views/customs/exit/components/advance-payment/index.vue
  24. 1 1
      src/packages/pc/views/customs/exit/components/cancel/index.vue
  25. 2 2
      src/packages/pc/views/customs/exit/components/check/index.vue
  26. 2 2
      src/packages/pc/views/customs/exit/components/delivery/index.vue
  27. 1 1
      src/packages/pc/views/customs/exit/components/details/index.vue
  28. 8 1
      src/packages/pc/views/customs/exit/components/download/index.vue
  29. 1 1
      src/packages/pc/views/customs/exit/components/edit/detail-edit/index.vue
  30. 1 1
      src/packages/pc/views/customs/exit/components/edit/index.vue
  31. 1 1
      src/packages/pc/views/order/main/components/contracted/index.vue
  32. 5 0
      src/packages/pc/views/report/components/daterange/index.less
  33. 81 0
      src/packages/pc/views/report/components/daterange/index.vue
  34. 14 11
      src/packages/pc/views/report/member/index.vue
  35. 14 11
      src/packages/pc/views/report/trade/index.vue
  36. 14 11
      src/packages/pc/views/report/warehousing/index.vue
  37. 6 2
      src/packages/pc/views/warehousing/goods/components/edit/diamond.vue
  38. 1 1
      src/packages/pc/views/warehousing/goods/components/edit/diamonds.vue
  39. 1 1
      src/packages/pc/views/warehousing/goods/components/edit/fancy.vue
  40. 1 1
      src/packages/pc/views/warehousing/goods/components/edit/jewelry.vue
  41. 1 1
      src/packages/pc/views/warehousing/goods/components/edit/rough.vue
  42. 7 0
      src/services/api/common/index.ts
  43. 23 0
      src/services/api/report/index.ts
  44. 1 1
      src/shims-vue.d.ts
  45. 1 1
      src/stores/modules/enum.ts
  46. 23 0
      src/types/ermcp/common.d.ts
  47. 5 4
      src/types/ermcp/customs.d.ts
  48. 191 0
      src/types/ermcp/report.d.ts
  49. 4 4
      src/types/proto/customs.d.ts

+ 9 - 9
package-lock.json

@@ -43,7 +43,7 @@
         "eslint-plugin-vue": "^8.0.3",
         "less": "^4.0.0",
         "less-loader": "^8.0.0",
-        "mockjs": "^1.1.0",
+        "mockjs-x": "^1.0.1-beta5",
         "resize-observer-polyfill": "^1.5.1",
         "ts-import-plugin": "^2.0.0",
         "typescript": "~4.5.5",
@@ -8551,10 +8551,10 @@
         "mkdirp": "bin/cmd.js"
       }
     },
-    "node_modules/mockjs": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz",
-      "integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
+    "node_modules/mockjs-x": {
+      "version": "1.0.1-beta5",
+      "resolved": "https://registry.npmmirror.com/mockjs-x/-/mockjs-x-1.0.1-beta5.tgz",
+      "integrity": "sha512-entZrUc5lOJ+af4jcM+OM7QiKp0Usszi7DKYIKX2oIss6k+cUC94BxcsJ35oN1Vm4XqqomlVIAyNFWMHTeZ67g==",
       "dev": true,
       "dependencies": {
         "commander": "*"
@@ -19024,10 +19024,10 @@
         "minimist": "^1.2.6"
       }
     },
-    "mockjs": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/mockjs/-/mockjs-1.1.0.tgz",
-      "integrity": "sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==",
+    "mockjs-x": {
+      "version": "1.0.1-beta5",
+      "resolved": "https://registry.npmmirror.com/mockjs-x/-/mockjs-x-1.0.1-beta5.tgz",
+      "integrity": "sha512-entZrUc5lOJ+af4jcM+OM7QiKp0Usszi7DKYIKX2oIss6k+cUC94BxcsJ35oN1Vm4XqqomlVIAyNFWMHTeZ67g==",
       "dev": true,
       "requires": {
         "commander": "*"

+ 1 - 1
package.json

@@ -45,7 +45,7 @@
     "eslint-plugin-vue": "^8.0.3",
     "less": "^4.0.0",
     "less-loader": "^8.0.0",
-    "mockjs": "^1.1.0",
+    "mockjs-x": "^1.0.1-beta5",
     "resize-observer-polyfill": "^1.5.1",
     "ts-import-plugin": "^2.0.0",
     "typescript": "~4.5.5",

+ 2 - 2
src/business/bank/index.ts

@@ -114,7 +114,7 @@ export function useBankCancelSign(bankInfo: Ermcp.BankAccountSignRsp) {
  */
 export function useAccountInOut() {
     const { getUserId } = useLoginStore()
-    const { dataList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.AccountOutInApplyRsp>()
+    const { dataList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.AccountOutInApplyRsp>()
     const columns = shallowRef(getTableColumns('mine_capital'))
     const loading = shallowRef(false)
 
@@ -146,7 +146,7 @@ export function useAccountInOut() {
     }
 
     const getAccountInOutApply = () => {
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
         return queryAccountInOutApply({
             data: {

+ 5 - 4
src/business/customs/bonded.ts

@@ -5,6 +5,7 @@ import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
 import { queryGZBSFWOrder, queryGZCJBSOrderFile, queryGZBSFWOrderDetail, queryFworderoperate, bsfwMemberOperate } from '@/services/api/customs'
 import { useLoginStore } from '@/stores'
+import Long from 'long'
 
 // 保税服务
 export function useBSFWOrderList() {
@@ -22,7 +23,7 @@ export function useBSFWOrderList() {
                 { label: '进行中', value: 2 },
                 { label: '已结束', value: 3 },
             ],
-            noClear: true,
+            locked: true,
         },
     ]
 
@@ -103,7 +104,7 @@ export function useBSFWOrderDetail(selectedRow: Ermcp.GZBSFWOrderRsp) {
 }
 
 // 出境文件下载
-export function useGZCJBSOrderFileList(orderid: number) {
+export function useGZCJBSOrderFileList(orderid: string) {
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.GZCJBSOrderFileRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('customs_bsfw_file'))
@@ -157,7 +158,7 @@ export function useBSFWOrderOperate({ orderid, gzbsstatus }: Ermcp.GZBSFWOrderRs
 }
 
 // 保税服务操作
-export function useBSFWMemberOperate(OrderID: number) {
+export function useBSFWMemberOperate(orderId: string) {
     const { loginInfo } = useLoginStore()
     const { UserID, LoginID, LoginCode } = loginInfo.value
     const loading = shallowRef(false)
@@ -166,7 +167,7 @@ export function useBSFWMemberOperate(OrderID: number) {
         UserID, // 用户ID,必填
         OperateID: LoginID, // 操作人ID,必填,LoginAccount的LoginID
         OperateAccount: LoginCode || LoginID.toString(), // 操作人账户,LoginAccount的LoginCode,LoginCode为空则填LoginID,必
-        OrderID, // 单据ID,必填
+        OrderID: Long.fromString(orderId), // 单据ID,必填
         OperateType: 0, // 操作类型,必填,1:上传发货单2:上传盖章单据3:确认预付款
         FileDetails: [], // 文件列表
         Remark: '', // 备注

+ 11 - 9
src/business/customs/exit.ts

@@ -5,6 +5,7 @@ import { getTableColumns } from '@/business/table'
 import { cjjcApply, queryGZCJJCOrder, cjjcMemberOperate, queryGZCJJCOrderDetail, queryGzcjjcorderoperate } from '@/services/api/customs'
 import { ClientType } from '@/constants/client'
 import { useLoginStore } from '@/stores'
+import Long from 'long'
 
 // 出境检测列表
 export function useCJJCOrderList() {
@@ -22,7 +23,7 @@ export function useCJJCOrderList() {
                 { label: '进行中', value: 2 },
                 { label: '已结束', value: 3 },
             ],
-            noClear: true,
+            locked: true,
         },
     ]
 
@@ -102,7 +103,7 @@ export function useGZCJJCOrderDetail(selectedRow: Ermcp.GZCJJCOrderRsp) {
         return queryGZCJJCOrderDetail({
             data: {
                 userid: getUserId(),
-                orderid: selectedRow.orderid,
+                orderid: selectedRow.orderidstr,
             },
             success: (res) => {
                 detailList.value = res.data
@@ -136,11 +137,10 @@ export function useCJJCOrderApply(selectedRow?: Ermcp.GZCJJCOrderRsp) {
         ClientType: ClientType.Web,
     })
 
-    if (selectedRow?.orderid) {
+    if (selectedRow?.orderidstr) {
         ({
             userid: formData.UserID,
             accountid: formData.AccountID,
-            orderid: formData.OrderID,
             gzcjaccounttype: formData.GZCJAccountType,
             gzcjaccount: formData.GZCJAccount,
             companynamecn: formData.CompanyNameCN,
@@ -157,10 +157,12 @@ export function useCJJCOrderApply(selectedRow?: Ermcp.GZCJJCOrderRsp) {
             gzcjdeliverytype: formData.GZCJDeliveryType,
         } = selectedRow)
 
+        formData.OrderID = Long.fromString(selectedRow.orderidstr)
+
         queryGZCJJCOrderDetail({
             data: {
                 userid: UserID,
-                orderid: selectedRow.orderid,
+                orderid: selectedRow.orderidstr,
             },
             success: (res) => {
                 res.data.forEach((e) => {
@@ -203,14 +205,14 @@ export function useCJJCOrderApply(selectedRow?: Ermcp.GZCJJCOrderRsp) {
 }
 
 // 出境检测单据操作
-export function useCJJCOrderOperate({ orderid, gzcjstatus }: Ermcp.GZCJJCOrderRsp) {
+export function useCJJCOrderOperate({ orderidstr, gzcjstatus }: Ermcp.GZCJJCOrderRsp) {
     const loading = shallowRef(false)
     const details = shallowRef<Ermcp.GzcjjcorderoperateRsp>()
 
     const getGzcjjcorderoperate = () => {
         queryGzcjjcorderoperate({
             data: {
-                orderid: orderid.toString(),
+                orderid: orderidstr,
                 status: gzcjstatus
             }
         })
@@ -224,7 +226,7 @@ export function useCJJCOrderOperate({ orderid, gzcjstatus }: Ermcp.GZCJJCOrderRs
 }
 
 // 出境检测操作
-export function useCJJCMemberOperate(OrderID: number) {
+export function useCJJCMemberOperate(orderId: string) {
     const { loginInfo } = useLoginStore()
     const { UserID, LoginID, LoginCode } = loginInfo.value
     const loading = shallowRef(false)
@@ -233,7 +235,7 @@ export function useCJJCMemberOperate(OrderID: number) {
         UserID, // 用户ID,必填
         OperateID: LoginID, // 操作人ID,必填,LoginAccount的LoginID
         OperateAccount: LoginCode || LoginID.toString(), // 操作人账户,LoginAccount的LoginCode,LoginCode为空则填LoginID,必
-        OrderID, // 单据ID,必填
+        OrderID: Long.fromString(orderId), // 单据ID,必填
         OperateType: 0, // 操作类型,必填,1:撤回2:确认发货3:确认检测结果
         ClientType: ClientType.Web, // 终端类型
         ClientSerialNo: '', // 客户端流水号

+ 3 - 3
src/business/goods/index.ts

@@ -32,7 +32,7 @@ import Long from 'long'
 // 钻石列表相关
 export function useDiamond() {
     const { getUserId } = useLoginStore()
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyWRPositionRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.MyWRPositionRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('warehousing_diamond'))
 
@@ -48,7 +48,7 @@ export function useDiamond() {
             key: 'zscategory',
             selectedValue: Category.Diamond,
             options: categoryList,
-            noClear: true,
+            locked: true,
         },
         {
             label: '仓库',
@@ -70,7 +70,7 @@ export function useDiamond() {
     }
 
     const getDiamondList = () => {
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
         return queryDiamondList({
             data: {

+ 2 - 2
src/business/order/index.ts

@@ -10,7 +10,7 @@ import Long from 'long'
 // 我的履约
 export function usePerformance(buyorsell?: BuyOrSell) {
     const { getUserId } = useLoginStore()
-    const { dataList, total, pageIndex, pageSize, inputList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyPerformancRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.MyPerformancRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('order'))
 
@@ -38,7 +38,7 @@ export function usePerformance(buyorsell?: BuyOrSell) {
     const getPerformanceList = () => {
         const { history: ishis, date } = filterData.value
         const [begindate, enddate] = ishis && Array.isArray(date) ? date : []
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
 
         return queryMyPerformance({

+ 289 - 0
src/business/report/index.ts

@@ -0,0 +1,289 @@
+import { shallowRef } from 'vue'
+import { useDataTable } from '@/hooks/datatable'
+import { getTableColumns } from '@/business/table'
+import { Category, getCurrencyTypeList } from '@/constants/diamond'
+import { queryMarketRun } from '@/services/api/common'
+import { queryMemberReport, queryWRPositionReport, queryTradeReport } from '@/services/api/report'
+import { useLoginStore } from '@/stores'
+import { Market } from '@/constants/market'
+
+// 会员报表列表
+export function useMemberReportList() {
+    const { getUserId } = useLoginStore()
+    const { dataList, total, pageIndex, pageSize, buttonList, filterMethod } = useDataTable<Ermcp.MemberReportRsp>()
+    const loading = shallowRef(false)
+    const columns = shallowRef(getTableColumns('report_member'))
+    const marketInfo = shallowRef<Ermcp.MarketRunRsp>() // 市场信息
+    const cycleType = shallowRef(5)
+    const dateValue = shallowRef<string[]>([])
+
+    filterMethod.onReset = () => {
+        dateValue.value = []
+        getMemberReportList()
+    }
+
+    filterMethod.onSearch = () => {
+        getMemberReportList()
+    }
+
+    const getMarketInfo = queryMarketRun({
+        data: {
+            marketID: Market.GZ
+        },
+        success: (res) => {
+            if (res.data.length) {
+                marketInfo.value = res.data[0]
+            }
+        }
+    })
+
+    const getMemberReportList = async () => {
+        loading.value = true
+        await getMarketInfo.then(() => {
+            if (dateValue.value.length === 0) {
+                const defaultDate = new Date().toISOString()
+                const { pretradedate } = marketInfo.value ?? {}
+
+                cycleType.value = 5
+                dateValue.value = [defaultDate, defaultDate]
+                if (pretradedate) {
+                    dateValue.value = [pretradedate, pretradedate]
+                }
+            }
+        })
+
+        const [begindate, enddate] = dateValue.value
+        return queryMemberReport({
+            data: {
+                userid: getUserId(),
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                cycletype: cycleType.value === 5 ? undefined : cycleType.value.toString(),
+                begindate: begindate,
+                enddate: enddate,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        cycleType,
+        dateValue,
+        buttonList,
+        getMemberReportList,
+    }
+}
+
+// 仓储报表列表
+export function useWarehousingReportList() {
+    const { getUserId } = useLoginStore()
+    const { dataList, total, pageIndex, pageSize, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.WRPositionReportRsp>()
+    const loading = shallowRef(false)
+    const columns = shallowRef(getTableColumns('report_warehousing'))
+    const marketInfo = shallowRef<Ermcp.MarketRunRsp>() // 市场信息
+    const cycleType = shallowRef(5)
+    const dateValue = shallowRef<string[]>([])
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: [
+                { label: '单颗裸钻', value: Category.Diamond },
+                { label: '单颗彩钻', value: Category.Fancy },
+                { label: '钻石首饰', value: Category.Jewelry }
+            ],
+        },
+        {
+            label: '商品币种',
+            key: 'zscurrencytype',
+            options: getCurrencyTypeList(),
+        },
+    ]
+
+    filterMethod.onReset = () => {
+        dateValue.value = []
+        getWarehousingReportList()
+    }
+
+    filterMethod.onSearch = () => {
+        getWarehousingReportList()
+    }
+
+    const getMarketInfo = queryMarketRun({
+        data: {
+            marketID: Market.GZ
+        },
+        success: (res) => {
+            if (res.data.length) {
+                marketInfo.value = res.data[0]
+            }
+        }
+    })
+
+    const getWarehousingReportList = async () => {
+        loading.value = true
+        await getMarketInfo.then(() => {
+            if (dateValue.value.length === 0) {
+                const defaultDate = new Date().toISOString()
+                const { pretradedate } = marketInfo.value ?? {}
+
+                cycleType.value = 5
+                dateValue.value = [defaultDate, defaultDate]
+                if (pretradedate) {
+                    dateValue.value = [pretradedate, pretradedate]
+                }
+            }
+        })
+
+        const [begindate, enddate] = dateValue.value
+        const qs = getQueryParams()
+
+        return queryWRPositionReport({
+            data: {
+                userid: getUserId(),
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                cycletype: cycleType.value === 5 ? undefined : cycleType.value.toString(),
+                begindate: begindate,
+                enddate: enddate,
+                zscategory: qs.zscategory,
+                zscurrencytype: qs.zscurrencytype,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        cycleType,
+        dateValue,
+        selectList,
+        buttonList,
+        getWarehousingReportList,
+    }
+}
+
+// 交易报表列表
+export function useTradeReportList() {
+    const { getUserId } = useLoginStore()
+    const { dataList, total, pageIndex, pageSize, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.TradeReportRsp>()
+    const loading = shallowRef(false)
+    const columns = shallowRef(getTableColumns('report_trade'))
+    const marketInfo = shallowRef<Ermcp.MarketRunRsp>() // 市场信息
+    const cycleType = shallowRef(5)
+    const dateValue = shallowRef<string[]>([])
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: [
+                { label: '单颗裸钻', value: Category.Diamond },
+                { label: '单颗彩钻', value: Category.Fancy },
+                { label: '钻石首饰', value: Category.Jewelry }
+            ],
+        },
+        {
+            label: '商品币种',
+            key: 'zscurrencytype',
+            options: getCurrencyTypeList(),
+        },
+    ]
+
+    filterMethod.onReset = () => {
+        dateValue.value = []
+        getTradeReportList()
+    }
+
+    filterMethod.onSearch = () => {
+        getTradeReportList()
+    }
+
+    const getMarketInfo = queryMarketRun({
+        data: {
+            marketID: Market.GZ
+        },
+        success: (res) => {
+            if (res.data.length) {
+                marketInfo.value = res.data[0]
+            }
+        }
+    })
+
+    const getTradeReportList = async () => {
+        loading.value = true
+        await getMarketInfo.then(() => {
+            if (dateValue.value.length === 0) {
+                const defaultDate = new Date().toISOString()
+                const { pretradedate } = marketInfo.value ?? {}
+
+                cycleType.value = 5
+                dateValue.value = [defaultDate, defaultDate]
+                if (pretradedate) {
+                    dateValue.value = [pretradedate, pretradedate]
+                }
+            }
+        })
+
+        const [begindate, enddate] = dateValue.value
+        const qs = getQueryParams()
+
+        return queryTradeReport({
+            data: {
+                userid: getUserId(),
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                cycletype: cycleType.value === 5 ? undefined : cycleType.value.toString(),
+                begindate: begindate,
+                enddate: enddate,
+                zscategory: qs.zscategory,
+                zscurrencytype: qs.zscurrencytype,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        cycleType,
+        dateValue,
+        selectList,
+        buttonList,
+        getTradeReportList,
+    }
+}

+ 99 - 56
src/business/table/index.ts

@@ -1,8 +1,60 @@
 import { shallowRef } from 'vue'
 import { useTableColumnStore } from '@/stores'
 
+/**
+ * 获取表格列数据
+ * @param tableKey 
+ * @returns 
+ */
+export function getTableColumns(tableKey: TableColumnKey) {
+    const tableColumns = pcTableColumnMap.get(tableKey) ?? [] // *这里应该判断终端类型,有空再处理*
+
+    return tableColumns.map((e) => {
+        e.show = true
+        if (e.prop === 'operate') {
+            e.fixed = 'right'
+        }
+        return e
+    })
+}
+
+export function useTableColumns(tableKey: string, operateColumn = true) {
+    const { tableColumns } = useTableColumnStore()
+
+    const columns = shallowRef(tableColumns.value.reduce((res, cur) => {
+        if (cur.tablekey === tableKey) {
+            cur.columns.forEach((e) => {
+                res.push({
+                    prop: e.columnfield,
+                    label: e.columntitle,
+                    width: Number(e.columnwidth),
+                    show: e.isshow ? true : false,
+                    fixed: e.fixed,
+                })
+            })
+            if (operateColumn) {
+                res.push({
+                    prop: 'operate',
+                    label: '操作',
+                    show: true,
+                })
+            }
+        }
+        return res
+    }, [] as Ermcp.TableColumn[]))
+
+    const updateColumns = () => {
+        console.log('更新表头列')
+    }
+
+    return {
+        columns,
+        updateColumns,
+    }
+}
+
 type TableColumnKey = typeof tableColumnKeys[number]
-const tableColumnKeys = ['system_menu', 'system_role', 'warehousing_diamond', 'warehousing_warehouse', 'mine_capital', 'listing_sellorder', 'listing_buyorder', 'listing_saleorder', 'listing_purchaseorder', 'listing_delisting', 'listing_bargain_buy', 'listing_bargain_sell', 'mine_address', 'mine_invoice', 'favorite', 'order', 'order_step', 'bargain_buy', 'bargain_sell', 'customs_cjjc', 'customs_bsfw', 'customs_bsfw_file'] as const
+const tableColumnKeys = ['system_menu', 'system_role', 'warehousing_diamond', 'warehousing_warehouse', 'mine_capital', 'listing_sellorder', 'listing_buyorder', 'listing_saleorder', 'listing_purchaseorder', 'listing_delisting', 'listing_bargain_buy', 'listing_bargain_sell', 'mine_address', 'mine_invoice', 'favorite', 'order', 'order_step', 'bargain_buy', 'bargain_sell', 'customs_cjjc', 'customs_bsfw', 'customs_bsfw_file', 'report_member', 'report_warehousing', 'report_trade'] as const
 
 /**
  * PC端表格列
@@ -294,7 +346,7 @@ const pcTableColumnMap = new Map<TableColumnKey, Ermcp.TableColumn[]>([
         { prop: 'contactname', label: '联系人姓名' },
         { prop: 'contactphoneno', label: '联系人电话' },
         { prop: 'gzcjstatusdisplay', label: '单据状态' },
-        { prop: 'operate', label: '操作', width: 180 }
+        { prop: 'operate', label: '操作', width: 260 }
     ]],
     // 交易服务-保税服务
     ['customs_bsfw', [
@@ -307,7 +359,7 @@ const pcTableColumnMap = new Map<TableColumnKey, Ermcp.TableColumn[]>([
         { prop: 'priceper', label: '单价(美元/克拉)', width: 160 },
         { prop: 'undefined', label: '备注' },
         { prop: 'gzbsstatusdisplay', label: '单据状态' },
-        { prop: 'operate', label: '操作', width: 180 }
+        { prop: 'operate', label: '操作', width: 260 }
     ]],
     // 交易服务-保税服务-文件下载
     ['customs_bsfw_file', [
@@ -315,56 +367,47 @@ const pcTableColumnMap = new Map<TableColumnKey, Ermcp.TableColumn[]>([
         { prop: 'operatetime', label: '生成时间' },
         { prop: 'operate', label: '操作', width: 180 }
     ]],
-])
-
-/**
- * 获取表格列数据
- * @param tableKey 
- * @returns 
- */
-export function getTableColumns(tableKey: TableColumnKey) {
-    const tableColumns = pcTableColumnMap.get(tableKey) ?? [] // *这里应该判断终端类型,有空再处理*
-
-    return tableColumns.map((e) => {
-        e.show = true
-        if (e.prop === 'operate') {
-            e.fixed = 'right'
-        }
-        return e
-    })
-}
-
-export function useTableColumns(tableKey: string, operateColumn = true) {
-    const { tableColumns } = useTableColumnStore()
-
-    const columns = shallowRef(tableColumns.value.reduce((res, cur) => {
-        if (cur.tablekey === tableKey) {
-            cur.columns.forEach((e) => {
-                res.push({
-                    prop: e.columnfield,
-                    label: e.columntitle,
-                    width: Number(e.columnwidth),
-                    show: e.isshow ? true : false,
-                    fixed: e.fixed,
-                })
-            })
-            if (operateColumn) {
-                res.push({
-                    prop: 'operate',
-                    label: '操作',
-                    show: true,
-                })
-            }
-        }
-        return res
-    }, [] as Ermcp.TableColumn[]))
-
-    const updateColumns = () => {
-        console.log('更新表头列')
-    }
-
-    return {
-        columns,
-        updateColumns,
-    }
-}
+    // 报表-会员报表
+    ['report_member', [
+        { prop: 'reckondate', label: '日期' },
+        { prop: 'accountid', label: '资金账户' },
+        { prop: 'balance', label: '期初余额' },
+        { prop: 'currentbalance', label: '期末余额' },
+        { prop: 'avaiablemoney', label: '可用资金' },
+        { prop: 'avaiableoutmoney', label: '可出资金' },
+        { prop: 'netvalue', label: '当前净值' },
+        { prop: 'inamount', label: '入金金额' },
+        { prop: 'outamount', label: '出金金额' },
+        { prop: 'paycharge', label: '手续费支出' },
+        { prop: 'deliveryamountin', label: '销售收入' },
+        { prop: 'deliveryamountout', label: '购买支出' },
+        { prop: 'otherfreezemargin', label: '其他冻结' },
+        { prop: 'outamountfreeze', label: '出金冻结' },
+    ]],
+    // 报表-仓储报表
+    ['report_warehousing', [
+        { prop: 'reckondate', label: '日期' },
+        { prop: 'zscategorydisplay', label: '商品分类' },
+        { prop: 'zscurrencytypedisplay', label: '商品货币' },
+        { prop: 'totalweight', label: '库存重量(ct)' },
+        { prop: 'totalprice', label: '库存金额' },
+        { prop: 'buytradeqty', label: '购买重量(ct)' },
+        { prop: 'buytradeamount', label: '购买金额(¥)' },
+        { prop: 'selltradeqty', label: '销售重量(ct)' },
+        { prop: 'selltradeamount', label: '销售金额(¥)' },
+    ]],
+    // 报表-交易报表
+    ['report_trade', [
+        { prop: 'reckondate', label: '日期' },
+        { prop: 'zscategorydisplay', label: '商品分类' },
+        { prop: 'zscurrencytypedisplay', label: '商品货币' },
+        { prop: 'buylistinglot', label: '买挂牌宗数' },
+        { prop: 'selllistinglot', label: '卖挂牌宗数' },
+        { prop: 'selllistingqty', label: '卖挂牌数量' },
+        { prop: 'selltradeamount', label: '卖挂牌金额' },
+        { prop: 'buytradeqty', label: '购买重量(ct)' },
+        { prop: 'buytradeamount', label: '购买金额(¥)' },
+        { prop: 'selltradeqty', label: '销售重量(ct)' },
+        { prop: 'selltradeamount', label: '销售金额(¥)' },
+    ]],
+])

+ 12 - 12
src/business/trade/list.ts

@@ -16,7 +16,7 @@ const categoryList = [
  * @returns 
  */
 export function useBuyOrder() {
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.BuyOrderRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.BuyOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_buyorder'))
 
@@ -44,7 +44,7 @@ export function useBuyOrder() {
 
     // 获取求购大厅委托单
     const getBuyOrderList = () => {
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
         return queryBuyOrder({
             data: {
@@ -84,7 +84,7 @@ export function useBuyOrder() {
  * @returns 
  */
 export function useSellOrder() {
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.SellOrderRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.SellOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_sellorder'))
 
@@ -112,7 +112,7 @@ export function useSellOrder() {
 
     // 获取出售大厅委托单
     const getSellOrderList = async () => {
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
         return querySellOrder({
             data: {
@@ -152,7 +152,7 @@ export function useSellOrder() {
  */
 export function useSaleOrder() {
     const { getUserId } = useLoginStore()
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MySellOrderRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.MySellOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_saleorder'))
 
@@ -190,7 +190,7 @@ export function useSaleOrder() {
     const getSaleOrderList = () => {
         const { history: ishis, date } = filterData.value
         const [begindate, enddate] = ishis && Array.isArray(date) ? date : []
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
 
         return queryMySellOrder({
@@ -235,7 +235,7 @@ export function useSaleOrder() {
  */
 export function usePurchaseOrder() {
     const { getUserId } = useLoginStore()
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyBuyOrderRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.MyBuyOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_purchaseorder'))
 
@@ -273,7 +273,7 @@ export function usePurchaseOrder() {
     const getPurchaseOrderList = () => {
         const { history: ishis, date } = filterData.value
         const [begindate, enddate] = ishis && Array.isArray(date) ? date : []
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
 
         return queryMyBuyOrder({
@@ -318,7 +318,7 @@ export function usePurchaseOrder() {
  */
 export function useDelistingOrder(buyorsell = BuyOrSell.Buy) {
     const { getUserId } = useLoginStore()
-    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyDeListingRsp>()
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParams } = useDataTable<Ermcp.MyDeListingRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_delisting'))
     const filterDate = shallowRef<string[]>([])
@@ -329,14 +329,14 @@ export function useDelistingOrder(buyorsell = BuyOrSell.Buy) {
             label: '商品分类',
             key: 'zscategory',
             selectedValue: Category.Diamond,
-            noClear: true,
+            locked: true,
             options: categoryList,
         },
         {
             label: '方向',
             key: 'buyorsell',
             selectedValue: buyOrSell.value,
-            noClear: true,
+            locked: true,
             options: getBuyOrSellList(),
         },
     ]
@@ -358,7 +358,7 @@ export function useDelistingOrder(buyorsell = BuyOrSell.Buy) {
     // 获取我的摘牌列表
     const getDelistingOrderList = () => {
         const [begindate, enddate] = filterDate.value || []
-        const param = getQueryParam()
+        const param = getQueryParams()
         loading.value = true
 
         return queryMyDeListing({

+ 0 - 41
src/components/base/upload/index.vue

@@ -1,41 +0,0 @@
-<template>
-    <div class="app-upload">
-        <el-upload v-model:file-list="fileList" :limit="1" :action="uploadUrl" @preview="onPreview">
-            <el-button type="primary">上传</el-button>
-        </el-upload>
-        <el-image-viewer :url-list="imageList" @close="onViewerClose" v-if="showViewer" teleported />
-    </div>
-</template>
-
-<script lang="ts" setup>
-import { ref, computed } from 'vue'
-import type { UploadProps, UploadUserFile } from 'element-plus'
-import service from '@/services'
-
-const { uploadUrl } = service.config
-const showViewer = ref(false)
-const fileList = ref<UploadUserFile[]>([])
-
-const imageList = computed(() => {
-    return fileList.value.reduce((res, cur) => {
-        if (cur.url) {
-            res.push(cur.url)
-        } else {
-            const response = cur.response as { filePath: string }[]
-            response?.forEach((e) => {
-                const filePath = uploadUrl.replace('/upload', '') + e.filePath.replace('./', '/')
-                res.push(filePath)
-            })
-        }
-        return res
-    }, [] as string[])
-})
-
-const onPreview: UploadProps['onPreview'] = () => {
-    showViewer.value = true
-}
-
-const onViewerClose = () => {
-    showViewer.value = false
-}
-</script>

+ 19 - 2
src/constants/customs.ts

@@ -37,7 +37,7 @@ export function getGZCJCategoryTypeName(value?: number) {
 }
 
 /**
- * 获取收货方式列表
+ * 获取出境检测收货方式列表
  * @returns 
  */
 export function getGZCJDeliveryTypeList() {
@@ -45,7 +45,7 @@ export function getGZCJDeliveryTypeList() {
 }
 
 /**
- * 获取收货方式名称
+ * 获取出境检测收货方式名称
  * @returns 
  */
 export function getGZCJDeliveryTypeName(value?: number) {
@@ -54,6 +54,23 @@ export function getGZCJDeliveryTypeName(value?: number) {
 }
 
 /**
+ * 获取保税服务提货方式列表
+ * @returns 
+ */
+export function getGZBSDeliveryTypeList() {
+    return getEnumTypeList('GZBSDeliveryType')
+}
+
+/**
+ * 获取保税服务提货方式名称
+ * @returns 
+ */
+export function getGZBSDeliveryTypeName(value?: number) {
+    const enums = getGZBSDeliveryTypeList()
+    return getEnumTypeName(enums, value)
+}
+
+/**
  * 获取形状列表
  * @returns 
  */

+ 13 - 3
src/filters/index.ts

@@ -3,15 +3,25 @@ import service from '@/services'
 import moment from 'moment'
 
 /**
+ * 获取url对象方法
+ * @param url 
+ * @param base 
+ * @returns 
+ */
+export function getUrl(url: string, base?: string) {
+    const { uploadUrl } = service.config
+    return new URL(url, base ?? uploadUrl)
+}
+
+/**
  * 获取图片地址
  * @param fileUrl 
  */
 export function getImageUrl(fileUrl: string) {
     if (fileUrl) {
-        const { openApiUrl } = service.config
-        return openApiUrl + fileUrl.replace('./', '/')
+        const url = getUrl(fileUrl)
+        return url.href
     }
-    // 返回默认图片
     return ''
 }
 

+ 132 - 0
src/hooks/datatable/index.next.ts

@@ -0,0 +1,132 @@
+import { reactive, ref, shallowRef, computed, UnwrapRef } from 'vue'
+import { FilterValue, FilterOptions, DataTableOptions } from './interface'
+
+export function useDataTable<T>(options: DataTableOptions = {}) {
+    // 数据源
+    const dataSource = ref<T[]>([])
+    // 总条数
+    const total = shallowRef(0)
+    // 每页条数
+    const pageSize = shallowRef(options.pageSize ?? 20)
+    // 当前页码
+    const pageIndex = shallowRef(options.pageIndex ?? 1)
+    // 总页数
+    const pageCount = computed(() => Math.ceil(total.value / pageSize.value) || 1)
+    // 过滤筛选值
+    const filters = shallowRef<FilterValue<T>[]>([])
+
+    // 数据列表
+    const dataList = computed<UnwrapRef<T[]>>({
+        get() {
+            const result = dataSource.value.filter((row) => {
+                // 过滤所有查询条件
+                return filters.value.every((e) => {
+                    return e.keys.some((key) => {
+                        const value = row[key]
+                        if (typeof value === 'number') {
+                            return e.filteredValue.includes(value as T[keyof T])
+                        }
+                        return e.filteredValue.some((text) => {
+                            return String(value).toLowerCase().indexOf(String(text)) >= 0
+                        })
+                    })
+                })
+            })
+            // 本地分页
+            if (options.pagination) {
+                return result.slice((pageIndex.value - 1) * pageSize.value, pageIndex.value * pageSize.value)
+            }
+            return result
+        },
+        set(val) {
+            dataSource.value = val
+        }
+    })
+
+    return {
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        pageCount,
+        filters,
+    }
+}
+
+export function useDataFilter<T>(submit?: (qs: Partial<T>) => void) {
+    const filterOptons: FilterOptions<T> = reactive({
+        selectList: [],
+        inputList: [],
+        buttonList: [],
+    })
+
+    // 获取过滤参数,支持多条件查询
+    const getFilterParams = () => {
+        const options: FilterValue<T>[] = []
+        filterOptons.selectList.forEach((e) => {
+            const { key, selectedValue } = e;
+            if (selectedValue !== undefined) {
+                options.push({
+                    keys: [key],
+                    filteredValue: [selectedValue],
+                })
+            }
+        })
+        filterOptons.inputList.forEach((e) => {
+            const { keys, value } = e;
+            if (value) {
+                options.push({
+                    keys,
+                    filteredValue: [value],
+                })
+            }
+        })
+        return options
+    }
+
+    // 获取查询参数,支持多条件查询
+    const getQueryParams = () => {
+        const params: Partial<T> = {}
+        filterOptons.selectList.forEach((e) => {
+            if (e.selectedValue !== undefined) {
+                params[e.key] = e.selectedValue
+            }
+        })
+        filterOptons.inputList.forEach((e) => {
+            e.keys.forEach((key) => {
+                if (e.value) {
+                    params[key] = e.value
+                }
+            })
+        })
+        return params
+    }
+
+    // 清空所有过滤条件
+    const clearAll = (callback?: () => void) => {
+        filterOptons.selectList.forEach((e) => {
+            if (!e.locked) {
+                e.selectedValue = undefined
+            }
+        })
+        filterOptons.inputList.forEach((e) => {
+            if (!e.locked) {
+                e.value = undefined
+            }
+        })
+        callback && callback()
+    }
+
+    const onSearch = (reset = false) => {
+        reset && clearAll()
+        const qs = getQueryParams()
+        submit && submit(qs)
+    }
+
+    return {
+        filterOptons,
+        getFilterParams,
+        getQueryParams,
+        clearAll,
+    }
+}

+ 6 - 6
src/hooks/datatable/index.ts

@@ -23,12 +23,12 @@ export function useDataTable<T>(options: DataTableOptions = {}) {
                 lable: '重置',
                 onClick: () => {
                     filterOptons.selectList.forEach((e) => {
-                        if (!e.noClear) {
+                        if (!e.locked) {
                             e.selectedValue = undefined
                         }
                     })
                     filterOptons.inputList.forEach((e) => {
-                        if (!e.noClear) {
+                        if (!e.locked) {
                             e.value = undefined
                         }
                     })
@@ -53,7 +53,7 @@ export function useDataTable<T>(options: DataTableOptions = {}) {
             filters.value = []
         },
         onSearch: () => {
-            filters.value = getFilterParam()
+            filters.value = getFilterParams()
         }
     }
 
@@ -86,7 +86,7 @@ export function useDataTable<T>(options: DataTableOptions = {}) {
     })
 
     // 获取过滤参数,支持多条件查询
-    const getFilterParam = () => {
+    const getFilterParams = () => {
         const options: FilterValue<T>[] = []
         filterOptons.selectList.forEach((e) => {
             const { key, selectedValue } = e;
@@ -110,7 +110,7 @@ export function useDataTable<T>(options: DataTableOptions = {}) {
     }
 
     // 获取查询参数,支持多条件查询
-    const getQueryParam = () => {
+    const getQueryParams = () => {
         const params: { [K in keyof T]?: T[K] } = {}
         filterOptons.selectList.forEach((e) => {
             if (e.selectedValue !== undefined) {
@@ -134,7 +134,7 @@ export function useDataTable<T>(options: DataTableOptions = {}) {
         pageSize,
         pageCount,
         filterMethod,
-        getQueryParam,
+        getQueryParams,
         ...toRefs(filterOptons),
     }
 }

+ 2 - 2
src/hooks/datatable/interface.ts

@@ -22,7 +22,7 @@ export interface FilterSelect<T> {
     key: keyof T,
     label?: string,
     selectedValue?: T[keyof T],
-    noClear?: boolean, // 重置时是否阻止清空当前值
+    locked?: boolean, // 重置时是否阻止清空当前值
     placeholder?: string,
     options: {
         label: string,
@@ -38,7 +38,7 @@ export interface FilterInput<T> {
     keys: (keyof T)[],
     label?: string,
     value?: T[keyof T],
-    noClear?: boolean, // 重置时是否阻止清空当前值
+    locked?: boolean, // 重置时是否阻止清空当前值
     type?: 'text' | 'number',
     placeholder?: string
 }

+ 1 - 1
src/mock/index.ts

@@ -1,4 +1,4 @@
-import Mock from 'mockjs'
+import Mock from 'mockjs-x'
 
 Mock.setup({
     timeout: '100-200'

+ 3 - 0
src/packages/pc/components/base/upload/index.less

@@ -0,0 +1,3 @@
+.app-upload {
+    line-height: normal;
+}

+ 140 - 21
src/packages/pc/components/base/upload/index.vue

@@ -1,41 +1,160 @@
 <template>
     <div class="app-upload">
-        <el-upload v-model:file-list="fileList" :limit="1" :action="uploadUrl" @preview="onPreview">
-            <el-button type="primary">上传</el-button>
+        <el-upload ref="uploadRef" :file-list="fileList" :limit="limit" :multiple="limit > 1" :action="uploadUrl"
+            :before-upload="onBeforeUpload" @success="onSuccess" @remove="onRemove" @preview="onPreview"
+            @exceed="onExceed">
+            <template #tip>
+                <div class="el-upload__tip">
+                    <slot name="tip"></slot>
+                </div>
+            </template>
+            <slot>
+                <el-button type="primary">上传</el-button>
+            </slot>
         </el-upload>
-        <el-image-viewer :url-list="imageList" @close="onViewerClose" v-if="showViewer" teleported />
+        <el-image-viewer :url-list="imageList.map((e)=>e.filePath)" :initial-index="imageIndex" @close="onViewerClose"
+            v-if="showViewer" teleported />
     </div>
 </template>
 
 <script lang="ts" setup>
-import { ref, computed } from 'vue'
-import type { UploadProps, UploadUserFile } from 'element-plus'
+import { shallowRef, computed, PropType, toRaw } from 'vue'
+import { ElMessage, UploadProps, UploadUserFile, UploadRawFile, UploadFile, UploadFiles, UploadInstance, genFileId } from 'element-plus'
+import { getImageUrl } from '@/filters'
 import service from '@/services'
 
+const props = defineProps({
+    fileTypes: {
+        type: Array as PropType<readonly ('image' | 'pdf')[]>,
+        default: () => ([])
+    },
+    limit: {
+        type: Number,
+        default: 1
+    },
+    maxSize: {
+        type: Number,
+        default: 0
+    },
+    typeMessage: {
+        type: String,
+        default: '请选择正确的文件类型'
+    }
+})
+
+const emit = defineEmits(['change'])
+
 const { uploadUrl } = service.config
-const showViewer = ref(false)
-const fileList = ref<UploadUserFile[]>([])
+const uploadRef = shallowRef<UploadInstance>()
+const showViewer = shallowRef(false)
+const fileList = shallowRef<UploadUserFile[]>([])
+const imageIndex = shallowRef(0)
+const imageTypes = ['image/png', 'image/jpeg']
+
+// 允许上传的文件类型
+const uploadTypes = props.fileTypes.reduce((res, value) => {
+    switch (value) {
+        case 'image': {
+            res.push(...imageTypes)
+            break
+        }
+        case 'pdf': {
+            res.push('application/pdf')
+            break
+        }
+    }
+    return res
+}, [] as string[])
 
+// 预览图列表
 const imageList = computed(() => {
-    return fileList.value.reduce((res, cur) => {
-        if (cur.url) {
-            res.push(cur.url)
-        } else {
-            const response = cur.response as { filePath: string }[]
-            response?.forEach((e) => {
-                const filePath = uploadUrl.replace('/upload', '') + e.filePath.replace('./', '/')
-                res.push(filePath)
-            })
+    const result: { uid: number, filePath: string }[] = []
+    fileList.value.forEach(({ raw, uid, response }) => {
+        if (raw && uid && response) {
+            // 判断是否图片类型
+            if (imageTypes.includes(raw.type)) {
+                (response as { filePath: string }[]).forEach((e) => {
+                    result.push({
+                        uid,
+                        filePath: getImageUrl(e.filePath)
+                    })
+                })
+            }
         }
-        return res
-    }, [] as string[])
+    })
+    return result
 })
 
-const onPreview: UploadProps['onPreview'] = () => {
-    showViewer.value = true
+const onChange = () => {
+    const files = fileList.value.reduce((res, { response }) => {
+        const list = (response ?? []) as unknown[]
+        list.forEach((e) => {
+            res.push(toRaw(e))
+        })
+        return res
+    }, [] as unknown[])
+    emit('change', props.limit > 1 ? files : files[0] ?? {})
+}
+
+// 当超出限制时的回调
+const onExceed = (files: File[]) => {
+    if (props.limit === 1) {
+        const el = uploadRef.value
+        if (el) {
+            const rawFile = files[0] as UploadRawFile
+            if (uploadTypes.includes(rawFile.type)) {
+                rawFile.uid = genFileId()
+                el.clearFiles()
+                el.handleStart(rawFile)
+                el.submit()
+            } else {
+                ElMessage.warning(props.typeMessage)
+            }
+        }
+    } else {
+        ElMessage.warning(`最多只能上传${props.limit}个文件`)
+    }
+}
+
+// 上传之前判断文件类型
+const onBeforeUpload = (rawFile: UploadRawFile) => {
+    if (uploadTypes.includes(rawFile.type)) {
+        return true
+    }
+    ElMessage.warning(props.typeMessage)
+    return false
+}
+
+// 上传成功的回调
+const onSuccess = (response: unknown, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
+    fileList.value = uploadFiles
+    onChange()
+}
+
+const onRemove = (uploadFile: UploadFile, uploadFiles: UploadFiles) => {
+    fileList.value = uploadFiles
+    onChange()
+}
+
+// 打开预览图
+const onPreview: UploadProps['onPreview'] = ({ uid, raw }: UploadFile) => {
+    if (imageList.value.length) {
+        // 判断是否图片类型
+        if (imageTypes.includes(raw?.type ?? '')) {
+            const index = imageList.value.findIndex((e) => e.uid === uid)
+            if (index > -1) {
+                imageIndex.value = index
+                showViewer.value = true
+            }
+        }
+    }
 }
 
 const onViewerClose = () => {
     showViewer.value = false
 }
-</script>
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 8 - 1
src/packages/pc/views/customs/bonded/components/download/index.vue

@@ -23,7 +23,14 @@ const props = defineProps({
     },
 })
 
-const { loading, dataList, columns, getGZCJBSOrderFileList } = useGZCJBSOrderFileList(props.selectedRow.orderid)
+const orderId = (() => {
+    if ('orderidstr' in props.selectedRow) {
+        return props.selectedRow.orderidstr
+    }
+    return props.selectedRow.orderid
+})()
+
+const { loading, dataList, columns, getGZCJBSOrderFileList } = useGZCJBSOrderFileList(orderId)
 const show = shallowRef(true)
 
 getGZCJBSOrderFileList()

+ 39 - 7
src/packages/pc/views/customs/bonded/components/upload-bill/index.vue

@@ -1,12 +1,22 @@
 <!-- 交易服务-保税服务-上传发货单 -->
 <template>
     <app-drawer title="上传发货单" v-model:show="show" :loading="loading" :refresh="refresh">
-        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formData">
+        <el-form ref="formRef" label-width="100px" :model="formData" :rules="formRules">
             <el-form-item label="单据编号">
                 {{ selectedRow.orderid }}
             </el-form-item>
-            <el-form-item class="el-form-item--row" label="备注" prop="Remark">
-                <el-input type="textarea" v-model="formData.Remark" />
+            <el-form-item label="提货方式" prop="GZBSDeliveryType">
+                <el-select v-model="formData.GZBSDeliveryType">
+                    <el-option :label="item.label" :value="item.value"
+                        v-for="(item, index) in getGZBSDeliveryTypeList()" :key="index" />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="发货单" prop="FileDetails">
+                <app-upload :limit="5" :file-types="['pdf']" @change="onUploadChange">
+                    <template #tip>
+                        <span>只支持pdf格式</span>
+                    </template>
+                </app-upload>
             </el-form-item>
         </el-form>
         <template #footer>
@@ -19,27 +29,49 @@
 <script lang="ts" setup>
 import { shallowRef, PropType } from 'vue'
 import { ElMessage } from 'element-plus'
-import { useCJJCMemberOperate } from '@/business/customs/exit'
+import type { FormInstance, FormRules } from 'element-plus'
+import { getGZBSDeliveryTypeList } from '@/constants/customs'
+import { useBSFWMemberOperate } from '@/business/customs/bonded'
 import AppDrawer from '@pc/components/base/drawer/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 const props = defineProps({
     selectedRow: {
-        type: Object as PropType<Ermcp.GZCJJCOrderRsp>,
+        type: Object as PropType<Ermcp.GZBSFWOrderRsp>,
         required: true
     },
 })
 
-const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderid)
+const { loading, formData, formSubmit } = useBSFWMemberOperate(props.selectedRow.orderid)
 const show = shallowRef(true)
 const refresh = shallowRef(false)
+const formRef = shallowRef<FormInstance>()
+
+const formRules: FormRules = {
+    GZBSDeliveryType: [{
+        required: true,
+        message: '请选择提货方式'
+    }],
+    FileDetails: [{
+        required: true,
+        message: '请上传发货单'
+    }],
+}
 
 const onCancel = (isRefresh = false) => {
     show.value = false
     refresh.value = isRefresh
 }
 
+const onUploadChange = (files: { fileName: string, filePath: string }[]) => {
+    formData.FileDetails = files.map((e) => ({
+        FileName: e.fileName,
+        FilePath: e.filePath,
+    }))
+}
+
 const onSubmit = () => {
-    formData.OperateType = 2
+    formData.OperateType = 1
     formSubmit().then(() => {
         ElMessage.success('提交成功')
         onCancel(true)

+ 72 - 0
src/packages/pc/views/customs/bonded/components/upload-seal/index.vue

@@ -0,0 +1,72 @@
+<!-- 交易服务-保税服务-上传盖章单据 -->
+<template>
+    <app-drawer title="上传盖章单据" v-model:show="show" :loading="loading" :refresh="refresh">
+        <el-form ref="formRef" label-width="100px" :model="formData" :rules="formRules">
+            <el-form-item label="单据编号">
+                {{ selectedRow.orderid }}
+            </el-form-item>
+            <el-form-item label="盖章" prop="FileDetails">
+                <app-upload :limit="5" :file-types="['pdf']" @change="onUploadChange">
+                    <template #tip>
+                        <span>只支持pdf格式</span>
+                    </template>
+                </app-upload>
+            </el-form-item>
+        </el-form>
+        <div>请下载文件“出境检测发票装箱单OJK(GIA发,运营收).pdf”, 盖章后上传。</div>
+        <template #footer>
+            <el-button @click="onCancel(false)" plain>取消</el-button>
+            <el-button type="primary" @click="onSubmit">确认</el-button>
+        </template>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { shallowRef, PropType } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { useBSFWMemberOperate } from '@/business/customs/bonded'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
+
+const props = defineProps({
+    selectedRow: {
+        type: Object as PropType<Ermcp.GZBSFWOrderRsp>,
+        required: true
+    },
+})
+
+const { loading, formData, formSubmit } = useBSFWMemberOperate(props.selectedRow.orderid)
+const show = shallowRef(true)
+const refresh = shallowRef(false)
+const formRef = shallowRef<FormInstance>()
+
+const formRules: FormRules = {
+    FileDetails: [{
+        required: true,
+        message: '请上传盖章单据'
+    }],
+}
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+const onUploadChange = (files: { fileName: string, filePath: string }[]) => {
+    formData.FileDetails = files.map((e) => ({
+        FileName: e.fileName,
+        FilePath: e.filePath,
+    }))
+}
+
+const onSubmit = () => {
+    formData.OperateType = 2
+    formSubmit().then(() => {
+        ElMessage.success('提交成功')
+        onCancel(true)
+    }).catch((err) => {
+        ElMessage.error('提交失败:' + err)
+    })
+}
+</script>

+ 2 - 2
src/packages/pc/views/customs/exit/components/advance-payment/index.vue

@@ -2,7 +2,7 @@
 <template>
     <app-drawer title="确认预付款" v-model:show="show" :loading="loading" :refresh="refresh">
         <el-descriptions v-if="details">
-            <el-descriptions-item label="单据编号">{{ selectedRow.orderid }}</el-descriptions-item>
+            <el-descriptions-item label="单据编号">{{ selectedRow.orderidstr }}</el-descriptions-item>
             <el-descriptions-item label="GIA检测费">{{ details.giausdfee }}{{ details.giarmbfee }}</el-descriptions-item>
             <el-descriptions-item label="海关税费">{{ details.customsfee }}</el-descriptions-item>
             <el-descriptions-item label="汇款银行手续费">{{ details.bankfee }}</el-descriptions-item>
@@ -34,7 +34,7 @@ const props = defineProps({
 })
 
 const { details, getGzcjjcorderoperate } = useCJJCOrderOperate(props.selectedRow)
-const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderid)
+const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderidstr)
 const show = shallowRef(true)
 const refresh = shallowRef(false)
 

+ 1 - 1
src/packages/pc/views/customs/exit/components/cancel/index.vue

@@ -22,7 +22,7 @@ const props = defineProps({
     },
 })
 
-const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderid)
+const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderidstr)
 const show = shallowRef(true)
 const refresh = shallowRef(false)
 

+ 2 - 2
src/packages/pc/views/customs/exit/components/check/index.vue

@@ -3,7 +3,7 @@
     <app-drawer title="确认检测结果" v-model:show="show" :loading="loading" :refresh="refresh">
         <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formData">
             <el-form-item label="单据编号">
-                {{ selectedRow.orderid }}
+                {{ selectedRow.orderidstr }}
             </el-form-item>
             <el-form-item class="el-form-item--row" label="备注" prop="Remark">
                 <el-input type="textarea" v-model="formData.Remark" />
@@ -29,7 +29,7 @@ const props = defineProps({
     },
 })
 
-const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderid)
+const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderidstr)
 const show = shallowRef(true)
 const refresh = shallowRef(false)
 

+ 2 - 2
src/packages/pc/views/customs/exit/components/delivery/index.vue

@@ -3,7 +3,7 @@
     <app-drawer title="出境发货" v-model:show="show" :loading="loading" :refresh="refresh">
         <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formData">
             <el-form-item label="单据编号">
-                {{ selectedRow.orderid }}
+                {{ selectedRow.orderidstr }}
             </el-form-item>
             <el-form-item class="el-form-item--row" label="备注" prop="Remark">
                 <el-input type="textarea" v-model="formData.Remark" />
@@ -29,7 +29,7 @@ const props = defineProps({
     },
 })
 
-const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderid)
+const { loading, formData, formSubmit } = useCJJCMemberOperate(props.selectedRow.orderidstr)
 const show = shallowRef(true)
 const refresh = shallowRef(false)
 

+ 1 - 1
src/packages/pc/views/customs/exit/components/details/index.vue

@@ -10,7 +10,7 @@
             <p>本表将作为委托方委托广州钻石交易中心办理出境检测业务申请使用,敬请务必如实填写公司信息、货物资料,并盖章确认。广州钻石交易中心根据此表确认信息,作为接受委托办理该批货物出境检测业务的凭证,仅对数量负责。</p>
         </div>
         <el-descriptions title="委托方信息" :column="2" border>
-            <el-descriptions-item width="100" label="单据编号">{{ selectedRow.orderid }}</el-descriptions-item>
+            <el-descriptions-item width="100" label="单据编号">{{ selectedRow.orderidstr }}</el-descriptions-item>
             <el-descriptions-item label="送检账户" v-if="selectedRow.gzcjaccounttype === 1">{{ selectedRow.gzcjaccount
             }}</el-descriptions-item>
             <el-descriptions-item label="公司名称(中文)">{{ selectedRow.companynamecn }}</el-descriptions-item>

+ 8 - 1
src/packages/pc/views/customs/exit/components/download/index.vue

@@ -23,7 +23,14 @@ const props = defineProps({
     },
 })
 
-const { loading, dataList, columns, getGZCJBSOrderFileList } = useGZCJBSOrderFileList(props.selectedRow.orderid)
+const orderId = (() => {
+    if ('orderidstr' in props.selectedRow) {
+        return props.selectedRow.orderidstr
+    }
+    return props.selectedRow.orderid
+})()
+
+const { loading, dataList, columns, getGZCJBSOrderFileList } = useGZCJBSOrderFileList(orderId)
 const show = shallowRef(true)
 
 getGZCJBSOrderFileList()

+ 1 - 1
src/packages/pc/views/customs/exit/components/edit/detail-edit/index.vue

@@ -55,7 +55,7 @@
 
 <script lang="ts" setup>
 import { ref, PropType, computed } from 'vue'
-import type { FormInstance, FormRules, } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
 import { useEnumStore } from '@/stores'
 import { getGZCJShapeTypeList, getGZCJMarkTypeList, getGZCJPublishTypeList } from '@/constants/customs'
 import AppDrawer from '@pc/components/base/drawer/index.vue'

+ 1 - 1
src/packages/pc/views/customs/exit/components/edit/index.vue

@@ -282,7 +282,7 @@ const onCancel = (isRefresh = false) => {
 
 const onSubmit = (draft = false) => {
     if (draft) {
-        formData.ApplyType = props.selectedRow?.orderid ? 2 : 1
+        formData.ApplyType = props.selectedRow?.orderidstr ? 2 : 1
     } else {
         formData.ApplyType = 3
     }

+ 1 - 1
src/packages/pc/views/order/main/components/contracted/index.vue

@@ -29,7 +29,7 @@ import type { FormInstance, FormRules } from 'element-plus'
 import { getStepTypeName } from '@/constants/order'
 import { usePerformanceContracted } from '@/business/order'
 import AppDrawer from '@pc/components/base/drawer/index.vue'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 const props = defineProps({
     selectedRow: {

+ 5 - 0
src/packages/pc/views/report/components/daterange/index.less

@@ -0,0 +1,5 @@
+.app-daterange {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+}

+ 81 - 0
src/packages/pc/views/report/components/daterange/index.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="app-daterange">
+        <el-select placeholder="请选择" v-model="selectedType" @change="onSelectChange">
+            <el-option v-for="option in cycleTypes" :key="option.value" :value="option.value" :label="option.label" />
+        </el-select>
+        <el-date-picker :type="datePickerType" placeholder="请选择" range-separator="至" start-placeholder="开始日期"
+            end-placeholder="结束日期" v-model="selectedValue" />
+    </div>
+</template>
+
+<script lang="ts" setup>
+import { PropType, computed } from 'vue'
+import { formatDate } from '@/filters'
+
+const props = defineProps({
+    cycleType: {
+        type: Number,
+        default: 0
+    },
+    dateValue: {
+        type: Array as PropType<string[]>,
+        default: () => ([])
+    }
+})
+
+const emit = defineEmits(['update:cycleType', 'update:dateValue'])
+
+const cycleTypes = [
+    { label: '日报表', type: 'daterange', value: 5 },
+    { label: '月报表', type: 'monthrange', value: 1 },
+    { label: '年报表', type: 'monthrange', value: 3 }
+]
+
+// 日期选择器类型
+const datePickerType = computed(() => {
+    const item = cycleTypes.find((e) => e.value === props.cycleType)
+    return item?.type ?? ''
+})
+
+// 当前选中的周期类型
+const selectedType = computed({
+    get: () => props.cycleType,
+    set: (val) => emit('update:cycleType', val)
+})
+
+// 当前选中的日期值
+const selectedValue = computed<string[]>({
+    get: () => props.dateValue,
+    set: ([begindate, enddate]) => {
+        const value = []
+        if (begindate && enddate) {
+            switch (props.cycleType) {
+                case 1: {
+                    value[0] = formatDate(begindate, 'YYYYMM')
+                    value[1] = formatDate(enddate, 'YYYYMM')
+                    break
+                }
+                case 3: {
+                    value[0] = formatDate(begindate, 'YYYY')
+                    value[1] = formatDate(enddate, 'YYYY')
+                    break
+                }
+                default: {
+                    value[0] = formatDate(begindate, 'YYYYMMDD')
+                    value[1] = formatDate(enddate, 'YYYYMMDD')
+                }
+            }
+        }
+        emit('update:dateValue', value)
+    }
+})
+
+// 切换周期类型
+const onSelectChange = () => {
+    selectedValue.value = []
+}
+</script>
+
+<style lang="less" scoped>
+@import './index.less';
+</style>

+ 14 - 11
src/packages/pc/views/report/member/index.vue

@@ -1,28 +1,31 @@
 <!-- 报表-会员报表 -->
 <template>
     <app-view>
+        <template #header>
+            <app-filter v-bind="{ buttonList }" :loading="loading">
+                <template #before>
+                    <app-date-range v-model:cycleType="cycleType" v-model:dateValue="dateValue" />
+                </template>
+            </app-filter>
+        </template>
         <!-- 表格数据 -->
         <app-table :data="dataList" v-model:columns="columns" :loading="loading">
-            <template #header>
-                <app-auth-operation :menus="['customs_exit_add']" />
-            </template>
-            <!-- 操作 -->
-            <template #operate="{ row }">
-                <app-auth-operation :options="{ selectedRow: row }" @closed="getGZCJJCOrderList" />
-            </template>
             <template #footer>
                 <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
-                    @change="getGZCJJCOrderList" />
+                    @change="getMemberReportList" />
             </template>
         </app-table>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { useCJJCOrderList } from '@/business/customs/exit'
-import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+import { useMemberReportList } from '@/business/report'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppFilter from '@pc/components/base/table-filter/index.vue'
+import AppDateRange from '../components/daterange/index.vue'
+
+const { loading, dataList, columns, total, pageIndex, pageSize, cycleType, dateValue, buttonList, getMemberReportList } = useMemberReportList()
 
-const { loading, dataList, columns, total, pageIndex, pageSize, getGZCJJCOrderList } = useCJJCOrderList()
+getMemberReportList()
 </script>

+ 14 - 11
src/packages/pc/views/report/trade/index.vue

@@ -1,28 +1,31 @@
 <!-- 报表-交易报表 -->
 <template>
     <app-view>
+        <template #header>
+            <app-filter v-bind="{ selectList, buttonList }" :loading="loading">
+                <template #before>
+                    <app-date-range v-model:cycleType="cycleType" v-model:dateValue="dateValue" />
+                </template>
+            </app-filter>
+        </template>
         <!-- 表格数据 -->
         <app-table :data="dataList" v-model:columns="columns" :loading="loading">
-            <template #header>
-                <app-auth-operation :menus="['customs_exit_add']" />
-            </template>
-            <!-- 操作 -->
-            <template #operate="{ row }">
-                <app-auth-operation :options="{ selectedRow: row }" @closed="getGZCJJCOrderList" />
-            </template>
             <template #footer>
                 <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
-                    @change="getGZCJJCOrderList" />
+                    @change="getTradeReportList" />
             </template>
         </app-table>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { useCJJCOrderList } from '@/business/customs/exit'
-import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+import { useTradeReportList } from '@/business/report'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppFilter from '@pc/components/base/table-filter/index.vue'
+import AppDateRange from '../components/daterange/index.vue'
+
+const { loading, dataList, columns, total, pageIndex, pageSize, cycleType, dateValue, selectList, buttonList, getTradeReportList } = useTradeReportList()
 
-const { loading, dataList, columns, total, pageIndex, pageSize, getGZCJJCOrderList } = useCJJCOrderList()
+getTradeReportList()
 </script>

+ 14 - 11
src/packages/pc/views/report/warehousing/index.vue

@@ -1,28 +1,31 @@
 <!-- 报表-仓储报表 -->
 <template>
     <app-view>
+        <template #header>
+            <app-filter v-bind="{ selectList, buttonList }" :loading="loading">
+                <template #before>
+                    <app-date-range v-model:cycleType="cycleType" v-model:dateValue="dateValue" />
+                </template>
+            </app-filter>
+        </template>
         <!-- 表格数据 -->
         <app-table :data="dataList" v-model:columns="columns" :loading="loading">
-            <template #header>
-                <app-auth-operation :menus="['customs_exit_add']" />
-            </template>
-            <!-- 操作 -->
-            <template #operate="{ row }">
-                <app-auth-operation :options="{ selectedRow: row }" @closed="getGZCJJCOrderList" />
-            </template>
             <template #footer>
                 <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
-                    @change="getGZCJJCOrderList" />
+                    @change="getWarehousingReportList" />
             </template>
         </app-table>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { useCJJCOrderList } from '@/business/customs/exit'
-import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+import { useWarehousingReportList } from '@/business/report'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppFilter from '@pc/components/base/table-filter/index.vue'
+import AppDateRange from '../components/daterange/index.vue'
+
+const { loading, dataList, columns, total, pageIndex, pageSize, cycleType, dateValue, selectList, buttonList, getWarehousingReportList } = useWarehousingReportList()
 
-const { loading, dataList, columns, total, pageIndex, pageSize, getGZCJJCOrderList } = useCJJCOrderList()
+getWarehousingReportList()
 </script>

+ 6 - 2
src/packages/pc/views/warehousing/goods/components/edit/diamond.vue

@@ -99,7 +99,7 @@
             <el-input placeholder="请输入" v-model="formData.CerNo" />
         </el-form-item>
         <el-form-item label="商品照片" prop="ImagePath">
-            <app-upload />
+            <app-upload :file-types="['image']" type-message="请选择正确的图片类型" @change="onUploadChange" />
         </el-form-item>
         <el-form-item class="el-form-item--row" label="备注" prop="Remark">
             <el-input type="textarea" v-model="formData.Remark" />
@@ -113,7 +113,7 @@ import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/diamond'
 import { useDiamondForm } from '@/business/goods'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 defineProps({
     code: String,
@@ -181,6 +181,10 @@ const shapeChange = (value: number) => {
     }
 }
 
+const onUploadChange = (file: { filePath: string }) => {
+    formData.ImagePath = file.filePath
+}
+
 const onSubmit = () => {
     formRef.value?.validate((valid) => {
         if (valid) {

+ 1 - 1
src/packages/pc/views/warehousing/goods/components/edit/diamonds.vue

@@ -85,7 +85,7 @@ import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/diamond'
 import { useDiamondForm } from '@/business/goods'
 import AppMultiple from '@pc/components/base/multiple/index.vue'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 defineProps({
     code: String,

+ 1 - 1
src/packages/pc/views/warehousing/goods/components/edit/fancy.vue

@@ -117,7 +117,7 @@ import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/diamond'
 import { useDiamondForm } from '@/business/goods'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 defineProps({
     code: String,

+ 1 - 1
src/packages/pc/views/warehousing/goods/components/edit/jewelry.vue

@@ -122,7 +122,7 @@ import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/diamond'
 import { useDiamondForm } from '@/business/goods'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 defineProps({
     code: String,

+ 1 - 1
src/packages/pc/views/warehousing/goods/components/edit/rough.vue

@@ -91,7 +91,7 @@ import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/diamond'
 import { useDiamondForm } from '@/business/goods'
 import AppMultiple from '@pc/components/base/multiple/index.vue'
-import AppUpload from '@/components/base/upload/index.vue'
+import AppUpload from '@pc/components/base/upload/index.vue'
 
 defineProps({
     code: String,

+ 7 - 0
src/services/api/common/index.ts

@@ -2,6 +2,13 @@ import { httpRequest } from '@/services/http'
 import { HttpParams } from '@/services/http/interface'
 
 /**
+ * 查询市场运行信息
+ */
+export function queryMarketRun(params: HttpParams<{ req: Ermcp.MarketRunReq, rsp: Ermcp.MarketRunRsp[] }>) {
+    return httpRequest('/Market/QueryMarketRun', 'get', params);
+}
+
+/**
  * 首页统计数据
  */
 export function homeData(params: HttpParams<{ req: Ermcp.HomeDataReq, rsp: Ermcp.HomeDataRsp }>) {

+ 23 - 0
src/services/api/report/index.ts

@@ -0,0 +1,23 @@
+import { httpRequest } from '@/services/http'
+import { HttpParams } from '@/services/http/interface'
+
+/**
+ * 查询会员报表
+ */
+export function queryMemberReport(params: HttpParams<{ req: Ermcp.MemberReportReq, rsp: Ermcp.MemberReportRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryMemberReport', 'get', params);
+}
+
+/**
+ * 查询仓储报表
+ */
+export function queryWRPositionReport(params: HttpParams<{ req: Ermcp.WRPositionReportReq, rsp: Ermcp.WRPositionReportRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryWRPositionReport', 'get', params);
+}
+
+/**
+ * 查询交易报表
+ */
+export function queryTradeReport(params: HttpParams<{ req: Ermcp.TradeReportReq, rsp: Ermcp.TradeReportRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryTradeReport', 'get', params);
+}

+ 1 - 1
src/shims-vue.d.ts

@@ -17,5 +17,5 @@ declare module 'worker-loader!*' {
   export default WebpackWorker;
 }
 
-declare module 'mockjs'
+declare module 'mockjs-x'
 declare module 'protobufjs'

+ 1 - 1
src/stores/modules/enum.ts

@@ -17,7 +17,7 @@ interface StoreState {
     allEnums: ShallowRef<Ermcp.EnumRsp[]>;
 }
 
-const enumKeys = ['ZSCategory', 'ZSCurrencyType', 'ZSCurrencyType', 'ZSColorType', 'ZSClarityType', 'ZSCutType', 'ZSShapeType', 'ZSSymmetryType', 'ZSPolishType', 'ZSFluorescenceType', 'ZSCertType', 'ZSCrystalType', 'ZSCZColor1Type', 'ZSCZColor2Type', 'ZSCZColor3Type', 'ZSStyleType', 'signstatus', 'applystatus', 'executetype', 'certificatetype', 'clientType', 'wrApplyStatus', 'performanceStatus', 'stepStatus', 'GZCJAccountType', 'GZCJCategoryType', 'GZCJDeliveryType', 'GZCJShapeType', 'GZCJMarkType', 'GZCJPublishType', 'GZCJServiceType', 'GZCJStatus', 'GZBSStatus'] as const
+const enumKeys = ['ZSCategory', 'ZSCurrencyType', 'ZSCurrencyType', 'ZSColorType', 'ZSClarityType', 'ZSCutType', 'ZSShapeType', 'ZSSymmetryType', 'ZSPolishType', 'ZSFluorescenceType', 'ZSCertType', 'ZSCrystalType', 'ZSCZColor1Type', 'ZSCZColor2Type', 'ZSCZColor3Type', 'ZSStyleType', 'signstatus', 'applystatus', 'executetype', 'certificatetype', 'clientType', 'wrApplyStatus', 'performanceStatus', 'stepStatus', 'GZCJAccountType', 'GZCJCategoryType', 'GZCJDeliveryType', 'GZCJShapeType', 'GZCJMarkType', 'GZCJPublishType', 'GZCJServiceType', 'GZCJStatus', 'GZBSStatus', 'GZBSDeliveryType'] as const
 
 /**
  * 枚举存储类

+ 23 - 0
src/types/ermcp/common.d.ts

@@ -119,4 +119,27 @@ declare namespace Ermcp {
         paramname: string; // 参数名称
         updatetime: string; // 更新时间
     }
+
+    /** 查询市场运行信息 请求 */
+    interface MarketRunReq {
+        marketID?: number; // 市场ID,不传返回所有
+    }
+
+    /** 查询市场运行信息 响应 */
+    interface MarketRunRsp {
+        afternexttradedate: string; // 下下交易日
+        clearquoteflag: number; // 行情清盘标志- 1:未发送 2:已发送 3:已回复
+        lastreckondate: string; // 最新交易日(结算成功)
+        machinedate: string; // 机器时间
+        manualflag: number; // 手动开市标志- 0:否 1:是 (市场为手动时,是否触发了手动开市标志)
+        marketid: number; // 市场ID
+        nexttradedate: string; // 下一交易日
+        pretradedate: string; // 上一交易日
+        reckonflag: number; // 结算标识 - 0: 停止结算 1: 正常(管理端控制此字段,交易服务根据此字段判断是否做结算)
+        runstatus: number; // 运行状态 - 0:初始化 1:待开市 2:开市 3:休市 4:手工休市 5:闭市 6:确认行权开始 7:确认行权结束 10:日终处理开始 11:日终处理成功 12:日终处理失败 13基础服务结算开始 14基础服务结算成功 23.资金结算开始 24.资金结算成功 25.资金结算失败 26.系统结算成功 27.系统结算失败 28.盘中处理开始 29.盘中处理成功 30.盘中处理失败 31.资金结算开始(内) 32.资金结算成功(内) 33.资金结算失败(内) 40.签到开始 41.签到成功 42.签到部份成功 43.签到失败 44.签退开始 45.签退成功 46.签退部份成功 47.签退失败 48.对账开始 49.对账成功 50.对账失败 51.清算开始 52.清算成功 53.清算失败 54.清算部分成功 55. 系统结算开始 62.今日免清算
+        sectionid: number; //时间段号[多时段时用]
+        tradedate: string; // 当前交易日(服务) 资金结算完成即变更,供交易服务使用
+        tradedate2: string; // 当前交易日(行情) 在第一个市场待开市时变更为TradeDate,供行情及终端系统使用
+        updatetime: string; // 更新时间
+    }
 }

+ 5 - 4
src/types/ermcp/customs.d.ts

@@ -33,6 +33,7 @@ declare namespace Ermcp {
         handlestatus: number; // 处理状态
         invoiceremark: string; // 复核备注 - 发票装箱单使用
         orderid: number; // 单据ID(801+Unix秒时间戳(10位)+xxxxxx)
+        orderidstr: string; // 单据ID 字符(801+Unix秒时间戳(10位)+xxxxxx)
         orderno: string; // 单据编号 - 合同编号:GZDECJJC+单据流水号
         ordersn: string; // 单据流水号 - yymm000 - yy表示年份,mm表示月份,年份、月份以两位数表示;000表示流水序号,序号不足三位以0补全
         origincountry: string; // 原产国
@@ -54,7 +55,7 @@ declare namespace Ermcp {
     /** 查询出境检测单据明细(批次信息) 请求 */
     interface GZCJJCOrderDetailReq {
         userid: number; // 用户ID
-        orderid?: number; // 单据ID
+        orderid?: string; // 单据ID
         page?: number; // 页码
         pagesize?: number; // 每页条数
     }
@@ -108,7 +109,7 @@ declare namespace Ermcp {
         gzbsstatusdisplay: string; // 单据状态
         handlestatus: number; // 处理状态
         orderdate: string; // 单据日期
-        orderid: number; // 单据ID(804+Unix秒时间戳(10位)+xxxxxx)
+        orderid: string; // 单据ID(804+Unix秒时间戳(10位)+xxxxxx)
         orderno: string; // 单据编号 - GZDEBSFW+单据流水号
         ordersn: string; // 单据流水号 - yymm000 - yy表示年份,mm表示月份,年份、月份以两位数表示;000表示流水序号,序号不足三位以0补全
         origincountry: string; // 原产国
@@ -156,7 +157,7 @@ declare namespace Ermcp {
     /** 查询保税服务单据明细 请求 */
     interface GZBSFWOrderDetailReq {
         userid: number; // 用户ID
-        orderid?: number; // 单据ID
+        orderid?: string; // 单据ID
         page?: number; // 页码
         pagesize?: number; // 每页条数
     }
@@ -180,7 +181,7 @@ declare namespace Ermcp {
 
     /** 出境保税单据文件 请求 */
     interface GZCJBSOrderFileReq {
-        orderid: number; // 单据ID
+        orderid: string; // 单据ID
         page?: number; // 页码
         pagesize?: number; // 每页条数
     }

+ 191 - 0
src/types/ermcp/report.d.ts

@@ -0,0 +1,191 @@
+declare namespace Ermcp {
+    /** 查询会员报表 请求 */
+    interface MemberReportReq {
+        userid: number; // 用户ID
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        cycletype?: string; // 周期类型 - 1:月 2:季 3:年 4:周 5:全报表 (日报表不传此参数)
+        begindate: string; // 开始时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+        enddate: string; // 结束时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+    }
+
+    /** 查询会员报表 响应 */
+    interface MemberReportRsp {
+        accountid: number; // 资金账户ID
+        accountname: string; // 账户名称
+        accountpl: number; // 今日账户盈亏 = 今日净值-昨日净值+今日出金-今日入金-今日划转+今日授信减少-今日授信增加+今日其它授信减少-今日其它授信增加+今日三方出金-今日三方入金;由统计服务更新
+        avaiablemoney: number; // 可用资金
+        avaiableoutmoney: number; // 可出资金
+        balance: number; // 期初余额
+        capitalbalance: number; // 本金余额[外部子账户实际出入金余额]
+        changeflag: number; // 变动标志(当前账户资金有任何变动更新为1系统结算时更新0;供清算时使用) 0:无变动 1:有变动
+        clearbalance: number; // 清算余额 = 期末余额 - 授信金额 - 其它授信金额
+        clearpl: number; // 真实资金变动值(除出入金、应付交易所手续费)清算盈亏 = 期末余额 - 期初余额 - (今日入金 + 今日出金) - 今日应付交易所手续费 - 【(今日授信增加 + 今日授信减少) - (今日其它授信增加 + 今日其它授信减少) ----母账户】 = 今日手续费支出 + 今日平仓盈亏 + 今日结算盈亏 + 其他支出 + 其他收入 + 今日划转金额 + 今日已收手续费分成 - 今日应付交易所手续费
+        closepl: number; // 今日平仓盈亏
+        closepl2: number; // 平仓盈亏(逐笔)
+        creditdecrease: number; // 今日授信减少
+        creditincrease: number; // 今日授信增加
+        curdebt: number; // 期末欠款
+        currencyid: number; // 货币ID
+        currentbalance: number; // 期末余额
+        cycletype: number; // 周期类型 - 1:月 2:季 3:年 4:周 5:全报表 (日报表不传此参数)
+        defercharge: number; // 今日递延费2支出[111, 112]
+        deliveryamountin: number; // 今日交收货款收入
+        deliveryamountout: number; // 今日交收货款支出
+        deliverycharge: number; // 今日交收手续费支出 [105,106]
+        deliverycompensationfeein: number; // 今日交收补偿费收入
+        deliverycompensationfeeout: number; // 今日交收补偿费支出
+        dividedcharge: number; // 今日已收手续费分成
+        floatnetvalue: number; // 浮动净值 = 净值 + 浮动盈亏
+        floatpl: number; // 浮动盈亏 - 每日有负债类商品
+        freezecharge: number; // 手续费冻结
+        freezemargin: number; // 冻结保证金
+        fromaccountid: number; // 所属上级账户
+        holdcharge: number; // 今日持仓过夜费支出[108,109,110]
+        inamount: number; // 今日入金金额
+        interestcharge: number; // 今日递延费支出[103, 104]
+        ismain: number; // 是否账号 0:不是母账户 1:是母账户
+        ismarketaccount: number; // 是否机构接单账号 0:不是 1:是
+        isreckonaccount: number; // 是否机构分润账号 0:不是 1:是
+        mortgagecredit: number; // 授信金额
+        netvalue: number; // 净值 = 期末余额 + 所有权市值 + 仓单市值仓单市值由统计服务更新
+        oridebt: number; // 期初欠款
+        orifreezecharge: number; // 期初手续费冻结
+        orifreezemargin: number; // 期初冻结保证金
+        orimortgagecredit: number; // 期初授信金额
+        oriothercredit: number; // 期初其它授信金额
+        oriotherfreezemargin: number; // 期初其他冻结保证金(出金冻结资金 交割买方冻结 申购冻结 全款买入 商城买入)
+        orioutamountfreeze: number; // 期初出金冻结
+        oriusedmargin: number; // 期初占用保证金
+        othercredit: number; // 其它授信金额
+        othercreditdecrease: number; // 今日其它授信减少
+        othercreditincrease: number; // 今日其它授信增加
+        otherfreezemargin: number; // 其他冻结保证金(出金冻结资金 交割买方冻结 申购冻结 全款买入 商城买入)
+        otherincome: number; // 其他收入(交割收款 申购收款 全款卖出 商城卖出 买家退货 会员手续费收入)
+        otherpay: number; // 其他支出(交割付款 申购付款 全款买入 商城买入 卖家退货)
+        outamount: number; // 今日出金金额
+        outamountfreeze: number; // 出金冻结
+        outthreshold: number; // 出金阈值
+        ownershipvalue: number; // 所有权市值
+        parentaccountid: number; // 所属根账户
+        password: string; // 资金密码
+        paycharge: number; // 今日手续费支出
+        paycharge2: number; // 今日手续费支出(外部配置)
+        payexchcharge: number; // 今日应付交易所手续费
+        reckondate: string; // 日照日期(yyyyMMdd)
+        reckonpl: number; // 今日结算盈亏
+        reckonpl2: number; // 结算盈亏(逐笔) - 汇总取期末
+        relatedaccountstatus: number; // 关联用户交易状态 - 1:正常(可交易) 2:受限(可平仓,不可建仓) 3:冻结(不可交易)
+        relateuserid: number; // 关联用户
+        riskrate: number; // 风险率 = 占用/ 浮动净值 或 浮动净值/占用
+        signstatus: number; // 签约状态 - 1:未签约 2:已签约 3:已解约
+        spotvalue: number; // 现货市值-统计服务更新
+        sublevelpath: string; // 账号层级路径(逗号分隔,首尾加逗号)
+        taaccounttype: number; // 外部/内部账号 - 1:外部账号 2:内部账号
+        thirdinamount: number; // 今日三方入金
+        thirdoutamount: number; // 今日三方出金
+        tradeamount: number; // 今日成交金额
+        tradecharge: number; // 今日交易手续费支出 [101,102]
+        tradeqty: number; // 今日成交量
+        tradestatus: number; // 交易状态 - 1:正常 2:受限 3:冻结 4:禁止建仓(人工受限) 5:禁止交易(人工冻结)
+        transferamount: number; // 今日划转金额(母子账号资金划转,从账号划入为正,从账号划出为负)
+        usedmargin: number; // 占用保证金
+        userid: number; // 用户ID
+    }
+
+    /** 查询仓储报表 请求 */
+    interface WRPositionReportReq {
+        userid: number; // 用户ID
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        cycletype?: string; // 周期类型 - 1:月 2:季 3:年 4:周 5:全报表 (日报表不传此参数)
+        begindate: string; // 开始时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+        enddate: string; // 结束时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+        zscategory?: number; // 商品分类
+        zscurrencytype?: number; // 商品币种
+    }
+
+    /** 查询仓储报表 响应 */
+    interface WRPositionReportRsp {
+        accountid: number; // 帐户ID
+        brandid: number; // 品牌ID(1交割品种升贴水参数表 AutoID) - 作废
+        buylistinglot: number; // 买挂牌宗数
+        buytradeamount: number; // 购买金额
+        buytradelot: number; // 购买宗数
+        buytradeqty: number; // 购买数量
+        creditcurqty: number; // 授信当前数量
+        creditfreezeqty: number; // 授信冻结数量
+        credittotalqty: number; // 授信总数量
+        credittradeqty: number; // 授信成交数量
+        decreaseqty: number; // 今日减少数量
+        deliverygoodsid: number; // 交割商品ID
+        deliverymonthid: number; // 月份ID(1交割品种升贴水参数表 AutoID) - 作废
+        freezeqty: number; // 总冻结数量
+        increaseqty: number; // 今日增加数量
+        marketvalue: number; // 市值
+        pickupqty: number; // 今日提货数量
+        qualityid: number; // 品质ID(1交割品种升贴水参数表 AutoID) - 作废
+        reckondate: string; // 日照时期(yyyyMMdd)
+        relatedqty: number; // 关联数量
+        selllistingamount: number; // 卖挂牌金额
+        selllistinglot: number; // 卖挂牌宗数
+        selllistingqty: number; // 卖挂牌数量
+        selltradeamount: number; // 销售金额
+        selltradelot: number; // 销售宗数
+        selltradeqty: number; // 销售数量
+        specid: number; // 规格ID(1交割品种升贴水参数表 AutoID) - 作废
+        totalprice: number; // 销售金额(¥)
+        totalqty: number; // 总数量
+        totalweight: number; // 销售重量(ct)
+        tradewrqty: number; // 订单仓单头寸总数量
+        transfertradewrqty: number; // 今日转订单数量
+        warehouseid: number; // 仓库ID(1交割品种升贴水参数表 AutoID) - 作废
+        wrfactortypeid: number; // 仓单要素类型ID
+        wrpositionid: number; // 仓单头寸ID(201+Unix秒时间戳(10位)+xxxxxx)
+        wrstandardcode: string; // 现货商品代码
+        wrstandardid: number; // 现货商品ID
+        wruserid: number; // 持有人ID
+        zscategory: number; // 商品分类
+        zscategorydisplay: string;
+        zscurrencytype: number; // 商品币种
+        zscurrencytypedisplay: string;
+        zscurrencytypedisplayunit: string;
+    }
+
+    /** 查询交易报表 请求 */
+    interface TradeReportReq {
+        userid: number; // 用户ID
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        cycletype?: string; // 周期类型 - 1:月 2:季 3:年 4:周 5:全报表 (日报表不传此参数)
+        begindate: string; // 开始时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+        enddate: string; // 结束时段(日报表:yyyymmdd 月报表:yyyymm 年报表:yyyy)
+        zscategory?: number; // 商品分类
+        zscurrencytype?: number; // 商品币种
+    }
+
+    /** 查询交易报表 响应 */
+    interface TradeReportRsp {
+        buylistingamount: number; // 买挂牌金额 - 无数据,预留
+        buylistinglot: number; // 买挂牌宗数
+        buylistingqty: number; // 买挂牌数量 - 无数据,预留
+        buytradeamount: number; // 购买金额
+        buytradelot: number; // 购买宗数
+        buytradeqty: number; // 购买数量
+        marketid: number; // 市场ID
+        reckondate: string; // 日照日期(yyyyMMdd)
+        selllistingamount: number; // 卖挂牌金额
+        selllistinglot: number; // 卖挂牌宗数
+        selllistingqty: number; // 卖挂牌数量
+        selltradeamount: number; // 销售金额
+        selltradelot: number; // 销售宗数
+        selltradeqty: number; // 销售数量
+        updatetime: string; // 更新时间
+        userid: number; // 用户ID
+        zscategory: number; // 钻石分类 - 枚举”ZSCategory“
+        zscategorydisplay: string;
+        zscurrencytype: number; // 货币类型 - 枚举“ZSCurrencyType”
+        zscurrencytypedisplay: string;
+        zscurrencytypedisplayunit: string;
+    }
+}

+ 4 - 4
src/types/proto/customs.d.ts

@@ -48,7 +48,7 @@ declare global {
             GZCJDeliveryType: number; // 收货方式,必填
             GZCJCategoryDetails: GZCJCategoryDetail[]; // 货物明细列表
             ApplyType: number; // 申请类型1:保存草稿2:修改草稿
-            OrderID: number; // 单据ID,ApplyType=2,3时,有则填
+            OrderID: Long; // 单据ID,ApplyType=2,3时,有则填
             ClientType: number; // 终端类型
             ClientSerialNo: string; // 客户端流水号
         }
@@ -70,7 +70,7 @@ declare global {
             UserID: number; // 用户ID,必填
             OperateID: number; // 操作人ID,必填,LoginAccount的LoginID
             OperateAccount: string; // 操作人账户,LoginAccount的LoginCode,LoginCode为空则填LoginID,必
-            OrderID: number; // 单据ID,必填
+            OrderID: Long; // 单据ID,必填
             OperateType: number; // 操作类型,必填,1:撤回2:确认发货3:确认检测结果
             Remark?: string; // 备注
             ClientType: number; // 终端类型
@@ -90,7 +90,7 @@ declare global {
         /** 出境检测确认预付款生成文件接口请求 */
         interface CJJCConfirmMarginBuildFileReq {
             Header?: IMessageHead;
-            OrderID: number; // 单据ID,必填
+            OrderID: Long; // 单据ID,必填
         }
 
         /** 出境检测确认预付款生成文件接口响应 */
@@ -108,7 +108,7 @@ declare global {
             UserID: number; // 用户ID,必填
             OperateID: number; // 操作人ID,必填,LoginAccount的LoginID
             OperateAccount: string; // 操作人账户,LoginAccount的LoginCode,LoginCode为空则填LoginID,必
-            OrderID: number; // 单据ID,必填
+            OrderID: Long; // 单据ID,必填
             OperateType: number; // 操作类型,必填,1:上传发货单2:上传盖章单据3:确认预付款
             FileDetails: FileDetail[]; // 文件列表
             Remark: string; // 备注