li.shaoyi il y a 3 ans
Parent
commit
2579525167
50 fichiers modifiés avec 2275 ajouts et 369 suppressions
  1. 40 6
      public/proto/gz.proto
  2. 63 21
      src/business/goods/index.ts
  3. 538 10
      src/business/order/index.ts
  4. 2 1
      src/business/sign/index.ts
  5. 8 1
      src/business/warehouse/index.ts
  6. 3 17
      src/components/base/modal/index.less
  7. 14 13
      src/components/base/modal/index.vue
  8. 26 0
      src/constants/enum/client.ts
  9. 18 2
      src/constants/enum/diamond.ts
  10. 2 0
      src/constants/enum/funcode.ts
  11. 29 19
      src/hooks/datatable/index.ts
  12. 12 11
      src/hooks/datatable/interface.ts
  13. 55 1
      src/mock/router.ts
  14. 8 1
      src/packages/mobile/components/modules/trade/index.less
  15. 10 6
      src/packages/mobile/components/modules/trade/index.vue
  16. 31 18
      src/packages/pc/assets/themes/default/default.less
  17. 28 16
      src/packages/pc/components/base/drawer/index.less
  18. 18 12
      src/packages/pc/components/base/drawer/index.vue
  19. 1 1
      src/packages/pc/components/base/pagination/index.less
  20. 2 2
      src/packages/pc/components/base/pagination/index.vue
  21. 1 1
      src/packages/pc/components/base/table-filter/index.less
  22. 9 5
      src/packages/pc/components/base/table-filter/index.vue
  23. 2 3
      src/packages/pc/components/base/table/index.less
  24. 1 1
      src/packages/pc/components/base/table/index.vue
  25. 0 52
      src/packages/pc/components/layouts/main/index.less
  26. 16 27
      src/packages/pc/components/layouts/main/index.vue
  27. 7 2
      src/packages/pc/components/modules/performance/index.vue
  28. 1 1
      src/packages/pc/router/index.ts
  29. 10 11
      src/packages/pc/views/listing/buy/components/add/index.vue
  30. 14 63
      src/packages/pc/views/listing/buy/index.vue
  31. 9 0
      src/packages/pc/views/listing/delisting/index.vue
  32. 9 0
      src/packages/pc/views/listing/inquire/index.vue
  33. 33 0
      src/packages/pc/views/listing/purchase/index.vue
  34. 33 0
      src/packages/pc/views/listing/sale/index.vue
  35. 72 0
      src/packages/pc/views/listing/sell/components/add/index.vue
  36. 31 1
      src/packages/pc/views/listing/sell/index.vue
  37. 4 3
      src/packages/pc/views/system/menu/components/edit/index.vue
  38. 201 1
      src/packages/pc/views/warehousing/stock/components/edit/diamond.vue
  39. 31 13
      src/packages/pc/views/warehousing/stock/components/edit/diamonds.vue
  40. 214 1
      src/packages/pc/views/warehousing/stock/components/edit/fancy.vue
  41. 11 4
      src/packages/pc/views/warehousing/stock/components/edit/index.vue
  42. 212 1
      src/packages/pc/views/warehousing/stock/components/edit/jewelry.vue
  43. 181 1
      src/packages/pc/views/warehousing/stock/components/edit/rough.vue
  44. 7 6
      src/packages/pc/views/warehousing/stock/index.vue
  45. 8 9
      src/packages/pc/views/warehousing/warehouse/components/edit/index.vue
  46. 5 3
      src/packages/pc/views/warehousing/warehouse/index.vue
  47. 28 0
      src/services/api/order/index.ts
  48. 182 2
      src/types/ermcp/order.d.ts
  49. 2 0
      src/types/proto/goods.d.ts
  50. 33 0
      src/types/proto/order.d.ts

+ 40 - 6
public/proto/gz.proto

@@ -250,12 +250,14 @@ message GZWRStandardExInfo {
 message AddZSGoodsReq {
 	optional MessageHead Header = 1;
 	optional uint64 UserID = 2; // 用户ID,必填
-	optional uint64 AccountID = 3; // 资金账户ID
-	optional GZWRStandardExInfo GZ_WRStandardExInfo = 4; // 钻石属性,对象中前4个字段必填
-	optional uint32 AddType = 5; // 类型1:新增商品2:新增并上架,必填
-	optional int32 PerformanceTemplateID = 6; // 履约模板ID,如果AddType=2时必填
-	optional uint64 MarketID = 7; // 市场ID必填
-	optional string ClientSerialNo = 8; // 客户端流水号
+		optional uint64 AccountID = 3; // 资金账户ID
+		optional GZWRStandardExInfo GZ_WRStandardExInfo = 4; // 钻石属性,对象中前4个字段必填
+		optional uint32 AddType = 5; // 类型1:新增商品2:新增并上架,必填
+		optional int64 PerformanceTemplateID = 6; // 履约模板ID,如果AddType=2时必填
+		optional uint64 MarketID = 7; // 市场ID必填
+		optional uint32 ClientType = 8; // 终端类型
+		optional uint32 OrderSrc = 9; // 委托来源
+		optional string ClientSerialNo = 10; // 客户端流水号
 }
 
 // 新增钻石商品接口响应
@@ -319,4 +321,36 @@ message ZSBuyOrderListingRsp {
 		optional uint64 WRTradeOrderID = 6; // 仓单贸易委托单ID
 		optional string OrderTime = 7; // 接收委托交易的时间
 		optional string ClientSerialNo = 8; // 客户端流水号
+}
+
+// 钻石卖挂牌接口请求
+message ZSSellOrderListingReq {
+	optional MessageHead Header = 1;
+		optional uint64 UserID = 2; // 用户ID,必填
+		optional uint64 AccountID = 3; // 资金账户ID,必填
+		optional uint64 WRStandardID = 4; // 现货商品ID,必填
+		optional uint64 WRFactorTypeID = 5; // 仓单要素类型ID,必填
+		optional double OrderQty = 6; // 挂牌数量,必填2位小数,为WeigthAvg的整数倍
+		optional uint64 LadingBillID = 7; // 提单ID,必填
+		optional uint32 SubNum = 8; // 提单子单号,必填
+		optional int64 PerformanceTemplateID = 9; // 履约计划模板ID
+		optional uint32 TimevalidType = 10; // 时间有效类型
+		optional string ValidTime = 11; // 有效期限
+		optional uint32 OrderSrc = 12; // 委托来源
+		optional string ClientSerialNo = 13; // 客户端流水号
+		optional string ClientOrderTime = 14; // 客户端委托时间
+		optional uint32 ClientType = 15; // 终端类型
+		optional uint64 MarketID = 16; // 市场ID,必填
+}
+// 钻石卖挂牌接口响应
+message ZSSellOrderListingRsp {
+	optional MessageHead Header = 1; // 消息头
+	optional int32 RetCode = 2; // 返回码
+	optional string RetDesc = 3; // 描述信息
+		optional uint32 UserID = 4; // 用户ID
+		optional uint64 AccountID = 5; // 资金账号
+		optional uint64 WRTradeOrderID = 6; // 仓单贸易委托单ID
+		optional uint64 FreezeQty = 7; // 冻结数量
+		optional string OrderTime = 8; // 接收委托交易的时间
+		optional string ClientSerialNo = 9; // 客户端流水号
 }

+ 63 - 21
src/business/goods/index.ts

@@ -2,6 +2,7 @@ import { shallowRef, reactive, computed } from 'vue'
 import { v4 } from 'uuid'
 import { useDataTable } from '@/hooks/datatable'
 import { formatDecimal } from '@/filters'
+import { ClientType } from '@/constants/enum/client'
 import { Market } from '@/constants/enum/market'
 import { queryWarehouseInfo } from '@/services/api/warehouse'
 import { addZSGoods, queryDiamondList } from '@/services/api/goods'
@@ -18,15 +19,18 @@ import {
     getSymmetryTypeList,
     getFluorescenceTypeList,
     getCurrencyTypeInfo,
+    getCertTypeList,
+    getCrystalTypeList,
+    getStyleTypeList,
+    getFancyColorType1List,
+    getFancyColorType2List,
+    getFancyColorType3List,
 } from '@/constants/enum/diamond'
 
 export function useDiamond() {
-    const { dataList, inputList, selectList, buttonMap, getQueryParam } = useDataTable<Ermcp.MyWRPositionRsp>()
+    const { UserID } = sessionData.getValue('loginInfo')
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam } = useDataTable<Ermcp.MyWRPositionRsp>()
     const loading = shallowRef(false)
-    const total = shallowRef(0)
-    const pageIndex = shallowRef(1)
-    const pageSize = shallowRef(20)
-    const selectedCategoryId = shallowRef(Category.Diamonds) // 当前选中钻石分类
 
     const columns = shallowRef<Ermcp.TableColumn[]>([
         {
@@ -95,18 +99,24 @@ export function useDiamond() {
     ])
 
     const getDiamondList = () => {
+        const param = getQueryParam()
         loading.value = true
         return queryDiamondList({
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                wruserid: sessionData.getLoginInfo('UserID'),
-                zscategory: selectedCategoryId.value
+                wruserid: UserID,
+                zscategory: selectList.value[0].selectedValue as Ermcp.MyWRPositionRsp['zscategory'],
+                zsallproperties: param.goodsno,
+                warehouseid: param.warehouseid,
             },
             success: (res) => {
                 total.value = res.total
                 dataList.value = res.data
             },
+            fail: () => {
+                dataList.value = []
+            },
             complete: () => {
                 loading.value = false
             }
@@ -117,7 +127,7 @@ export function useDiamond() {
         {
             label: '商品分类',
             key: 'zscategory',
-            selectedValue: selectedCategoryId.value,
+            selectedValue: Category.Diamonds,
             options: getCategoryList(),
         },
         {
@@ -128,12 +138,38 @@ export function useDiamond() {
     ]
 
     inputList.value = [
-        { label: '商品', keys: ['goodsno', 'zsshapetypedisplay'] },
+        { label: '商品', keys: ['goodsno'] },
     ]
 
-    buttonMap.get('search')!.onClick = () => {
-        const param = getQueryParam()
+    const [reset, search] = buttonList.value
+    reset.onClick = () => {
+        selectList.value.forEach((e, i) => {
+            if (i) {
+                e.selectedValue = undefined
+            }
+        })
+        inputList.value.forEach((e) => e.value = undefined)
+        getDiamondList()
     }
+    search.onClick = getDiamondList
+
+    // 获取仓库列表
+    queryWarehouseInfo({
+        data: {
+            userid: UserID,
+            status: 1,
+            isincludeexchange: true,
+        },
+        success: (res) => {
+            const warehouse = selectList.value[1]
+            res.data.forEach((e) => {
+                warehouse.options.push({
+                    label: e.warehousename,
+                    value: e.autoid
+                })
+            })
+        }
+    })
 
     return {
         loading,
@@ -144,7 +180,7 @@ export function useDiamond() {
         columns,
         inputList,
         selectList,
-        buttonMap,
+        buttonList,
         getDiamondList,
     }
 }
@@ -153,19 +189,14 @@ export function useDiamondForm(category: Category) {
     const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
     const loading = shallowRef(false)
     const warehouseList = shallowRef<Ermcp.WarehouseInfoRsp[]>([]) // 仓库列表
+    const performanceId = shallowRef<number>() // 选中的履约模板ID
+    const shapeId = shallowRef<number>() // 选中的形状ID
     const formItem = reactive<Partial<Proto.GZWRStandardExInfo>>({
         ZSCategory: category,
-        GoodsNo: '',
     })
 
     // 选中的枚举类型
     const selectedType = reactive({
-        shapeType: computed({
-            get: () => formItem.ZSShapeType,
-            set: (val) => {
-                formItem.ZSShapeType = val
-            }
-        }),
         colorType: computed({
             get: () => [formItem.ZSColorType1, formItem.ZSColorType2],
             set: (val) => {
@@ -220,6 +251,12 @@ export function useDiamondForm(category: Category) {
         polishTypeList: getPolishTypeList(),
         symmetryTypeList: getSymmetryTypeList(),
         fluorescenceTypeList: getFluorescenceTypeList(),
+        certTypeList: getCertTypeList(),
+        crystalTypeList: getCrystalTypeList(),
+        styleTypeList: getStyleTypeList(),
+        fancyColorType1List: getFancyColorType1List(),
+        fancyColorType2List: getFancyColorType2List(),
+        fancyColorType3List: getFancyColorType3List(),
     }
 
     if (enums.currencyTypeList.length) {
@@ -238,16 +275,19 @@ export function useDiamondForm(category: Category) {
     // 货币信息
     const currencyInfo = computed(() => getCurrencyTypeInfo(formItem.ZSCurrencyType ?? 0))
 
-    const formSubmit = (addType: number) => {
+    const formSubmit = () => {
         loading.value = true
         return addZSGoods({
             data: {
                 UserID,
                 AccountID: AccountIDs[0],
-                AddType: addType,
+                AddType: performanceId.value ? 2 : 1,
                 MarketID: Market.GZ,
+                OrderSrc: 2,
+                ClientType: ClientType.Web,
                 ClientSerialNo: v4(),
                 GZ_WRStandardExInfo: formItem,
+                PerformanceTemplateID: performanceId.value,
             },
             complete: () => {
                 loading.value = false
@@ -270,6 +310,8 @@ export function useDiamondForm(category: Category) {
     return {
         loading,
         formItem,
+        performanceId,
+        shapeId,
         caratUnit,
         enums,
         selectedType,

+ 538 - 10
src/business/order/index.ts

@@ -1,7 +1,9 @@
 import { shallowRef, reactive } from 'vue'
 import { v4 } from 'uuid'
+import { ClientType } from '@/constants/enum/client'
+import { useDataTable } from '@/hooks/datatable'
 import { Market } from '@/constants/enum/market'
-import { zsBuyOrderListing } from '@/services/api/order'
+import { zsBuyOrderListing, zsSellOrderListing, queryBuyOrder, querySellOrder, queryMyBuyOrder, queryMySellOrder } from '@/services/api/order'
 import { sessionData } from '@/stores'
 import {
     Category,
@@ -15,14 +17,133 @@ import {
     getSymmetryTypeList,
     getFluorescenceTypeList,
     getCrystalTypeList,
-    getFancyColorTypeList,
+    getFancyColorType1List,
     getStyleTypeList,
 } from '@/constants/enum/diamond'
+import moment from 'moment'
 
-export function useOrderForm() {
+/**
+ * 求购大厅
+ * @returns 
+ */
+export function useBuyOrder() {
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam, resetFilter } = useDataTable<Ermcp.BuyOrderRsp>()
+    const loading = shallowRef(false)
+
+    const columns = shallowRef<Ermcp.TableColumn[]>([
+        {
+            prop: 'wrtradeorderid',
+            label: '委托单号',
+            width: 200,
+            show: true,
+        },
+        {
+            prop: 'buyusername',
+            label: '买方',
+            show: true,
+        },
+        {
+            prop: 'zscategorydisplay',
+            label: '商品分类',
+            show: true,
+        },
+        {
+            prop: 'zstabledisplay',
+            label: '求购信息',
+            show: true,
+        },
+        {
+            prop: 'wrtradeorderstatus',
+            label: '状态',
+            show: true,
+        },
+        {
+            prop: 'validtime',
+            label: '有效日期',
+            show: true,
+        },
+        {
+            prop: 'ordertime',
+            label: '委托时间',
+            show: true,
+        },
+        {
+            prop: 'operate',
+            label: '操作',
+            show: true,
+            fixed: 'right',
+        }
+    ])
+
+    // 获取求购大厅委托单
+    const getBuyOrderList = () => {
+        const param = getQueryParam()
+        loading.value = true
+        return queryBuyOrder({
+            data: {
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                zscategory: param.zscategory,
+                wrtradeorderid: param.wrtradeorderid,
+                zsallproperties: param.zstabledisplay,
+                buyusername: param.buyusername,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            fail: () => {
+                dataList.value = []
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: getCategoryList(),
+        },
+    ]
+
+    inputList.value = [
+        { label: '单号', keys: ['wrtradeorderid'], type: 'number' },
+        { label: '买方', keys: ['buyusername'] },
+        { label: '商品', keys: ['zstabledisplay'] },
+    ]
+
+    const [reset, search] = buttonList.value
+    reset.onClick = () => {
+        resetFilter()
+        getBuyOrderList()
+    }
+    search.onClick = getBuyOrderList
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        inputList,
+        selectList,
+        buttonList,
+        getBuyOrderList,
+    }
+}
+
+/**
+ * 求购大厅表单
+ * @returns 
+ */
+export function useBuyOrderForm() {
     const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
     const loading = shallowRef(false)
-    const performanceId = shallowRef<number>()
+    const performanceId = shallowRef<number>() // 履约模板ID
     const formItem = reactive<Proto.GZBuyOrderDetailExInfo>({
         UserID,
         AccountID: AccountIDs[0],
@@ -53,14 +174,10 @@ export function useOrderForm() {
         symmetryTypeList: getSymmetryTypeList(),
         fluorescenceTypeList: getFluorescenceTypeList(),
         crystalTypeList: getCrystalTypeList(),
-        fancyColorTypeList: getFancyColorTypeList(),
+        fancyColorType1List: getFancyColorType1List(),
         styleTypeList: getStyleTypeList(),
     }
 
-    const categoryChange = (value: number) => {
-        console.log(value)
-    }
-
     const formSubmit = () => {
         loading.value = true
         if (formItem.Size.some((val) => !val)) {
@@ -75,6 +192,7 @@ export function useOrderForm() {
                 AccountID: AccountIDs[0],
                 MarketID: Market.GZ,
                 OrderSrc: 2,
+                ClientType: ClientType.Web,
                 ClientSerialNo: v4(),
                 PerformanceTemplateID: performanceId.value,
                 GZ_BuyOrderDetailExInfo: formItem
@@ -90,7 +208,417 @@ export function useOrderForm() {
         performanceId,
         formItem,
         enums,
-        categoryChange,
         formSubmit,
     }
+}
+
+/**
+ * 出售大厅
+ * @returns 
+ */
+export function useSellOrder() {
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam, resetFilter } = useDataTable<Ermcp.SellOrderRsp>()
+    const loading = shallowRef(false)
+
+    const columns = shallowRef<Ermcp.TableColumn[]>([
+        {
+            prop: 'wrtradeorderid',
+            label: '委托单号',
+            width: 200,
+            show: true,
+        },
+        {
+            prop: 'sellusername',
+            label: '卖方',
+            show: true,
+        },
+        {
+            prop: 'zscategory',
+            label: '商品分类',
+            show: true,
+        },
+        {
+            prop: 'goodsno',
+            label: '商品编号',
+            show: true,
+        },
+        {
+            prop: 'totalqty',
+            label: '总重量',
+            show: true,
+        },
+        {
+            prop: 'fixedprice',
+            label: '克拉单价',
+            show: true,
+        },
+        {
+            prop: 'remainqty',
+            label: '剩余重量',
+            show: true,
+        },
+        {
+            prop: 'wrtradeorderstatus',
+            label: '委托状态',
+            show: true,
+        },
+        {
+            prop: 'ordertime',
+            label: '委托时间',
+            show: true,
+        },
+        {
+            prop: 'tradedate',
+            label: '交易日',
+            show: true,
+        },
+        {
+            prop: 'operate',
+            label: '操作',
+            show: true,
+            fixed: 'right',
+        }
+    ])
+
+    // 获取出售大厅委托单
+    const getSellOrderList = () => {
+        const param = getQueryParam()
+        loading.value = true
+        return querySellOrder({
+            data: {
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                zscategory: param.zscategory,
+                wrtradeorderid: param.wrtradeorderid,
+                zsallproperties: param.goodsno,
+                buyusername: param.sellusername,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            fail: () => {
+                dataList.value = []
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: getCategoryList(),
+        },
+    ]
+
+    inputList.value = [
+        { label: '单号', keys: ['wrtradeorderid'], type: 'number' },
+        { label: '卖方', keys: ['sellusername'] },
+        { label: '商品', keys: ['goodsno'] },
+    ]
+
+    const [reset, search] = buttonList.value
+    reset.onClick = () => {
+        resetFilter()
+        getSellOrderList()
+    }
+    search.onClick = getSellOrderList
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        inputList,
+        selectList,
+        buttonList,
+        getSellOrderList,
+    }
+}
+
+/**
+ * 出售大厅表单
+ * @returns 
+ */
+export function useSellOrderForm() {
+    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const loading = shallowRef(false)
+    const categoryList = getCategoryList()
+    const selectedCategoryId = shallowRef(Category.Diamonds)
+    const formItem = reactive<Proto.ZSSellOrderListingReq>({
+        Header: {
+            AccountID: AccountIDs[0],
+        },
+        UserID,
+        AccountID: AccountIDs[0],
+        WRStandardID: 0,
+        WRFactorTypeID: 0,
+        OrderQty: 0,
+        LadingBillID: 0,
+        SubNum: 0,
+        TimevalidType: 4,
+        ValidTime: '',
+        OrderSrc: 2,
+        ClientSerialNo: v4(),
+        ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
+        ClientType: ClientType.Web,
+        MarketID: Market.GZ,
+    })
+
+    const formSubmit = () => {
+        loading.value = true
+        return zsSellOrderListing({
+            data: formItem,
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    return {
+        loading,
+        formItem,
+        categoryList,
+        selectedCategoryId,
+        formSubmit,
+    }
+}
+
+/**
+ * 我的出售
+ */
+export function useSaleOrder() {
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam, resetFilter } = useDataTable<Ermcp.MySellOrderRsp>()
+    const loading = shallowRef(false)
+
+    const columns = shallowRef<Ermcp.TableColumn[]>([
+        {
+            prop: 'wrtradeorderid',
+            label: '委托单号',
+            width: 200,
+            show: true,
+        },
+        {
+            prop: 'buyusername',
+            label: '挂牌会员',
+            show: true,
+        },
+        {
+            prop: 'zscategory',
+            label: '商品分类',
+            show: true,
+        },
+        {
+            prop: 'goodsno',
+            label: '商品编号',
+            show: true,
+        },
+        {
+            prop: 'totalqty',
+            label: '委托重量',
+            show: true,
+        },
+        {
+            prop: 'fixedprice',
+            label: '克拉单价',
+            show: true,
+        },
+        {
+            prop: 'selledqty',
+            label: '成交重量',
+            show: true,
+        },
+        {
+            prop: 'wrtradeorderstatus',
+            label: '委托状态',
+            show: true,
+        },
+        {
+            prop: 'ordertime',
+            label: '委托时间',
+            show: true,
+        },
+        {
+            prop: 'operate',
+            label: '操作',
+            show: true,
+            fixed: 'right',
+        }
+    ])
+
+    // 获取我的出售列表
+    const getSaleOrderList = () => {
+        const param = getQueryParam()
+        loading.value = true
+        return queryMySellOrder({
+            data: {
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                userid: sessionData.getLoginInfo('UserID'),
+                zscategory: param.zscategory,
+                wrtradeorderid: param.wrtradeorderid,
+                zsallproperties: param.goodsno,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            fail: () => {
+                dataList.value = []
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: getCategoryList(),
+        },
+    ]
+
+    inputList.value = [
+        { label: '单号', keys: ['wrtradeorderid'], type: 'number' },
+        { label: '商品', keys: ['goodsno'] },
+    ]
+
+    const [reset, search] = buttonList.value
+    reset.onClick = () => {
+        resetFilter()
+        getSaleOrderList()
+    }
+    search.onClick = getSaleOrderList
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        inputList,
+        selectList,
+        buttonList,
+        getSaleOrderList,
+    }
+}
+
+/**
+ * 我的求购
+ */
+export function usePurchaseOrder() {
+    const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam, resetFilter } = useDataTable<Ermcp.MyBuyOrderRsp>()
+    const loading = shallowRef(false)
+
+    const columns = shallowRef<Ermcp.TableColumn[]>([
+        {
+            prop: 'wrtradeorderid',
+            label: '委托单号',
+            width: 200,
+            show: true,
+        },
+        {
+            prop: 'buyusername',
+            label: '会员',
+            show: true,
+        },
+        {
+            prop: 'zscategorydisplay',
+            label: '商品分类',
+            show: true,
+        },
+        {
+            prop: 'zstabledisplay',
+            label: '求购信息',
+            show: true,
+        },
+        {
+            prop: 'wrtradeorderstatus',
+            label: '状态',
+            show: true,
+        },
+        {
+            prop: 'validtime',
+            label: '有效日期',
+            show: true,
+        },
+        {
+            prop: 'ordertime',
+            label: '委托时间',
+            show: true,
+        },
+        {
+            prop: 'operate',
+            label: '操作',
+            show: true,
+            fixed: 'right',
+        }
+    ])
+
+    // 获取我的求购列表
+    const getPurchaseOrderList = () => {
+        const param = getQueryParam()
+        loading.value = true
+        return queryMyBuyOrder({
+            data: {
+                page: pageIndex.value,
+                pagesize: pageSize.value,
+                userid: sessionData.getLoginInfo('UserID'),
+                zscategory: param.zscategory,
+                wrtradeorderid: param.wrtradeorderid,
+                zsallproperties: param.zstabledisplay,
+            },
+            success: (res) => {
+                total.value = res.total
+                dataList.value = res.data
+            },
+            fail: () => {
+                dataList.value = []
+            },
+            complete: () => {
+                loading.value = false
+            }
+        })
+    }
+
+    selectList.value = [
+        {
+            label: '商品分类',
+            key: 'zscategory',
+            options: getCategoryList(),
+        },
+    ]
+
+    inputList.value = [
+        { label: '单号', keys: ['wrtradeorderid'], type: 'number' },
+        { label: '商品', keys: ['zstabledisplay'] },
+    ]
+
+    const [reset, search] = buttonList.value
+    reset.onClick = () => {
+        resetFilter()
+        getPurchaseOrderList()
+    }
+    search.onClick = getPurchaseOrderList
+
+    return {
+        loading,
+        dataList,
+        total,
+        pageIndex,
+        pageSize,
+        columns,
+        inputList,
+        selectList,
+        buttonList,
+        getPurchaseOrderList,
+    }
 }

+ 2 - 1
src/business/sign/index.ts

@@ -1,5 +1,6 @@
 import { ref, reactive } from 'vue'
 import { v4 } from 'uuid'
+import { ClientType } from '@/constants/enum/client'
 import { sessionData } from '@/stores'
 import { initBaseData } from '@/business/common'
 import { login, queryLoginId } from '@/services/api/account'
@@ -13,7 +14,7 @@ export function useSign() {
         LoginPWD: '123456',
         GUID: v4(),
         LoginType: 0,
-        ClientType: 4,
+        ClientType: ClientType.Web,
         Version: '2.0.0.0',
         DeviceID: ''
     })

+ 8 - 1
src/business/warehouse/index.ts

@@ -5,7 +5,7 @@ import { commonStore, sessionData } from '@/stores'
 //import { useTableColumns } from '../table'
 
 export function useWarehouse() {
-    const { dataList } = useDataTable<Ermcp.WarehouseInfoRsp>()
+    const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.WarehouseInfoRsp>()
     const loading = shallowRef(false)
 
     const columns = shallowRef<Ermcp.TableColumn[]>([
@@ -43,6 +43,7 @@ export function useWarehouse() {
             prop: 'operate',
             label: '操作',
             show: true,
+            fixed: 'right',
         }
     ])
 
@@ -50,9 +51,12 @@ export function useWarehouse() {
         loading.value = true
         return queryWarehouseInfo({
             data: {
+                page: pageIndex.value,
+                pagesize: pageSize.value,
                 userid: sessionData.getLoginInfo('UserID'),
             },
             success: (res) => {
+                total.value = res.total
                 dataList.value = res.data
             },
             complete: () => {
@@ -64,6 +68,9 @@ export function useWarehouse() {
     return {
         dataList,
         columns,
+        total,
+        pageIndex,
+        pageSize,
         getWarehouseList,
     }
 }

+ 3 - 17
src/components/base/modal/index.less

@@ -29,23 +29,9 @@
     }
 
     &__container {
-        display       : inline-flex;
-        flex-direction: column;
-        max-width     : 100%;
-        max-height    : 100%;
-        overflow      : hidden;
-    }
-
-    &__container &__header,
-    &__container &__footer {
-        &:empty {
-            display: none;
-        }
-    }
-
-    &__container &__body {
-        flex      : 1;
-        overflow-y: auto;
+        max-width : 100vw;
+        max-height: 100vh;
+        overflow  : auto;
     }
 
     /* 全屏 */

+ 14 - 13
src/components/base/modal/index.vue

@@ -5,15 +5,7 @@
             <div :class="['app-modal__mask', transitionClass]" :style="transitionStyles"></div>
             <div :class="['app-modal__wrapper', direction]" @click.self="onMask">
                 <div :class="['app-modal__container', transitionClass]" :style="containerStyles">
-                    <div class="app-modal__header">
-                        <slot name="header"></slot>
-                    </div>
-                    <div class="app-modal__body">
-                        <slot></slot>
-                    </div>
-                    <div class="app-modal__footer">
-                        <slot name="footer"></slot>
-                    </div>
+                    <slot></slot>
                 </div>
             </div>
         </div>
@@ -32,10 +24,6 @@ export default defineComponent({
             type: Boolean,
             default: false,
         },
-        loading: {
-            type: Boolean,
-            default: false,
-        },
         // 窗口关闭后是否刷新
         refresh: {
             type: Boolean,
@@ -76,6 +64,11 @@ export default defineComponent({
             type: [Number, String],
             default: 'auto',
         },
+        // 窗口高度
+        height: {
+            type: [Number, String],
+            default: 'auto',
+        },
     },
     setup(props, { emit }) {
         const { visible, transitionClass, transitionStyles, transition } = useModal(props.show, props.delay);
@@ -93,9 +86,17 @@ export default defineComponent({
                 }
                 return width === 'auto' ? width : width + 'px';
             }
+            const getHeight = () => {
+                const height = props.height.toString();
+                if (height.endsWith('%')) {
+                    return height;
+                }
+                return height === 'auto' ? height : height + 'px';
+            }
             return {
                 ...transitionStyles.value,
                 width: getWidth(),
+                height: getHeight(),
             }
         })
 

+ 26 - 0
src/constants/enum/client.ts

@@ -0,0 +1,26 @@
+import { getEnumTypeList } from './index'
+
+/**
+ * 客户端类型
+ */
+export enum ClientType {
+    None = 0,  // 保留为未填终端类型
+    PCManager = 1,  // PC管理端
+    PCTrade = 2,  // PC交易端
+    Android = 3,  // 手机客户端_安卓
+    Web = 4,  // 网页客户端
+    Wechat = 5,  // 微信客户端
+    IOS = 6,  // 手机客户端_苹果
+    AccountOnline = 7,  // 网上开户客户端
+    Invalid = 8,  // 无效终端编号
+    Quote = 9,  // 报价终端
+    TradeInterface = 10 // 交易接口
+}
+
+/**
+ * 获取客户端类型列表
+ * @returns 
+ */
+export function getClientTypeList() {
+    return getEnumTypeList('clientType')
+}

+ 18 - 2
src/constants/enum/diamond.ts

@@ -109,14 +109,30 @@ export function getCrystalTypeList() {
 }
 
 /**
- * 获取彩钻类型列表
+ * 获取彩钻类型1列表
  * @returns 
  */
-export function getFancyColorTypeList() {
+export function getFancyColorType1List() {
     return getEnumTypeList('ZSCZColor1Type')
 }
 
 /**
+ * 获取彩钻类型2列表
+ * @returns 
+ */
+export function getFancyColorType2List() {
+    return getEnumTypeList('ZSCZColor2Type')
+}
+
+/**
+ * 获取彩钻类型3列表
+ * @returns 
+ */
+export function getFancyColorType3List() {
+    return getEnumTypeList('ZSCZColor3Type')
+}
+
+/**
  * 获取款式类型列表
  * @returns 
  */

+ 2 - 0
src/constants/enum/funcode.ts

@@ -29,4 +29,6 @@ export enum FunCode {
 
     ZSBuyOrderListingReq = 1441837, // 钻石买挂牌接口请求
     ZSBuyOrderListingRsp = 1441838, //钻石买挂牌接口应答
+    ZSSellOrderListingReq = 1441829, // 钻石卖挂牌接口请求
+    ZSSellOrderListingRsp = 1441830, // 钻石卖挂牌接口响应
 }

+ 29 - 19
src/hooks/datatable/index.ts

@@ -4,19 +4,24 @@ import { FilterValue, FilterSelect, FilterInput, FilterButton } from './interfac
 export function useDataTable<T>() {
     // 数据源
     const dataSource = shallowRef<T[]>([])
+    // 总记录条数
+    const total = shallowRef(0)
+    // 当前页码
+    const pageIndex = shallowRef(1)
+    // 每页条数
+    const pageSize = shallowRef(20)
     // 过滤筛选值
-    const filters = shallowRef<FilterValue<T>[]>([])
+    const filters = shallowRef<FilterValue<T, keyof T>[]>([])
     // 过滤选项
-    const filterOptons: { selectList: FilterSelect<T>[], inputList: FilterInput<T>[] } = reactive({
+    const filterOptons: { selectList: FilterSelect<T, keyof T>[], inputList: FilterInput<T, keyof T>[], buttonList: FilterButton[] } = reactive({
         selectList: [],
         inputList: [],
+        buttonList: [
+            { lable: '重置', onClick: () => resetFilter() },
+            { lable: '查询', className: 'el-button--primary', onClick: () => onFilter() }, // 这里 className 不应该使用框架样式,以后再解决
+        ]
     })
 
-    const buttonMap = new Map<string, FilterButton>([
-        ['reset', { lable: '重置', onClick: () => resetFilter() }],
-        ['search', { lable: '查询', className: 'el-button--primary', onClick: () => onFilter() }] // 这里 className 不应该使用框架样式,以后再解决
-    ])
-
     // 数据列表
     const dataList = computed<T[]>({
         get() {
@@ -26,10 +31,10 @@ export function useDataTable<T>() {
                     return e.keys.some((key) => {
                         const value = row[key]
                         if (typeof value === 'number') {
-                            return e.filteredValue.includes(String(value))
+                            return e.filteredValue.includes(value)
                         }
                         return e.filteredValue.some((text) => {
-                            return String(value).toLowerCase().indexOf(text) >= 0
+                            return String(value).toLowerCase().indexOf(String(text)) >= 0
                         })
                     })
                 })
@@ -40,15 +45,19 @@ export function useDataTable<T>() {
         }
     })
 
-    // 本地过滤,支持多条件查询
     const onFilter = () => {
-        const options: FilterValue<T>[] = []
+        filters.value = getFilterParam()
+    }
+
+    // 获取过滤参数,支持多条件查询
+    const getFilterParam = () => {
+        const options: FilterValue<T, keyof T>[] = []
         filterOptons.selectList.forEach((e) => {
             const { key, selectedValue } = e;
             if (selectedValue !== undefined) {
                 options.push({
                     keys: [key],
-                    filteredValue: [selectedValue.toString()],
+                    filteredValue: [selectedValue],
                 })
             }
         })
@@ -61,13 +70,12 @@ export function useDataTable<T>() {
                 })
             }
         })
-        filters.value = options
-        console.log('表格过滤参数', options)
+        return options
     }
 
-    // 获取查询参数
+    // 获取查询参数,支持多条件查询
     const getQueryParam = () => {
-        const params: { [K in keyof T]?: string | number } = {}
+        const params: { [K in keyof T]?: T[K] } = {}
         filterOptons.selectList.forEach((e) => {
             if (e.selectedValue) {
                 params[e.key] = e.selectedValue
@@ -80,7 +88,6 @@ export function useDataTable<T>() {
                 }
             })
         })
-        console.log('表格查询参数', params)
         return params
     }
 
@@ -93,9 +100,12 @@ export function useDataTable<T>() {
 
     return {
         dataList,
-        buttonMap,
-        onFilter,
+        total,
+        pageIndex,
+        pageSize,
+        getFilterParam,
         getQueryParam,
+        resetFilter,
         ...toRefs(filterOptons),
     }
 }

+ 12 - 11
src/hooks/datatable/interface.ts

@@ -1,33 +1,34 @@
 /** 
  * 数据过滤项
  */
-export interface FilterValue<T> {
-    keys: (keyof T)[], // 多条件字段
-    filteredValue: string[], // 多选过滤或模糊查询
+export interface FilterValue<T, K extends keyof T> {
+    keys: K[], // 多条件字段
+    filteredValue: (T[K])[], // 多选过滤或模糊查询
 }
 
 /** 
  * 过滤选择框
  */
-export interface FilterSelect<T> {
-    key: keyof T,
+export interface FilterSelect<T, K extends keyof T> {
+    key: K,
     label?: string,
-    selectedValue?: string | number,
+    selectedValue?: T[K],
     placeholder?: string,
     options: {
         label: string,
-        value: string | number,
+        value: T[K],
     }[],
-    onChange?: (value: string | number) => void
+    onChange?: (value: T[K]) => void
 }
 
 /** 
  * 过滤输入框
  */
-export interface FilterInput<T> {
-    keys: (keyof T)[],
+export interface FilterInput<T, K extends keyof T> {
+    keys: K[],
     label?: string,
-    value?: string,
+    value?: T[K],
+    type?: 'text' | 'number',
     placeholder?: string
 }
 

+ 55 - 1
src/mock/router.ts

@@ -91,7 +91,53 @@ const appmenu = {
                         url: 'sell',
                         urlType: 1,
                         component: 'views/listing/sell/index.vue',
+                        children: [
+                            {
+                                authType: 3,
+                                title: '我要出售',
+                                code: 'listing_sell_add',
+                                component: 'views/listing/sell/components/add/index.vue',
+                                buttonName: 'add',
+                                buttonType: 'primary',
+                            },
+                        ]
+                    },
+                    {
+                        authType: 1,
+                        sort: 1,
+                        title: '我的出售',
+                        code: 'listing_sale',
+                        url: 'sale',
+                        urlType: 1,
+                        component: 'views/listing/sale/index.vue',
+                    },
+                    {
+                        authType: 1,
+                        sort: 1,
+                        title: '我的求购',
+                        code: 'listing_purchase',
+                        url: 'purchase',
+                        urlType: 1,
+                        component: 'views/listing/purchase/index.vue',
                     },
+                    {
+                        authType: 1,
+                        sort: 1,
+                        title: '我的摘牌',
+                        code: 'listing_delisting',
+                        url: 'delisting',
+                        urlType: 1,
+                        component: 'views/listing/delisting/index.vue',
+                    },
+                    {
+                        authType: 1,
+                        sort: 1,
+                        title: '我的询价',
+                        code: 'listing_inquire',
+                        url: 'inquire',
+                        urlType: 1,
+                        component: 'views/listing/inquire/index.vue',
+                    }
                 ]
             },
             {
@@ -115,7 +161,7 @@ const appmenu = {
                         children: [
                             {
                                 authType: 3,
-                                title: '商品上架',
+                                title: '添加商品',
                                 code: 'warehousing_stock_add',
                                 component: 'views/warehousing/stock/components/edit/index.vue',
                                 buttonName: 'add',
@@ -123,6 +169,14 @@ const appmenu = {
                             },
                             {
                                 authType: 3,
+                                title: '商品上架',
+                                code: 'warehousing_stock_sell',
+                                component: 'views/warehousing/stock/components/edit/index.vue',
+                                buttonName: 'sell',
+                                buttonType: 'primary',
+                            },
+                            {
+                                authType: 3,
                                 title: '详情',
                                 code: 'warehousing_stock_details',
                                 component: 'views/warehousing/stock/components/details/index.vue',

+ 8 - 1
src/packages/mobile/components/modules/trade/index.less

@@ -1,7 +1,14 @@
 .app-trade {
-    .app-modal__container {
+    &__wrapper {
+        display         : flex;
+        flex-direction  : column;
         width           : 100%;
         height          : 100%;
         background-color: #f7f7f7;
     }
+
+    &__body {
+        flex      : 1;
+        overflow-y: auto;
+    }
 }

+ 10 - 6
src/packages/mobile/components/modules/trade/index.vue

@@ -1,10 +1,14 @@
 <template>
-    <app-modal class="app-trade" direction="right" v-model:show="showModal">
-        <template #header>
-            <app-navbar title="挂牌求购" @back="closed" />
-        </template>
-        <AddressEdit show-postal show-delete show-set-default show-search-result
-            :area-columns-placeholder="['请选择', '请选择', '请选择']" />
+    <app-modal class="app-trade" direction="right" height="100%" v-model:show="showModal">
+        <div class="app-trade__wrapper">
+            <div class="app-trade__header">
+                <app-navbar title="挂牌求购" @back="closed" />
+            </div>
+            <div class="app-trade__body">
+                <AddressEdit show-postal show-delete show-set-default show-search-result
+                    :area-columns-placeholder="['请选择', '请选择', '请选择']" />
+            </div>
+        </div>
     </app-modal>
 </template>
 

+ 31 - 18
src/packages/pc/assets/themes/default/default.less

@@ -60,7 +60,7 @@
 
                 &__content {
                     align-items  : flex-start;
-                    padding-right: 80px;
+                    padding-right: 60px;
                 }
 
                 &--row {
@@ -75,26 +75,39 @@
     }
 
     .app-tabs {
-        .tabs {
-            flex-wrap: wrap;
+        &__navbar {
+            z-index         : 1;
+            display         : flex;
+            align-items     : center;
+            background-color: #fff;
+            border-top      : 1px solid #f2f2f2;
+            box-shadow      : 0 2px 16px 0 rgba(0, 0, 0, .1);
+            padding         : 8px 20px 0 20px;
 
-            &-item {
-                display         : flex;
-                justify-content : center;
-                align-items     : center;
-                color           : #626675;
-                cursor          : pointer;
-                border-radius   : 4px;
-                background-color: #f0f0f1;
-                padding         : 8px 16px;
+            .tabs {
+                &-item {
+                    height                 : 40px;
+                    line-height            : 40px;
+                    color                  : #777;
+                    border-top-left-radius : 4px;
+                    border-top-right-radius: 4px;
+                    cursor                 : pointer;
+                    padding                : 0 20px;
 
-                &:not(:first-child) {
-                    margin-left: 10px;
-                }
+                    &:not(:first-child) {
+                        margin-left: 4px;
+                    }
 
-                &.is-active {
-                    color      : #222;
-                    font-weight: bold;
+                    &:hover {
+                        color           : inherit;
+                        background-color: var(--tabbar-hover);
+                    }
+
+                    &.is-active {
+                        color           : #fff !important;
+                        background-color: var(--tabbar-active);
+                        border-bottom   : 0;
+                    }
                 }
             }
         }

+ 28 - 16
src/packages/pc/components/base/drawer/index.less

@@ -1,32 +1,44 @@
 .app-drawer {
-    .app-modal__container {
+    &__wrapper {
+        display         : flex;
+        flex-direction  : column;
+        max-height      : 100vh;
         min-width       : 320px;
         border-radius   : 4px;
         background-color: #fff;
         box-shadow      : 0 0 20px 0 rgba(0, 0, 0, .15);
+        overflow        : hidden;
     }
 
-    .app-modal__header {
-        position     : relative;
-        font-size    : 16px;
-        border-bottom: 1px solid #f2f2f2;
-        padding      : 18px 24px;
+    &__header {
+        display        : flex;
+        justify-content: space-between;
+        align-items    : center;
+        border-bottom  : 1px solid #f2f2f2;
+        padding        : 18px 24px;
+
+        h1 {
+            font-size: 16px;
+        }
+
+        .el-icon {
+            font-size: 16px;
+            cursor   : pointer;
+        }
     }
 
-    .app-modal__body {
-        padding: 24px 48px;
+    &__body {
+        flex      : 1;
+        overflow-y: auto;
+        padding   : 24px 48px;
     }
 
-    .app-modal__footer {
+    &__footer {
         text-align: center;
         padding   : 24px 48px;
-    }
 
-    &__close {
-        position : absolute;
-        top      : 50%;
-        right    : 24px;
-        transform: translate3d(0, -50%, 0);
-        cursor   : pointer;
+        &:empty {
+            display: none;
+        }
     }
 }

+ 18 - 12
src/packages/pc/components/base/drawer/index.vue

@@ -1,18 +1,20 @@
 <!-- 抽屉弹框组件 -->
 <template>
   <app-modal class="app-drawer" :show="show" :close-on-click-mask="false" @mask="close">
-    <template #header>
-      <div class="app-drawer__title">{{ title }}</div>
-      <el-icon class="app-drawer__close" @click="close">
-        <Close />
-      </el-icon>
-    </template>
-    <template #default>
-      <slot></slot>
-    </template>
-    <template #footer>
-      <slot name="footer"></slot>
-    </template>
+    <div class="app-drawer__wrapper" v-loading="loading">
+      <div class="app-drawer__header">
+        <h1>{{ title }}</h1>
+        <el-icon @click="close">
+          <Close />
+        </el-icon>
+      </div>
+      <div class="app-drawer__body">
+        <slot></slot>
+      </div>
+      <div class="app-drawer__footer">
+        <slot name="footer"></slot>
+      </div>
+    </div>
   </app-modal>
 </template>
 
@@ -30,6 +32,10 @@ defineProps({
     type: String,
     default: '标题',
   },
+  loading: {
+    type: Boolean,
+    default: false,
+  },
 })
 
 const close = () => {

+ 1 - 1
src/packages/pc/components/base/pagination/index.less

@@ -1,6 +1,6 @@
 .app-pagination {
     display        : flex;
-    justify-content: center;
+    justify-content: flex-end;
 
     .el-pagination {
         padding: 0;

+ 2 - 2
src/packages/pc/components/base/pagination/index.vue

@@ -37,13 +37,13 @@ const page = reactive({
 const handleSizeChange = (val: number) => {
     page.size = val;
     emit('update:pageSize', val);
-    emit('change', val);
+    emit('change');
 }
 
 const handleCurrentChange = (val: number) => {
     page.index = val;
     emit('update:pageIndex', val);
-    emit('change', val);
+    emit('change');
 }
 </script>
 

+ 1 - 1
src/packages/pc/components/base/table-filter/index.less

@@ -18,6 +18,6 @@
     }
 
     .el-input {
-        width: 200px;
+        width: 160px;
     }
 }

+ 9 - 5
src/packages/pc/components/base/table-filter/index.vue

@@ -9,14 +9,14 @@
       </el-select>
     </el-form-item>
     <el-form-item v-for="(item, i) in inputList" :key="i" :label="item.label">
-      <el-input :placeholder="item.placeholder ?? '请输入关键字'" v-model="item.value" />
+      <el-input :type="item.type" :placeholder="item.placeholder ?? '请输入关键字'" v-model="item.value" />
     </el-form-item>
     <el-form-item v-if="$slots.after">
       <slot name="after"></slot>
     </el-form-item>
     <el-form-item>
-      <el-button :class="item.className" v-for="(item, i) in buttonMap.values()" :key="i" @click="item.onClick">{{
-      item.lable }}
+      <el-button :class="item.className" v-for="(item, i) in buttonList" :key="i" :loading="loading"
+        @click="item.onClick">{{ item.lable }}
       </el-button>
     </el-form-item>
     <el-form-item v-if="$slots.default">
@@ -38,10 +38,14 @@ defineProps({
     type: Array as PropType<FilterInput[]>,
     default: () => [],
   },
-  buttonMap: {
-    type: Map as PropType<Map<string, FilterButton>>,
+  buttonList: {
+    type: Array as PropType<FilterButton[]>,
     default: () => [],
   },
+  loading: {
+    type: Boolean,
+    default: false
+  },
 })
 </script>
 

+ 2 - 3
src/packages/pc/components/base/table/index.less

@@ -39,12 +39,11 @@
 
         th.el-table__cell {
             font-weight: normal;
-            height     : 30px;
-            padding    : 12px 0;
+            padding    : 8px 0;
         }
 
         td.el-table__cell {
-            padding: 10px 0;
+            padding: 8px 0;
 
             .el-table__placeholder:empty {
                 display: none;

+ 1 - 1
src/packages/pc/components/base/table/index.vue

@@ -12,7 +12,7 @@
       </div>
     </div>
     <div class="app-table__container">
-      <el-table ref="tableRef" v-bind="$attrs" v-loading="loading" highlight-current-row scrollbar-always-on border>
+      <el-table ref="tableRef" v-bind="$attrs" v-loading="loading" highlight-current-row scrollbar-always-on>
         <!-- 展开行 -->
         <el-table-column type="expand" v-if="$slots.expand">
           <template #default="{ row, $index }">

+ 0 - 52
src/packages/pc/components/layouts/main/index.less

@@ -1,52 +0,0 @@
-.app-main {
-    display       : flex;
-    flex-direction: column;
-    height        : 100%;
-
-    &__navbar {
-        z-index         : 1;
-        display         : flex;
-        align-items     : center;
-        background-color: #fff;
-        border-top      : 1px solid #f2f2f2;
-        box-shadow      : 0 2px 16px 0 rgba(0, 0, 0, .1);
-        padding         : 8px 20px 0 20px;
-
-        .el-menu {
-            flex: 1;
-
-            &--horizontal {
-                border-bottom: 0;
-            }
-
-            .el-menu-item {
-                height                 : 40px;
-                //line-height: 40px; bug 会导致鼠标经过严重卡顿
-                min-width              : auto;
-                color                  : #777;
-                border-top-left-radius : 4px;
-                border-top-right-radius: 4px;
-
-                &:not(:first-child) {
-                    margin-left: 4px;
-                }
-
-                &:hover {
-                    color           : inherit;
-                    background-color: var(--tabbar-hover);
-                }
-
-                &.is-active {
-                    color           : #fff !important;
-                    background-color: var(--tabbar-active);
-                    border-bottom   : 0;
-                }
-            }
-        }
-    }
-
-    &__container {
-        flex      : 1;
-        overflow-y: auto;
-    }
-}

+ 16 - 27
src/packages/pc/components/layouts/main/index.vue

@@ -1,47 +1,36 @@
 <template>
-    <div class="app-main">
-        <div class="app-main__navbar">
-            <el-menu mode="horizontal" :default-active="activeMenu" @select="routerTo">
-                <el-menu-item v-for="(item, index) in secondMenus" :key="index" :index="item.name">
-                    {{ item.label }}
-                </el-menu-item>
-            </el-menu>
-            <slot></slot>
-        </div>
-        <div class="app-main__container">
+    <app-tabs class="app-main" :data-list="secondMenus" v-model:data-index="dataIndex" @change="onTabChange">
+        <el-scrollbar class="app-main__container" always>
             <!-- 二级路由 -->
             <router-view v-slot="{ Component, route }">
                 <component :is="Component" :key="route.fullPath" />
             </router-view>
-        </div>
-    </div>
+        </el-scrollbar>
+    </app-tabs>
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, computed } from 'vue'
+import { shallowRef } from 'vue'
 import { useAuth } from '@/hooks/auth'
 import { AuthMenu } from '@/hooks/auth/interface'
+import AppTabs from '@/components/base/tabs/index.vue'
 
 const { route, router, getChildrenMenus } = useAuth()
 const parentRoute = route.matched[route.matched.length - 2] // 父级路由信息
 const secondMenus = shallowRef<AuthMenu[]>([]) // 二级菜单
+const dataIndex = shallowRef(0) // 选中的标签
 
 if (parentRoute) {
-    secondMenus.value = getChildrenMenus(parentRoute.name?.toString())
+    const menus = getChildrenMenus(parentRoute.name?.toString())
+    const index = menus.findIndex((e) => e.name === route.name)
+    secondMenus.value = menus
+    if (index > -1) {
+        dataIndex.value = index
+    }
 }
 
-// 高亮菜单
-const activeMenu = computed(() => {
-    const item = secondMenus.value.find((e) => route.matched.some((m) => m.name === e.name))
-    return item?.name
-})
-
-// 路由跳转
-const routerTo = (name: string) => {
+// 切换标签
+const onTabChange = (index: number, { name }: AuthMenu) => {
     router.push({ name })
 }
-</script>
-
-<style lang="less">
-@import './index.less';
-</style>
+</script>

+ 7 - 2
src/packages/pc/components/modules/performance/index.vue

@@ -1,5 +1,6 @@
 <template>
-    <el-select popper-class="app-performance" value-key="autoid" v-model="selectedItem" @change="onChange">
+    <el-select popper-class="app-performance" value-key="autoid" :placeholder="placeholder" v-model="selectedItem"
+        @change="onChange" clearable>
         <el-option class="app-performance-item" v-for="(item, i) in dataList" :key="i" :label="item.templatename"
             :value="item">
             <h4 class="app-performance-item__title">{{ item.templatename }}</h4>
@@ -18,7 +19,11 @@ import { shallowRef } from 'vue'
 import { queryPermancePlanTmp } from '@/services/api/performance'
 
 const props = defineProps({
-    modelValue: Number
+    modelValue: Number,
+    placeholder: {
+        type: String,
+        default: '请选择'
+    }
 })
 
 const emit = defineEmits(['update:modelValue'])

+ 1 - 1
src/packages/pc/router/index.ts

@@ -53,7 +53,7 @@ const router = createRouter({
 router.beforeEach((to, from, next) => {
     const isLoginOrRegister = to.name === 'login' || to.name === 'register';
     const title = to.meta.title;
-    document.title = title ? `MTP - ${title}` : 'MTP';
+    document.title = title ? `广钻钻石交易中心 - ${title}` : '广钻钻石交易中心';
 
     // 判断服务是否加载完成
     if (service.isReady) {

+ 10 - 11
src/packages/pc/views/listing/buy/components/add/index.vue

@@ -1,10 +1,9 @@
 <!-- 求购大厅-我要求购 -->
 <template>
-    <app-drawer title="我要求购" :width="960" v-model:show="show" :refresh="refresh">
-        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" label-position="left" :model="formItem"
-            :rules="formRules">
+    <app-drawer title="我要求购" :width="960" v-model:show="show" :loading="loading" :refresh="refresh">
+        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
             <el-form-item label="商品分类" prop="ZSCategory">
-                <el-select v-model="formItem.ZSCategory" @change="categoryChange">
+                <el-select v-model="formItem.ZSCategory">
                     <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.categoryList"
                         :key="index" />
                 </el-select>
@@ -37,7 +36,7 @@
                     v-model="formItem.ZSClarityType" />
             </el-form-item>
             <el-form-item label="彩钻颜色" prop="ZSCZColor1Type" v-if="formItem.ZSCategory === Category.Fancy">
-                <app-multiple class="el-form-item--col" :data-list="enums.fancyColorTypeList"
+                <app-multiple class="el-form-item--col" :data-list="enums.fancyColorType1List"
                     v-model="formItem.ZSCZColor1Type" />
             </el-form-item>
             <el-form-item label="颜色" prop="ZSColorType" v-else>
@@ -70,11 +69,11 @@
                 <app-multiple class="el-form-item--col" :data-list="enums.styleTypeList" v-model="formItem.ZSStyleType"
                     checkbox />
             </el-form-item>
+            <el-form-item class="el-form-item--row">
+                <el-button type="primary" @click="onSubmit">提交</el-button>
+                <el-button @click="onCancel(false)" plain>取消</el-button>
+            </el-form-item>
         </el-form>
-        <template #footer>
-            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
-            <el-button :loading="loading" type="primary" @click="onSubmit">提交</el-button>
-        </template>
     </app-drawer>
 </template>
 
@@ -82,7 +81,7 @@
 import { ref, defineAsyncComponent } from 'vue'
 import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
-import { useOrderForm } from '@/business/order'
+import { useBuyOrderForm } from '@/business/order'
 import { Category } from '@/constants/enum/diamond'
 import AppDrawer from '@pc/components/base/drawer/index.vue'
 import AppMultiple from '@pc/components/base/multiple/index.vue'
@@ -91,7 +90,7 @@ const components = {
     performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
 }
 
-const { loading, performanceId, formItem, enums, categoryChange, formSubmit } = useOrderForm()
+const { loading, performanceId, formItem, enums, formSubmit } = useBuyOrderForm()
 const show = ref(true)
 const refresh = ref(false)
 const formRef = ref<FormInstance>()

+ 14 - 63
src/packages/pc/views/listing/buy/index.vue

@@ -1,85 +1,36 @@
+<!-- 挂牌大厅-求购大厅 -->
 <template>
     <app-view>
         <template #header>
-            <app-filter v-bind="{ selectList, inputList, buttonList }" />
+            <app-filter v-bind="{ selectList, inputList, buttonList }" :loading="loading" />
         </template>
         <!-- 表格数据 -->
-        <app-table :data="dataList" v-model:columns="columns" :row-key="rowKey" border>
+        <app-table :data="dataList" v-model:columns="columns" :loading="loading">
             <template #header>
-                <app-auth-operation :menus="['add']" />
+                <app-auth-operation :menus="['add']" @closed="getBuyOrderList" />
             </template>
+            <!-- 操作 -->
             <template #operate="{ row }">
-                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" linkButton />
+                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" @closed="getBuyOrderList"
+                    linkButton />
             </template>
-            <template #footer>
-                <app-pagination :total="400" />
+            <template #footer v-if="total > pageSize">
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="getBuyOrderList" />
             </template>
         </app-table>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { ref } from 'vue'
-import { useDataTable } from '@/hooks/datatable'
-import { queryGoodsList } from '@/services/api/goods'
-import { useTable } from '@pc/components/base/table'
+import { ElMessage } from 'element-plus'
+import { useBuyOrder } from '@/business/order'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 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'
 
-const { rowKey } = useTable<Ermcp.GoodsRsp>('id');
-const { dataList, selectList, inputList, buttonList } = useDataTable<Ermcp.GoodsRsp>();
+const { loading, dataList, columns, total, pageIndex, pageSize, selectList, inputList, buttonList, getBuyOrderList } = useBuyOrder()
 
-selectList.value = [
-    {
-        key: 'id',
-        placeholder: '商品合约',
-        options: [
-            { label: '黄金', value: 1000 },
-            { label: '昆特牌', value: 1001 }
-        ],
-    },
-]
-
-inputList.value = [
-    { placeholder: '模糊搜索商品名称', keys: ['goodsName', 'goodsCode'] },
-]
-
-const columns = ref([
-    {
-        prop: 'id',
-        label: '序号',
-        sortable: true,
-        show: true,
-        fixed: '',
-    },
-    {
-        prop: 'goodsCode',
-        label: '合约',
-        sortable: true,
-        show: true,
-    },
-    {
-        prop: 'goodsName',
-        label: '商品',
-        show: true,
-    },
-    {
-        prop: 'lastPrice',
-        label: '最新价',
-        show: true,
-    },
-    {
-        prop: 'operate',
-        label: '操作',
-        show: true,
-    }
-])
-
-queryGoodsList({
-    success: (res) => {
-        dataList.value = res.data;
-    }
-})
+getBuyOrderList().catch((err) => ElMessage.error(err))
 </script>

+ 9 - 0
src/packages/pc/views/listing/delisting/index.vue

@@ -0,0 +1,9 @@
+<!-- 挂牌大厅-我的摘牌 -->
+<template>
+    <app-view>
+        我的摘牌
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+</script>

+ 9 - 0
src/packages/pc/views/listing/inquire/index.vue

@@ -0,0 +1,9 @@
+<!-- 挂牌大厅-我的询价 -->
+<template>
+    <app-view>
+        我的询价
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+</script>

+ 33 - 0
src/packages/pc/views/listing/purchase/index.vue

@@ -0,0 +1,33 @@
+<!-- 挂牌大厅-我的求购 -->
+<template>
+    <app-view>
+        <template #header>
+            <app-filter v-bind="{ selectList, inputList, buttonList }" :loading="loading" />
+        </template>
+        <!-- 表格数据 -->
+        <app-table :data="dataList" v-model:columns="columns" :loading="loading">
+            <!-- 操作 -->
+            <template #operate="{ row }">
+                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" @closed="getPurchaseOrderList"
+                    linkButton />
+            </template>
+            <template #footer v-if="total > pageSize">
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="getPurchaseOrderList" />
+            </template>
+        </app-table>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import { usePurchaseOrder } from '@/business/order'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+import AppFilter from '@pc/components/base/table-filter/index.vue'
+
+const { loading, dataList, total, pageIndex, pageSize, columns, selectList, inputList, buttonList, getPurchaseOrderList } = usePurchaseOrder()
+
+getPurchaseOrderList().catch((err) => ElMessage.error(err))
+</script>

+ 33 - 0
src/packages/pc/views/listing/sale/index.vue

@@ -0,0 +1,33 @@
+<!-- 挂牌大厅-我的出售 -->
+<template>
+    <app-view>
+        <template #header>
+            <app-filter v-bind="{ selectList, inputList, buttonList }" :loading="loading" />
+        </template>
+        <!-- 表格数据 -->
+        <app-table :data="dataList" v-model:columns="columns" :loading="loading">
+            <!-- 操作 -->
+            <template #operate="{ row }">
+                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" @closed="getSaleOrderList"
+                    linkButton />
+            </template>
+            <template #footer v-if="total > pageSize">
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="getSaleOrderList" />
+            </template>
+        </app-table>
+    </app-view>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import { useSaleOrder } from '@/business/order'
+import AppTable from '@pc/components/base/table/index.vue'
+import AppPagination from '@pc/components/base/pagination/index.vue'
+import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+import AppFilter from '@pc/components/base/table-filter/index.vue'
+
+const { loading, dataList, total, pageIndex, pageSize, columns, selectList, inputList, buttonList, getSaleOrderList } = useSaleOrder()
+
+getSaleOrderList().catch((err) => ElMessage.error(err))
+</script>

+ 72 - 0
src/packages/pc/views/listing/sell/components/add/index.vue

@@ -0,0 +1,72 @@
+<!-- 求购大厅-我要出售 -->
+<template>
+    <app-drawer title="我要出售" :width="960" v-model:show="show" :loading="loading" :refresh="refresh">
+        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
+            <el-form-item label="商品分类" prop="ZSCategory">
+                <el-select v-model="selectedCategoryId">
+                    <el-option :label="item.label" :value="item.value" v-for="(item, index) in categoryList"
+                        :key="index" />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="履约方式" prop="PerformanceTemplateID">
+                <component :is="components.performance" v-model="formItem.PerformanceTemplateID" />
+            </el-form-item>
+            <el-form-item label="选择商品" prop="Origin">
+                <el-input />
+            </el-form-item>
+            <el-form-item class="el-form-item--row">
+                <el-button type="primary" @click="onSubmit">提交</el-button>
+                <el-button @click="onCancel(false)" plain>取消</el-button>
+            </el-form-item>
+        </el-form>
+    </app-drawer>
+</template>
+
+<script lang="ts" setup>
+import { ref, defineAsyncComponent } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { useSellOrderForm } from '@/business/order'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
+
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const { loading, formItem, selectedCategoryId, categoryList, formSubmit } = useSellOrderForm()
+const show = ref(true)
+const refresh = ref(false)
+const formRef = ref<FormInstance>()
+
+const formRules: FormRules = {
+    ZSCategory: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (selectedCategoryId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择商品分类'))
+            }
+        }
+    }],
+    PerformanceTemplateID: [{ required: true, message: '请选择履约方式' }],
+}
+
+const onCancel = (isRefresh = false) => {
+    show.value = false
+    refresh.value = isRefresh
+}
+
+const onSubmit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            formSubmit().then(() => {
+                ElMessage.success('提交成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('提交失败:' + err)
+            })
+        }
+    })
+}
+</script>

+ 31 - 1
src/packages/pc/views/listing/sell/index.vue

@@ -1,6 +1,36 @@
+<!-- 挂牌大厅-出售大厅 -->
 <template>
-    <app-view>出售大厅</app-view>
+    <app-view>
+        <template #header>
+            <app-filter v-bind="{ selectList, inputList, buttonList }" :loading="loading" />
+        </template>
+        <!-- 表格数据 -->
+        <app-table :data="dataList" v-model:columns="columns" :loading="loading">
+            <template #header>
+                <app-auth-operation :menus="['add']" @closed="getSellOrderList" />
+            </template>
+            <!-- 操作 -->
+            <template #operate="{ row }">
+                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" @closed="getSellOrderList"
+                    linkButton />
+            </template>
+            <template #footer v-if="total > pageSize">
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="getSellOrderList" />
+            </template>
+        </app-table>
+    </app-view>
 </template>
 
 <script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import { useSellOrder } from '@/business/order'
+import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
+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'
+
+const { loading, dataList, columns, total, pageIndex, pageSize, selectList, inputList, buttonList, getSellOrderList } = useSellOrder()
+
+getSellOrderList().catch((err) => ElMessage.error(err))
 </script>

+ 4 - 3
src/packages/pc/views/system/menu/components/edit/index.vue

@@ -1,5 +1,6 @@
 <template>
-    <app-drawer class="system-menu-edit" title="编辑" width="680" v-model:show="show" :refresh="refresh">
+    <app-drawer class="system-menu-edit" title="编辑" width="680" v-model:show="show" :loading="loading"
+        :refresh="refresh">
         <template #default>
             <el-form ref="formRef" label-width="90px" :model="formItem">
                 <el-form-item label="权限类型" prop="authtype">
@@ -62,8 +63,8 @@
             </el-form>
         </template>
         <template #footer>
-            <el-button :loading="loading" @click="onCancel(false)">取消</el-button>
-            <el-button :loading="loading" @click="onSubmit" type="primary">提交</el-button>
+            <el-button @click="onCancel(false)">取消</el-button>
+            <el-button @click="onSubmit" type="primary">提交</el-button>
         </template>
     </app-drawer>
 </template>

+ 201 - 1
src/packages/pc/views/warehousing/stock/components/edit/diamond.vue

@@ -1,6 +1,206 @@
+<!-- 添加商品-单颗裸钻 -->
 <template>
-    <div>单颗</div>
+    <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
+        <el-form-item label="商品编号" prop="GoodsNo">
+            <el-input placeholder="请输入" v-model="formItem.GoodsNo" />
+        </el-form-item>
+        <el-form-item label="履约方式" prop="PerformanceTemplateID" v-if="code === 'warehousing_stock_sell'">
+            <component :is="components.performance" v-model="performanceId" />
+        </el-form-item>
+        <el-form-item label="货币类型" prop="ZSCurrencyType">
+            <el-radio-group v-model="formItem.ZSCurrencyType">
+                <el-radio :label="item.value" v-for="(item, index) in enums.currencyTypeList" :key="index">
+                    {{ item.label }}
+                </el-radio>
+            </el-radio-group>
+        </el-form-item>
+        <el-form-item label="价格" prop="Price">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Price">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="克拉重量" prop="Weight">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Weight">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="克拉单位">
+            <span>{{ currencyInfo?.param2 }}{{ caratUnit }} (总价/总重量)</span>
+        </el-form-item>
+        <el-form-item label="形状" prop="ZSShapeType">
+            <el-select v-model="shapeId" @change="shapeChange">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.shapeTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="尺寸" prop="Size">
+            <div class="el-form-item--col">
+                <el-input-number type="number" v-model="formItem.Size1" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size2" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size3" :controls="false" />
+            </div>
+        </el-form-item>
+        <el-form-item label="颜色" prop="ZSColorType1">
+            <el-select v-model="formItem.ZSColorType1">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.colorTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="切工" prop="ZSCutType1">
+            <el-select v-model="formItem.ZSCutType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.cutTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="净度" prop="ZSClarityType1">
+            <el-select v-model="formItem.ZSClarityType1">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.clarityTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="抛光" prop="ZSPolishType1">
+            <el-select v-model="formItem.ZSPolishType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.polishTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="对称" prop="ZSSymmetryType1">
+            <el-select v-model="formItem.ZSSymmetryType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.symmetryTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="荧光" prop="ZSFluorescenceType1">
+            <el-select v-model="formItem.ZSFluorescenceType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.fluorescenceTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="仓库" prop="WarehouseID">
+            <el-select v-model="formItem.WarehouseID">
+                <el-option :label="item.warehousename" :value="item.autoid" v-for="(item, index) in warehouseList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="市场价" prop="MarketPrice">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.MarketPrice">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="证书类型" prop="ZSCertType">
+            <el-select v-model="formItem.ZSCertType" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.certTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="证书编号" prop="CerNo">
+            <el-input placeholder="请输入" v-model="formItem.CerNo" />
+        </el-form-item>
+        <el-form-item label="商品照片" prop="ImagePath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item class="el-form-item--row" label="备注" prop="Remark">
+            <el-input type="textarea" v-model="formItem.Remark" />
+        </el-form-item>
+        <el-form-item class="el-form-item--row">
+            <el-button type="primary" :loading="loading" @click="onSubmit">提交</el-button>
+            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
+        </el-form-item>
+    </el-form>
 </template>
 
 <script lang="ts" setup>
+import { ref, PropType, defineAsyncComponent, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { Category } from '@/constants/enum/diamond'
+import { useDiamondForm } from '@/business/goods'
+import AppUpload from '@/components/base/upload/index.vue'
+
+defineProps({
+    code: String,
+    selectedRow: {
+        type: Object as PropType<Ermcp.UserRole>,
+        default: () => ({})
+    }
+})
+
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const emit = defineEmits(['loading', 'cancel'])
+const { loading, formItem, performanceId, shapeId, caratUnit, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Diamond)
+const formRef = ref<FormInstance>()
+
+const formRules: FormRules = {
+    ZSCategory: [{ required: true, message: '请选择商品分类' }],
+    GoodsNo: [{ required: true, message: '请输入商品编号', trigger: 'blur' }],
+    ZSCurrencyType: [{ required: true, message: '请选择货币类型' }],
+    Price: [{ required: true, type: 'number', message: '请输入价格' }],
+    Weight: [{ required: true, type: 'number', message: '请输入克拉重量' }],
+    ZSColorType1: [{ required: true, message: '请选择颜色' }],
+    ZSClarityType1: [{ required: true, message: '请选择净度' }],
+    WarehouseID: [{ required: true, message: '请选择仓库' }],
+    PerformanceTemplateID: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (performanceId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择履约方式'))
+            }
+        }
+    }],
+    ZSShapeType: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (shapeId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择形状'))
+            }
+        }
+    }],
+    Size: [{
+        validator: (rule, value, callback) => {
+            const { Size1, Size2, Size3 } = formItem
+            if ((!Size1 && !Size2 && !Size3) || (Size1 && Size2 && Size3)) {
+                callback()
+            } else {
+                callback(new Error('请输入尺寸'))
+            }
+        }
+    }],
+}
+
+// 选择形状
+const shapeChange = (value: number) => {
+    if (value) {
+        formItem.ZSShapeType = [value]
+    } else {
+        formItem.ZSShapeType = []
+    }
+}
+
+const onCancel = (isRefresh = false) => {
+    emit('cancel', isRefresh)
+}
+
+const onSubmit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            formSubmit().then(() => {
+                ElMessage.success('提交成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('提交失败:' + err)
+            })
+        }
+    })
+}
+
+watch(loading, (val) => emit('loading', val))
 </script>

+ 31 - 13
src/packages/pc/views/warehousing/stock/components/edit/diamonds.vue

@@ -1,10 +1,12 @@
-<!-- 我的库存-成批裸钻 -->
+<!-- 添加商品-成批裸钻 -->
 <template>
-    <el-form ref="formRef" class="el-form--horizontal" label-width="100px" label-position="left" :model="formItem"
-        :rules="formRules">
+    <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
         <el-form-item label="商品编号" prop="GoodsNo">
             <el-input placeholder="请输入" v-model="formItem.GoodsNo" />
         </el-form-item>
+        <el-form-item label="履约方式" prop="PerformanceTemplateID" v-if="code === 'warehousing_stock_sell'">
+            <component :is="components.performance" v-model="performanceId" />
+        </el-form-item>
         <el-form-item label="货币类型" prop="ZSCurrencyType">
             <el-radio-group v-model="formItem.ZSCurrencyType">
                 <el-radio :label="item.value" v-for="(item, index) in enums.currencyTypeList" :key="index">
@@ -31,7 +33,7 @@
             <span>{{ currencyInfo?.param2 }}{{ caratUnit }} (总价/总重量)</span>
         </el-form-item>
         <el-form-item class="el-form-item--row" label="形状" prop="ZSShapeType">
-            <app-multiple class="el-form-item--col" :data-list="enums.shapeTypeList" v-model="selectedType.shapeType"
+            <app-multiple class="el-form-item--col" :data-list="enums.shapeTypeList" v-model="formItem.ZSShapeType"
                 checkbox />
         </el-form-item>
         <el-form-item label="颜色" prop="ZSColorType">
@@ -67,22 +69,21 @@
                 <template #append>{{ currencyInfo?.enumitemvalue }}</template>
             </el-input>
         </el-form-item>
-        <el-form-item label="商品照片">
+        <el-form-item label="商品照片" prop="ImagePath">
             <app-upload />
         </el-form-item>
         <el-form-item class="el-form-item--row" label="备注" prop="Remark">
             <el-input type="textarea" v-model="formItem.Remark" />
         </el-form-item>
         <el-form-item class="el-form-item--row">
-            <el-button :loading="loading" type="primary" @click="onSubmit(1)">添加商品</el-button>
-            <el-button :loading="loading" type="primary">添加并上传</el-button>
-            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
+            <el-button type="primary" @click="onSubmit">提交</el-button>
+            <el-button @click="onCancel(false)" plain>取消</el-button>
         </el-form-item>
     </el-form>
 </template>
 
 <script lang="ts" setup>
-import { ref, PropType } from 'vue'
+import { ref, PropType, defineAsyncComponent, watch } from 'vue'
 import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { Category } from '@/constants/enum/diamond'
@@ -91,14 +92,19 @@ import AppMultiple from '@pc/components/base/multiple/index.vue'
 import AppUpload from '@/components/base/upload/index.vue'
 
 defineProps({
+    code: String,
     selectedRow: {
         type: Object as PropType<Ermcp.UserRole>,
         default: () => ({})
     }
 })
 
-const emit = defineEmits(['cancel'])
-const { loading, formItem, caratUnit, selectedType, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Diamonds)
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const emit = defineEmits(['loading', 'cancel'])
+const { loading, formItem, performanceId, caratUnit, selectedType, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Diamonds)
 const formRef = ref<FormInstance>()
 
 const formRules: FormRules = {
@@ -110,6 +116,16 @@ const formRules: FormRules = {
     WeightAvg: [{ required: true, type: 'number', message: '请输入平均重量' }],
     ZSShapeType: [{ required: true, message: '请选择形状' }],
     WarehouseID: [{ required: true, message: '请选择仓库' }],
+    PerformanceTemplateID: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (performanceId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择履约方式'))
+            }
+        }
+    }],
     ZSColorType: [{
         required: true,
         validator: (rule, value, callback) => {
@@ -172,10 +188,10 @@ const onCancel = (isRefresh = false) => {
     emit('cancel', isRefresh)
 }
 
-const onSubmit = (addType: number) => {
+const onSubmit = () => {
     formRef.value?.validate((valid) => {
         if (valid) {
-            formSubmit(addType).then(() => {
+            formSubmit().then(() => {
                 ElMessage.success('提交成功')
                 onCancel(true)
             }).catch((err) => {
@@ -184,4 +200,6 @@ const onSubmit = (addType: number) => {
         }
     })
 }
+
+watch(loading, (val) => emit('loading', val))
 </script>

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

@@ -1,6 +1,219 @@
+<!-- 添加商品-彩色钻石 -->
 <template>
-    <div>彩钻</div>
+    <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
+        <el-form-item label="商品编号" prop="GoodsNo">
+            <el-input placeholder="请输入" v-model="formItem.GoodsNo" />
+        </el-form-item>
+        <el-form-item label="履约方式" prop="PerformanceTemplateID" v-if="code === 'warehousing_stock_sell'">
+            <component :is="components.performance" v-model="performanceId" />
+        </el-form-item>
+        <el-form-item label="货币类型" prop="ZSCurrencyType">
+            <el-radio-group v-model="formItem.ZSCurrencyType">
+                <el-radio :label="item.value" v-for="(item, index) in enums.currencyTypeList" :key="index">
+                    {{ item.label }}
+                </el-radio>
+            </el-radio-group>
+        </el-form-item>
+        <el-form-item label="价格" prop="Price">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Price">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="克拉重量" prop="Weight">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Weight">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="克拉单位">
+            <span>{{ currencyInfo?.param2 }}{{ caratUnit }} (总价/总重量)</span>
+        </el-form-item>
+        <el-form-item label="尺寸" prop="Size">
+            <div class="el-form-item--col">
+                <el-input-number type="number" v-model="formItem.Size1" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size2" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size3" :controls="false" />
+            </div>
+        </el-form-item>
+        <el-form-item label="形状" prop="ZSShapeType">
+            <el-select v-model="shapeId" @change="shapeChange">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.shapeTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="颜色" prop="ZSCZColorType">
+            <div class="el-form-item--col">
+                <el-select v-model="formItem.ZSCZColor1Type">
+                    <el-option :label="item.label" :value="item.value"
+                        v-for="(item, index) in enums.fancyColorType1List" :key="index" />
+                </el-select>
+                <el-select v-model="formItem.ZSCZColor2Type">
+                    <el-option :label="item.label" :value="item.value"
+                        v-for="(item, index) in enums.fancyColorType2List" :key="index" />
+                </el-select>
+                <el-select v-model="formItem.ZSCZColor3Type">
+                    <el-option :label="item.label" :value="item.value"
+                        v-for="(item, index) in enums.fancyColorType3List" :key="index" />
+                </el-select>
+            </div>
+        </el-form-item>
+        <el-form-item label="净度" prop="ZSClarityType1">
+            <el-select v-model="formItem.ZSClarityType1">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.clarityTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="抛光" prop="ZSPolishType1">
+            <el-select v-model="formItem.ZSPolishType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.polishTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="对称" prop="ZSSymmetryType1">
+            <el-select v-model="formItem.ZSSymmetryType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.symmetryTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="荧光" prop="ZSFluorescenceType1">
+            <el-select v-model="formItem.ZSFluorescenceType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.fluorescenceTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="仓库" prop="WarehouseID">
+            <el-select v-model="formItem.WarehouseID">
+                <el-option :label="item.warehousename" :value="item.autoid" v-for="(item, index) in warehouseList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="市场价" prop="MarketPrice">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.MarketPrice">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="证书类型" prop="ZSCertType">
+            <el-select v-model="formItem.ZSCertType" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.certTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="证书编号" prop="CerNo">
+            <el-input placeholder="请输入" v-model="formItem.CerNo" />
+        </el-form-item>
+        <el-form-item label="商品照片" prop="ImagePath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item class="el-form-item--row" label="备注" prop="Remark">
+            <el-input type="textarea" v-model="formItem.Remark" />
+        </el-form-item>
+        <el-form-item class="el-form-item--row">
+            <el-button type="primary" :loading="loading" @click="onSubmit">提交</el-button>
+            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
+        </el-form-item>
+    </el-form>
 </template>
 
 <script lang="ts" setup>
+import { ref, PropType, defineAsyncComponent, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { Category } from '@/constants/enum/diamond'
+import { useDiamondForm } from '@/business/goods'
+import AppUpload from '@/components/base/upload/index.vue'
+
+defineProps({
+    code: String,
+    selectedRow: {
+        type: Object as PropType<Ermcp.UserRole>,
+        default: () => ({})
+    }
+})
+
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const emit = defineEmits(['loading', 'cancel'])
+const { loading, formItem, performanceId, shapeId, caratUnit, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Fancy)
+const formRef = ref<FormInstance>()
+
+const formRules: FormRules = {
+    ZSCategory: [{ required: true, message: '请选择商品分类' }],
+    GoodsNo: [{ required: true, message: '请输入商品编号', trigger: 'blur' }],
+    ZSCurrencyType: [{ required: true, message: '请选择货币类型' }],
+    Price: [{ required: true, type: 'number', message: '请输入价格' }],
+    Weight: [{ required: true, type: 'number', message: '请输入克拉重量' }],
+    ZSClarityType1: [{ required: true, message: '请选择净度' }],
+    WarehouseID: [{ required: true, message: '请选择仓库' }],
+    PerformanceTemplateID: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (performanceId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择履约方式'))
+            }
+        }
+    }],
+    ZSShapeType: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (shapeId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择形状'))
+            }
+        }
+    }],
+    ZSCZColorType: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (formItem.ZSCZColor1Type && formItem.ZSCZColor2Type && formItem.ZSCZColor3Type) {
+                callback()
+            } else {
+                callback(new Error('请选择颜色'))
+            }
+        }
+    }],
+    Size: [{
+        validator: (rule, value, callback) => {
+            const { Size1, Size2, Size3 } = formItem
+            if ((!Size1 && !Size2 && !Size3) || (Size1 && Size2 && Size3)) {
+                callback()
+            } else {
+                callback(new Error('请输入尺寸'))
+            }
+        }
+    }],
+}
+
+// 选择形状
+const shapeChange = (value: number) => {
+    if (value) {
+        formItem.ZSShapeType = [value]
+    } else {
+        formItem.ZSShapeType = []
+    }
+}
+
+const onCancel = (isRefresh = false) => {
+    emit('cancel', isRefresh)
+}
+
+const onSubmit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            formSubmit().then(() => {
+                ElMessage.success('提交成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('提交失败:' + err)
+            })
+        }
+    })
+}
+
+watch(loading, (val) => emit('loading', val))
 </script>

+ 11 - 4
src/packages/pc/views/warehousing/stock/components/edit/index.vue

@@ -1,13 +1,14 @@
 <!-- 账号权限 -->
 <template>
-    <app-drawer title="商品上架" :width="960" v-model:show="show" :refresh="refresh">
+    <app-drawer :title="code === 'warehousing_stock_sell' ? '商品上架' : '添加商品'" :width="960" v-model:show="show"
+        :loading="loading" :refresh="refresh">
         <el-tabs v-model="componentId">
             <template v-for="(item, index) in categoryList" :key="index">
                 <el-tab-pane :label="item.label" :name="Category[item.value]" />
             </template>
         </el-tabs>
-        <component :is="componentMap.get(componentId)" v-bind="{ selectedRow }" style="padding-bottom:24px"
-            @cancel="onCancel" v-if="componentId" />
+        <component :is="componentMap.get(componentId)" v-bind="{ code, selectedRow }" style="padding-bottom:24px"
+            @cancel="onCancel" @loading="onLoading" v-if="componentId" />
     </app-drawer>
 </template>
 
@@ -17,6 +18,7 @@ import { getCategoryList, Category } from '@/constants/enum/diamond'
 import AppDrawer from '@pc/components/base/drawer/index.vue'
 
 defineProps({
+    code: String,
     selectedRow: {
         type: Object as PropType<Ermcp.GoodsRsp>,
         default: () => ({})
@@ -32,6 +34,7 @@ const componentMap = new Map<string, unknown>([
 ])
 
 const show = shallowRef(true)
+const loading = shallowRef(false)
 const refresh = shallowRef(false)
 const componentId = shallowRef('')
 const categoryList = getCategoryList()
@@ -41,7 +44,11 @@ if (categoryList.length) {
     componentId.value = Category[value]
 }
 
-const onCancel = (isRefresh = false) => {
+const onLoading = (isLoading: boolean) => {
+    loading.value = isLoading
+}
+
+const onCancel = (isRefresh: boolean) => {
     show.value = false
     refresh.value = isRefresh
 }

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

@@ -1,6 +1,217 @@
+<!-- 添加商品-钻石首饰 -->
 <template>
-    <div>首饰</div>
+    <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
+        <el-form-item label="商品编号" prop="GoodsNo">
+            <el-input placeholder="请输入" v-model="formItem.GoodsNo" />
+        </el-form-item>
+        <el-form-item label="履约方式" prop="PerformanceTemplateID" v-if="code === 'warehousing_stock_sell'">
+            <component :is="components.performance" v-model="performanceId" />
+        </el-form-item>
+        <el-form-item label="货币类型" prop="ZSCurrencyType">
+            <el-radio-group v-model="formItem.ZSCurrencyType">
+                <el-radio :label="item.value" v-for="(item, index) in enums.currencyTypeList" :key="index">
+                    {{ item.label }}
+                </el-radio>
+            </el-radio-group>
+        </el-form-item>
+        <el-form-item label="价格" prop="Price">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Price">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="主石重量" prop="Weight">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Weight">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="款式" prop="ZSStyleType">
+            <el-select v-model="formItem.ZSStyleType">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.styleTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="尺寸" prop="Size">
+            <div class="el-form-item--col">
+                <el-input-number type="number" v-model="formItem.Size1" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size2" :controls="false" />
+                <span>×</span>
+                <el-input-number type="number" v-model="formItem.Size3" :controls="false" />
+            </div>
+        </el-form-item>
+        <el-form-item label="形状" prop="ZSShapeType">
+            <el-select v-model="shapeId" @change="shapeChange">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.shapeTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="切工" prop="ZSCutType1">
+            <el-select v-model="formItem.ZSCutType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.cutTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="颜色" prop="ZSColorType1">
+            <el-select v-model="formItem.ZSColorType1">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.colorTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="抛光" prop="ZSPolishType1">
+            <el-select v-model="formItem.ZSPolishType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.polishTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="净度" prop="ZSClarityType1">
+            <el-select v-model="formItem.ZSClarityType1">
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.clarityTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="荧光" prop="ZSFluorescenceType1">
+            <el-select v-model="formItem.ZSFluorescenceType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.fluorescenceTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="对称" prop="ZSSymmetryType1">
+            <el-select v-model="formItem.ZSSymmetryType1" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.symmetryTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="市场价" prop="MarketPrice">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.MarketPrice">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="仓库" prop="WarehouseID">
+            <el-select v-model="formItem.WarehouseID">
+                <el-option :label="item.warehousename" :value="item.autoid" v-for="(item, index) in warehouseList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="镶嵌材料" prop="SettingMaterial">
+            <el-input placeholder="请输入" v-model="formItem.SettingMaterial" />
+        </el-form-item>
+        <el-form-item label="证书类型" prop="ZSCertType">
+            <el-select v-model="formItem.ZSCertType" clearable>
+                <el-option :label="item.label" :value="item.value" v-for="(item, index) in enums.certTypeList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="证书编号" prop="CerNo">
+            <el-input placeholder="请输入" v-model="formItem.CerNo" />
+        </el-form-item>
+        <el-form-item label="配石描述" prop="StoneDesc">
+            <el-input placeholder="请输入" v-model="formItem.StoneDesc" />
+        </el-form-item>
+        <el-form-item label="商品照片" prop="ImagePath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item class="el-form-item--row" label="备注" prop="Remark">
+            <el-input type="textarea" v-model="formItem.Remark" />
+        </el-form-item>
+        <el-form-item class="el-form-item--row">
+            <el-button type="primary" :loading="loading" @click="onSubmit">提交</el-button>
+            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
+        </el-form-item>
+    </el-form>
 </template>
 
 <script lang="ts" setup>
+import { ref, PropType, defineAsyncComponent, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { Category } from '@/constants/enum/diamond'
+import { useDiamondForm } from '@/business/goods'
+import AppUpload from '@/components/base/upload/index.vue'
+
+defineProps({
+    code: String,
+    selectedRow: {
+        type: Object as PropType<Ermcp.UserRole>,
+        default: () => ({})
+    }
+})
+
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const emit = defineEmits(['loading', 'cancel'])
+const { loading, formItem, performanceId, shapeId, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Jewelry)
+const formRef = ref<FormInstance>()
+
+const formRules: FormRules = {
+    ZSCategory: [{ required: true, message: '请选择商品分类' }],
+    GoodsNo: [{ required: true, message: '请输入商品编号', trigger: 'blur' }],
+    SettingMaterial: [{ required: true, message: '请输入镶嵌材料', trigger: 'blur' }],
+    ZSCurrencyType: [{ required: true, message: '请选择货币类型' }],
+    ZSStyleType: [{ required: true, message: '请选择款式' }],
+    Price: [{ required: true, type: 'number', message: '请输入价格' }],
+    Weight: [{ required: true, type: 'number', message: '请输入克拉重量' }],
+    ZSColorType1: [{ required: true, message: '请选择颜色' }],
+    ZSClarityType1: [{ required: true, message: '请选择净度' }],
+    WarehouseID: [{ required: true, message: '请选择仓库' }],
+    PerformanceTemplateID: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (performanceId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择履约方式'))
+            }
+        }
+    }],
+    ZSShapeType: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (shapeId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择形状'))
+            }
+        }
+    }],
+    Size: [{
+        validator: (rule, value, callback) => {
+            const { Size1, Size2, Size3 } = formItem
+            if ((!Size1 && !Size2 && !Size3) || (Size1 && Size2 && Size3)) {
+                callback()
+            } else {
+                callback(new Error('请输入尺寸'))
+            }
+        }
+    }],
+}
+
+// 选择形状
+const shapeChange = (value: number) => {
+    if (value) {
+        formItem.ZSShapeType = [value]
+    } else {
+        formItem.ZSShapeType = []
+    }
+}
+
+const onCancel = (isRefresh = false) => {
+    emit('cancel', isRefresh)
+}
+
+const onSubmit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            formSubmit().then(() => {
+                ElMessage.success('提交成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('提交失败:' + err)
+            })
+        }
+    })
+}
+
+watch(loading, (val) => emit('loading', val))
 </script>

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

@@ -1,6 +1,186 @@
+<!-- 添加商品-成批毛坯 -->
 <template>
-    <div>毛坯</div>
+    <el-form ref="formRef" class="el-form--horizontal" label-width="110px" :model="formItem" :rules="formRules">
+        <el-form-item label="商品编号" prop="GoodsNo">
+            <el-input placeholder="请输入" v-model="formItem.GoodsNo" />
+        </el-form-item>
+        <el-form-item label="履约方式" prop="PerformanceTemplateID" v-if="code === 'warehousing_stock_sell'">
+            <component :is="components.performance" v-model="performanceId" />
+        </el-form-item>
+        <el-form-item label="货币类型" prop="ZSCurrencyType">
+            <el-radio-group v-model="formItem.ZSCurrencyType">
+                <el-radio :label="item.value" v-for="(item, index) in enums.currencyTypeList" :key="index">
+                    {{ item.label }}
+                </el-radio>
+            </el-radio-group>
+        </el-form-item>
+        <el-form-item label="总价" prop="Price">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Price">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="总重量" prop="Weight">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.Weight">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="平均重量" prop="WeightAvg">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.WeightAvg">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="克拉单位">
+            <span>{{ currencyInfo?.param2 }}{{ caratUnit }} (总价/总重量)</span>
+        </el-form-item>
+        <el-form-item class="el-form-item--row" label="晶型" prop="ZSCrystalType">
+            <app-multiple class="el-form-item--col" :data-list="enums.crystalTypeList" v-model="formItem.ZSCrystalType"
+                checkbox />
+        </el-form-item>
+        <el-form-item label="颜色" prop="ZSColorType">
+            <app-multiple class="el-form-item--col" :data-list="enums.colorTypeList" v-model="selectedType.colorType" />
+        </el-form-item>
+        <el-form-item label="荧光" prop="ZSFluorescenceType">
+            <app-multiple class="el-form-item--col" :data-list="enums.fluorescenceTypeList"
+                v-model="selectedType.fluorescenceType" />
+        </el-form-item>
+        <el-form-item label="净度" prop="ZSClarityType">
+            <app-multiple class="el-form-item--col" :data-list="enums.clarityTypeList"
+                v-model="selectedType.clarityType" />
+        </el-form-item>
+        <el-form-item label="原产地" prop="Origin">
+            <el-input placeholder="请输入" v-model="formItem.Origin" />
+        </el-form-item>
+        <el-form-item label="仓库" prop="WarehouseID">
+            <el-select v-model="formItem.WarehouseID">
+                <el-option :label="item.warehousename" :value="item.autoid" v-for="(item, index) in warehouseList"
+                    :key="index" />
+            </el-select>
+        </el-form-item>
+        <el-form-item label="金伯利编号" prop="CPCertNo">
+            <el-input placeholder="请输入" v-model="formItem.CPCertNo" />
+        </el-form-item>
+        <el-form-item label="市场价" prop="MarketPrice">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.MarketPrice">
+                <template #append>{{ currencyInfo?.enumitemvalue }}</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="金伯利重量" prop="KPWeight">
+            <el-input type="number" placeholder="请输入" v-model.number="formItem.KPWeight">
+                <template #append>(克拉)</template>
+            </el-input>
+        </el-form-item>
+        <el-form-item label="商品照片" prop="ImagePath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item label="金伯利图片" prop="KPPath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item label="仓单扫描件" prop="WRPath">
+            <app-upload />
+        </el-form-item>
+        <el-form-item class="el-form-item--row" label="备注" prop="Remark">
+            <el-input type="textarea" v-model="formItem.Remark" />
+        </el-form-item>
+        <el-form-item class="el-form-item--row">
+            <el-button :loading="loading" type="primary" @click="onSubmit">提交</el-button>
+            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
+        </el-form-item>
+    </el-form>
 </template>
 
 <script lang="ts" setup>
+import { ref, PropType, defineAsyncComponent, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import { Category } from '@/constants/enum/diamond'
+import { useDiamondForm } from '@/business/goods'
+import AppMultiple from '@pc/components/base/multiple/index.vue'
+import AppUpload from '@/components/base/upload/index.vue'
+
+defineProps({
+    code: String,
+    selectedRow: {
+        type: Object as PropType<Ermcp.UserRole>,
+        default: () => ({})
+    }
+})
+
+const components = {
+    performance: defineAsyncComponent(() => import('@pc/components/modules/performance/index.vue')),
+}
+
+const emit = defineEmits(['loading', 'cancel'])
+const { loading, formItem, performanceId, caratUnit, selectedType, enums, warehouseList, currencyInfo, formSubmit } = useDiamondForm(Category.Rough)
+const formRef = ref<FormInstance>()
+
+const formRules: FormRules = {
+    ZSCategory: [{ required: true, message: '请选择商品分类' }],
+    GoodsNo: [{ required: true, message: '请输入商品编号', trigger: 'blur' }],
+    Origin: [{ required: true, message: '请输入原产地', trigger: 'blur' }],
+    CPCertNo: [{ required: true, message: '请输入金伯利证书编号', trigger: 'blur' }],
+    KPWeight: [{ required: true, message: '请输入金伯利证书重量', trigger: 'blur' }],
+    ZSCurrencyType: [{ required: true, message: '请选择货币类型' }],
+    Price: [{ required: true, type: 'number', message: '请输入总价' }],
+    Weight: [{ required: true, type: 'number', message: '请输入总重量' }],
+    WeightAvg: [{ required: true, type: 'number', message: '请输入平均重量' }],
+    WarehouseID: [{ required: true, message: '请选择仓库' }],
+    KPPath: [{ required: true, message: '请上传金伯利证书图片' }],
+    PerformanceTemplateID: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (performanceId.value) {
+                callback()
+            } else {
+                callback(new Error('请选择履约方式'))
+            }
+        }
+    }],
+    ZSColorType: [{
+        required: true,
+        validator: (rule, value, callback) => {
+            if (formItem.ZSColorType1 && formItem.ZSColorType2) {
+                callback()
+            } else {
+                callback(new Error('请选择颜色'))
+            }
+        }
+    }],
+    ZSClarityType: [{
+        validator: (rule, value, callback) => {
+            if ((!formItem.ZSClarityType1 && !formItem.ZSClarityType2) || (formItem.ZSClarityType1 && formItem.ZSClarityType2)) {
+                callback()
+            } else {
+                callback(new Error('请选择净度'))
+            }
+        }
+    }],
+    ZSFluorescenceType: [{
+        validator: (rule, value, callback) => {
+            if ((!formItem.ZSFluorescenceType1 && !formItem.ZSFluorescenceType2) || (formItem.ZSFluorescenceType1 && formItem.ZSFluorescenceType2)) {
+                callback()
+            } else {
+                callback(new Error('请选择荧光'))
+            }
+        }
+    }]
+}
+
+const onCancel = (isRefresh = false) => {
+    emit('cancel', isRefresh)
+}
+
+const onSubmit = () => {
+    formRef.value?.validate((valid) => {
+        if (valid) {
+            formSubmit().then(() => {
+                ElMessage.success('提交成功')
+                onCancel(true)
+            }).catch((err) => {
+                ElMessage.error('提交失败:' + err)
+            })
+        }
+    })
+}
+
+watch(loading, (val) => emit('loading', val))
 </script>

+ 7 - 6
src/packages/pc/views/warehousing/stock/index.vue

@@ -1,13 +1,13 @@
-<!-- 我的库存 -->
+<!-- 我的仓储-我的库存 -->
 <template>
-    <app-view class="market-quote">
+    <app-view>
         <template #header>
-            <app-filter v-bind="{ selectList, inputList, buttonMap }" />
+            <app-filter v-bind="{ selectList, inputList, buttonList }" :loading="loading" />
         </template>
         <!-- 表格数据 -->
         <app-table :data="dataList" v-model:columns="columns" :loading="loading">
             <template #header>
-                <app-auth-operation :menus="['add']" />
+                <app-auth-operation :menus="['add', 'sell']" @closed="getDiamondList" />
             </template>
             <!-- 颜色 -->
             <template #zscolortype="{ row }">
@@ -19,7 +19,8 @@
             </template>
             <!-- 操作 -->
             <template #operate="{ row }">
-                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" linkButton />
+                <app-auth-operation :menus="['details']" :options="{ selectedRow: row }" @closed="getDiamondList"
+                    linkButton />
             </template>
             <template #footer v-if="total > pageSize">
                 <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
@@ -37,7 +38,7 @@ import AppPagination from '@pc/components/base/pagination/index.vue'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppFilter from '@pc/components/base/table-filter/index.vue'
 
-const { loading, dataList, total, pageIndex, pageSize, columns, selectList, inputList, buttonMap, getDiamondList } = useDiamond()
+const { loading, dataList, total, pageIndex, pageSize, columns, selectList, inputList, buttonList, getDiamondList } = useDiamond()
 
 getDiamondList().catch((err) => ElMessage.error(err))
 </script>

+ 8 - 9
src/packages/pc/views/warehousing/warehouse/components/edit/index.vue

@@ -1,9 +1,8 @@
 <!-- 我的仓库-编辑仓库 -->
 <template>
-    <app-drawer :title="selectedRow.warehousecode ? '修改仓库' : '新增仓库'" :width="880" v-model:show="show"
+    <app-drawer :title="selectedRow.warehousecode ? '修改仓库' : '新增仓库'" :width="880" v-model:show="show" :loading="loading"
         :refresh="refresh">
-        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" label-position="left" :model="formItem"
-            :rules="formRules">
+        <el-form ref="formRef" class="el-form--horizontal" label-width="100px" :model="formItem" :rules="formRules">
             <el-form-item label="仓库代码" prop="warehousecode">
                 <el-input placeholder="请输入" v-model="formItem.warehousecode" />
             </el-form-item>
@@ -29,11 +28,11 @@
             <el-form-item class="el-form-item--row" prop="address">
                 <el-input placeholder="请输入" v-model="formItem.address" />
             </el-form-item>
+            <el-form-item class="el-form-item--row">
+                <el-button type="primary" @click="onSubmit">提交</el-button>
+                <el-button @click="onCancel(false)" plain>取消</el-button>
+            </el-form-item>
         </el-form>
-        <template #footer>
-            <el-button :loading="loading" @click="onCancel(false)" plain>取消</el-button>
-            <el-button :loading="loading" type="primary" @click="onSubmit">提交</el-button>
-        </template>
     </app-drawer>
 </template>
 
@@ -62,7 +61,7 @@ const formRules: FormRules = {
     warehousename: [{ required: true, message: '请输入仓库名称', trigger: 'blur' }],
     contactname: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
     contactnum: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
-    address: [{ required: true, message: '请输入仓库地址', trigger: 'blur' }],
+    address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }],
     area: [
         {
             required: true,
@@ -70,7 +69,7 @@ const formRules: FormRules = {
                 if (formItem.provinceid && formItem.cityid && formItem.districtid) {
                     callback()
                 } else {
-                    callback(new Error('请选择仓库地'))
+                    callback(new Error('请选择仓库地'))
                 }
             }
         }

+ 5 - 3
src/packages/pc/views/warehousing/warehouse/index.vue

@@ -1,3 +1,4 @@
+<!-- 我的仓储-我的仓库 -->
 <template>
     <app-view>
         <app-table :data="dataList" v-model:columns="columns">
@@ -8,8 +9,9 @@
                 <app-auth-operation :menus="['edit']" :options="{ selectedRow: row }" @closed="getWarehouseList"
                     linkButton />
             </template>
-            <template #footer>
-                <app-pagination :total="400" />
+            <template #footer v-if="total > pageSize">
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
+                    @change="getWarehouseList" />
             </template>
         </app-table>
     </app-view>
@@ -22,7 +24,7 @@ import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
 
-const { dataList, columns, getWarehouseList } = useWarehouse()
+const { dataList, columns, total, pageIndex, pageSize, getWarehouseList } = useWarehouse()
 
 getWarehouseList().catch((err) => ElMessage.error(err))
 </script>

+ 28 - 0
src/services/api/order/index.ts

@@ -12,6 +12,27 @@ export function zsBuyOrderListing(params: TradeRequest<Proto.ZSBuyOrderListingRe
 }
 
 /**
+ * 钻石卖挂牌
+ */
+export function zsSellOrderListing(params: TradeRequest<Proto.ZSSellOrderListingReq, Proto.ZSSellOrderListingRsp>) {
+    return tradeServerRequest('ZSSellOrderListingReq', 'ZSSellOrderListingRsp', params, Market.GZ);
+}
+
+/**
+ * 查询求购大厅委托单
+ */
+export function queryBuyOrder(params: HttpRequest<{ req: Ermcp.BuyOrderReq, rsp: Ermcp.BuyOrderRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryBuyOrder', 'get', params);
+}
+
+/**
+ * 查询我的求购
+ */
+export function queryMyBuyOrder(params: HttpRequest<{ req: Ermcp.MyBuyOrderReq, rsp: Ermcp.MyBuyOrderRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryMyBuyOrder', 'get', params);
+}
+
+/**
  * 搜索出售大厅委托单
  */
 export function sellOrderSearch(params: HttpRequest<{ req: Ermcp.SellOrderSearchReq, rsp: Ermcp.SellOrderRsp[] }>) {
@@ -23,4 +44,11 @@ export function sellOrderSearch(params: HttpRequest<{ req: Ermcp.SellOrderSearch
  */
 export function querySellOrder(params: HttpRequest<{ req: Ermcp.SellOrderReq, rsp: Ermcp.SellOrderRsp[] }>) {
     return httpRequest('/Guangzuan/QuerySellOrder', 'get', params);
+}
+
+/**
+ * 查询我的出售
+ */
+export function queryMySellOrder(params: HttpRequest<{ req: Ermcp.MySellOrderReq, rsp: Ermcp.MySellOrderRsp[] }>) {
+    return httpRequest('/Guangzuan/QueryMySellOrder', 'get', params);
 }

+ 182 - 2
src/types/ermcp/order.d.ts

@@ -51,7 +51,7 @@ declare namespace Ermcp {
         clientordertime: string; // 客户端委托时间
         exchangerate: number; // 汇率[67]
         firstratio: number; // 首付比率 - [挂牌时指定,摘牌时使用]
-        fixedprice: number; // 固定价格 - [挂牌]
+        fixedprice: number; // [克拉单价]固定价格 - [挂牌]
         freezecharge: number; // 冻结手续费
         freezefirstamount: number; // 冻结首付金额 - [摘牌]
         freezemargin: number; // 冻结保证金
@@ -62,14 +62,15 @@ declare namespace Ermcp {
         marginvalue: number; // 保证金设置值
         marketid: number; // 市场ID
         orderamount: number; // 挂牌金额[账户] [67]= OrderQty * FixedPrice * ExchangeRate /100
-        orderqty: number; // 委托数量
         ordertime: string; // 委托时间
         performancetemplateid: number; // 履约计划模板ID
         pricefactor: number; // 价格系数(浮动价时填写) - [挂牌]
         pricemove: number; // 升贴水(浮动价时填写) - [挂牌]
         relatedwrtradeorderid: number; // 关联委托单号(摘牌委托关联挂牌委托单ID)
+        remainqty: number; // 剩余重量
         retcode: number; // 错误代码
         sellusername: string; // 卖方(查询字段-模糊查询)
+        totalqty: number; // 总重量
         tradedate: string; // 交易日(yyyyMMdd)
         tradeprice: number; // 成交价格 - [摘牌] (浮动价 ((商品1价格商品1价格系数+升贴水) 商品1重量系数 + 商品2价格商品2价格系数+商品2升贴水) 商品2重量系数 …)* 委托单价格系数 + 委托单升贴水)
         tradeqty: number; // 成交数量
@@ -91,4 +92,183 @@ declare namespace Ermcp {
         zscategory: number; // 钻石分类 - 枚举”ZSCategory“
         zscurrencytype: number; // 货币类型 - 枚举“ZSCurrencyType”
     }
+
+    /** 查询求购大厅委托单请求 */
+    interface BuyOrderReq {
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        zsallproperties?: string; // 商品(查询字段-模糊查询)
+        zscategory?: number; // 钻石分类枚举ID
+        wrtradeorderid?: number; // 委托单号
+        buyusername?: string; // 买方(查询字段-模糊查询)
+    }
+
+    /** 查询求购大厅委托单响应 */
+    interface BuyOrderRsp {
+        accountid: number; // 资金账户ID
+        buyusername: string; // 买方
+        marketid: number; // 市场ID
+        ordertime: string; // 委托时间
+        origin: string; // 原产地
+        remark: string; // 备注
+        userid: number; // 用户ID
+        validtime: string; // 有效期限
+        warehouseids: string; // 仓库ID - 多个, 逗号分隔
+        warehouseinfosdisplay: string;
+        wrtradeorderstatus: number; // 委托状态 - 参考枚举’WRTradeOrderStatus’ - 1:委托请求 2:待冻结 3:委托成功 4:委托失败 5:配对成功 6:已撤 7:部成 8:已成 9:部成部撤 10:成交失败 11:委托拒绝 12:经过摘牌(先摘后挂专用) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用) 17:冻结PD成功 18:冻结PD失败 19:冻结能量成功 20:冻结能量失败 21:预约已报价 22:过期未付 23:优惠券处理中 24:仓单生成失败 25:首付扣款失败 26:履约失败 27:撤单解冻贷款失败WRTrade_OrderDetail、
+        wrtradeorderid: number; // [委托单号]买委托单ID(320+Unix秒时间戳(10位)+xxxxxx)
+        zscategory: number; // 钻石分类 - 枚举”ZSCategory“
+        zscategorydisplay: string;
+        zsclaritytype: string; // 净度 - 两个, 逗号分隔
+        zsclaritytypedisplay: string;
+        zscolortype: string; // 颜色 - 两个, 逗号分隔
+        zscolortypedisplay: string;
+        zscrystaltype: string; // 晶型 - 多个,逗号分隔
+        zscrystaltypedisplay: string;
+        zscurrencytype: string; // 货币类型 - 多个, 逗号分隔
+        zscurrencytypedisplay: string;
+        zscuttype: string; // 切工 - 两个, 逗号分隔
+        zscuttypedisplay: string;
+        zsczcolor1type: string; // 彩钻颜色1, 逗号分隔
+        zsczcolor1typedisplay: string;
+        zsczcolor2type: string; // 彩钻颜色2, 逗号分隔
+        zsczcolor2typedisplay: string;
+        zsczcolor3type: string; // 彩钻颜色3, 逗号分隔
+        zsczcolor3typedisplay: string;
+        zsfluorescencetype: string; // 荧光 - 多个, 逗号分隔
+        zsfluorescencetypedisplay: string;
+        zspolishtype: string; // 抛光度 - 两个, 逗号分隔
+        zspolishtypedisplay: string;
+        zsshapetype: string; // 形状 - 多个, 逗号分隔
+        zsshapetypedisplay: string;
+        zssize: string; // 尺寸 - 两个小数, 逗号分隔
+        zsstyletype: string; // 款式 - 多个, 逗号分隔
+        zsstyletypedisplay: string;
+        zssymmetrytype: string; // 对称度 - 两个, 逗号分隔
+        zssymmetrytypedisplay: string;
+        zstabledisplay: string; // 求购信息
+    }
+
+    /** 查询我的出售请求 */
+    interface MySellOrderReq {
+        userid: number; // 用户ID
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        zsallproperties?: string; // 商品(查询字段-模糊查询)
+        zscategory?: number; // 钻石分类枚举ID
+        wrtradeorderid?: number; // 委托单号
+        ishis?: string; // 是否历史查询
+    }
+
+    /** 查询我的出售响应 */
+    interface MySellOrderRsp {
+        accountid: number; // 资金账号
+        applyid: number; // 申请单ID
+        attachment1: string; // 附件1
+        attachment2: string; // 附件2
+        buyorsell: number; // 买卖 - 0:买 1:卖
+        canbargain: number; // 是否可议价 - 0:不可 1:可
+        cancelqty: number; // 撤销数量
+        canceltime: string; // 撤销时间
+        chargealgorithm: number; // 手续费收取方式 1:比率 2:固定
+        chargealgorithmvalue: number; // 手续费设置值(交易所部分)
+        chargealgorithmvalue2: number; // 手续费设置值(会员部分)
+        clientordertime: string; // 客户端委托时间
+        exchangerate: number; // 汇率[67]
+        firstratio: number; // 首付比率 - [挂牌时指定,摘牌时使用]
+        fixedprice: number; // [克拉单价]固定价格 - [挂牌]
+        freezecharge: number; // 冻结手续费
+        freezefirstamount: number; // 冻结首付金额 - [摘牌]
+        freezemargin: number; // 冻结保证金
+        goodsno: string; // 商品编号
+        isspecified: number; // 是否指定对手 - 0:不指定 1:指定好友(贸易圈) 2:指定对手 - [挂牌]
+        marginalgorithm: number; // 保证金方式 - 1:比率 2:固定
+        marginvalue: number; // 保证金设置值
+        marketid: number; // 市场ID
+        orderamount: number; // 挂牌金额[账户] [67]= OrderQty * FixedPrice * ExchangeRate /100
+        ordertime: string; // 委托时间
+        performancetemplateid: number; // 履约计划模板ID
+        pricefactor: number; // 价格系数(浮动价时填写) - [挂牌]
+        pricemove: number; // 升贴水(浮动价时填写) - [挂牌]
+        relatedwrtradeorderid: number; // 关联委托单号(摘牌委托关联挂牌委托单ID)
+        retcode: number; // 错误代码
+        selledqty: number; // 成交重量
+        totalqty: number; // 总重量
+        tradedate: string; // 交易日(yyyyMMdd)
+        tradeprice: number; // 成交价格 - [摘牌] (浮动价 ((商品1价格商品1价格系数+升贴水) 商品1重量系数 + 商品2价格商品2价格系数+商品2升贴水) 商品2重量系数 …)* 委托单价格系数 + 委托单升贴水)
+        tradeqty: number; // 成交数量
+        unfreezecharge: number; // 解冻手续费
+        unfreezefirstamount: number; // 解冻首付金额 - [摘牌]
+        unfreezemargin: number; // 解冻保证金
+        userid: number; // 用户ID
+        uuid: string; // 发起端唯一id
+        validtime: string; // 有效期限
+        validtype: number; // 有效类型 - 1当日有效 2本周有效 3指定日期有效 4一直有效
+        wrbargainid: number; // 议价申请单ID
+        wrfactortypeid: number; // 仓单要素类型ID/商品ID(77)
+        wrpricetype: number; // 价格方式 - 1:固定价 2-浮动价 - [挂牌]
+        wrstandardid: number; // 现货商品ID
+        wrtradeorderid: number; // 仓单贸易委托单ID(320+Unix秒时间戳(10位)+xxxxxx)
+        wrtradeorderstatus: number; // 委托状态 - 参考枚举’WRTradeOrderStatus’ - 1:委托请求 2:待冻结 3:委托成功 4:委托失败 5:配对成功 6:已撤 7:部成 8:已成 9:部成部撤 10:成交失败 11:委托拒绝 12:经过摘牌(先摘后挂专用) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用) 17:冻结PD成功 18:冻结PD失败 19:冻结能量成功 20:冻结能量失败 21:预约已报价 22:过期未付 23:优惠券处理中 24:仓单生成失败 25:首付扣款失败 26:履约失败 27:撤单解冻贷款失败
+        wrtradetype: number; // 仓单贸易类型 - 1:挂牌 2:摘牌 3:提货卖(文化中国) 4:提货买(文化中国)
+        wrtransferuserid: number; // 仓单受让用户 - [摘牌]
+        zscategory: number; // 钻石分类 - 枚举”ZSCategory“
+        zscurrencytype: number; // 货币类型 - 枚举“ZSCurrencyType”
+    }
+
+    /** 查询我的求购请求 */
+    interface MyBuyOrderReq {
+        userid: number; // 用户ID
+        page?: number; // 页码
+        pagesize?: number; // 每页条数
+        zsallproperties?: string; // 商品(查询字段-模糊查询)
+        zscategory?: number; // 钻石分类枚举ID
+        wrtradeorderid?: number; // 委托单号
+        ishis?: string; // 是否历史查询
+    }
+
+    /** 查询我的求购响应 */
+    interface MyBuyOrderRsp {
+        accountid: number; // 资金账户ID
+        marketid: number; // 市场ID
+        ordertime: string; // 委托时间
+        origin: string; // 原产地
+        remark: string; // 备注
+        userid: number; // 用户ID
+        validtime: string; // 有效期限
+        warehouseids: string; // 仓库ID - 多个, 逗号分隔
+        warehouseinfosdisplay: string;
+        wrtradeorderid: number; // [委托单号]买委托单ID(320+Unix秒时间戳(10位)+xxxxxx)
+        wrtradeorderstatus: number; // 委托状态 - 参考枚举’WRTradeOrderStatus’ - 1:委托请求 2:待冻结 3:委托成功 4:委托失败 5:配对成功 6:已撤 7:部成 8:已成 9:部成部撤 10:成交失败 11:委托拒绝 12:经过摘牌(先摘后挂专用) 13:冻结成功(通道交易专用) 14:通道已撤 15:通道部成部撤 16:成交失败违约(荷兰式竞拍专用) 17:冻结PD成功 18:冻结PD失败 19:冻结能量成功 20:冻结能量失败 21:预约已报价 22:过期未付 23:优惠券处理中 24:仓单生成失败 25:首付扣款失败 26:履约失败 27:撤单解冻贷款失败WRTrade_OrderDetail、
+        zscategory: number; // 钻石分类 - 枚举”ZSCategory“
+        zscategorydisplay: string;
+        zsclaritytype: string; // 净度 - 两个, 逗号分隔
+        zsclaritytypedisplay: string;
+        zscolortype: string; // 颜色 - 两个, 逗号分隔
+        zscolortypedisplay: string;
+        zscrystaltype: string; // 晶型 - 多个,逗号分隔
+        zscrystaltypedisplay: string;
+        zscurrencytype: string; // 货币类型 - 多个, 逗号分隔
+        zscurrencytypedisplay: string;
+        zscuttype: string; // 切工 - 两个, 逗号分隔
+        zscuttypedisplay: string;
+        zsczcolor1type: string; // 彩钻颜色1, 逗号分隔
+        zsczcolor1typedisplay: string;
+        zsczcolor2type: string; // 彩钻颜色2, 逗号分隔
+        zsczcolor2typedisplay: string;
+        zsczcolor3type: string; // 彩钻颜色3, 逗号分隔
+        zsczcolor3typedisplay: string;
+        zsfluorescencetype: string; // 荧光 - 多个, 逗号分隔
+        zsfluorescencetypedisplay: string;
+        zspolishtype: string; // 抛光度 - 两个, 逗号分隔
+        zspolishtypedisplay: string;
+        zsshapetype: string; // 形状 - 多个, 逗号分隔
+        zsshapetypedisplay: string;
+        zssize: string; // 尺寸 - 两个小数, 逗号分隔
+        zsstyletype: string; // 款式 - 多个, 逗号分隔
+        zsstyletypedisplay: string;
+        zssymmetrytype: string; // 对称度 - 两个, 逗号分隔
+        zssymmetrytypedisplay: string;
+        zstabledisplay: string; // 求购信息
+    }
 }

+ 2 - 0
src/types/proto/goods.d.ts

@@ -11,6 +11,8 @@ declare global {
             AddType: number; // 类型1:新增商品2:新增并上架,必填
             PerformanceTemplateID?: number; // 履约模板ID,如果AddType=2时必填
             MarketID: number; // 市场ID必填
+            ClientType: number; // 终端类型
+            OrderSrc: number; // 委托来源
             ClientSerialNo: string; // 客户端流水号
         }
 

+ 33 - 0
src/types/proto/order.d.ts

@@ -51,5 +51,38 @@ declare global {
             Remark?: string; // 备注
             WarehouseIDs?: number[]; // 仓库ID
         }
+
+        /** 钻石卖挂牌接口请求 */
+        interface ZSSellOrderListingReq {
+            Header?: IMessageHead;
+            UserID: number; // 用户ID,必填
+            AccountID: number; // 资金账户ID,必填
+            WRStandardID: number; // 现货商品ID,必填
+            WRFactorTypeID: number; // 仓单要素类型ID,必填
+            OrderQty: number; // 挂牌数量,必填2位小数,为WeigthAvg的整数倍
+            LadingBillID: number; // 提单ID,必填
+            SubNum: number; // 提单子单号,必填
+            PerformanceTemplateID?: number; // 履约计划模板ID
+            TimevalidType: number; // 时间有效类型
+            ValidTime: string; // 有效期限
+            OrderSrc: number; // 委托来源
+            ClientSerialNo: string; // 客户端流水号
+            ClientOrderTime: string; // 客户端委托时间
+            ClientType: number; // 终端类型
+            MarketID: number; // 市场ID,必填
+        }
+
+        /** 钻石卖挂牌接口响应 */
+        interface ZSSellOrderListingRsp {
+            Header?: IMessageHead; // 消息头
+            RetCode?: number; // 返回码
+            RetDesc?: string; // 描述信息
+            UserID: number; // 用户ID
+            AccountID: number; // 资金账户ID
+            WRTradeOrderID: number; // 仓单贸易委托单ID
+            FreezeQty: number; // 冻结数量
+            OrderTime: string; // 接收委托交易的时间
+            ClientSerialNo: string; // 客户端流水号
+        }
     }
 }