diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizDeliveryOrder.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizDeliveryOrder.java index 17026451..daa1854d 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizDeliveryOrder.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/bid/BizDeliveryOrder.java @@ -26,6 +26,9 @@ public class BizDeliveryOrder extends BaseEntity { private List items; private String supplierName; private Integer itemCount; + private String type; + private Long clientQuoteId; + private String clientName; public Long getDoId() { return doId; } public void setDoId(Long doId) { this.doId = doId; } @@ -59,4 +62,10 @@ public class BizDeliveryOrder extends BaseEntity { public void setSupplierName(String supplierName) { this.supplierName = supplierName; } public Integer getItemCount() { return itemCount; } public void setItemCount(Integer itemCount) { this.itemCount = itemCount; } + public String getType() { return type; } + public void setType(String type) { this.type = type; } + public Long getClientQuoteId() { return clientQuoteId; } + public void setClientQuoteId(Long clientQuoteId) { this.clientQuoteId = clientQuoteId; } + public String getClientName() { return clientName; } + public void setClientName(String clientName) { this.clientName = clientName; } } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java index 132eb99d..855de522 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/bid/impl/BizDeliveryOrderServiceImpl.java @@ -37,7 +37,8 @@ public class BizDeliveryOrderServiceImpl implements IBizDeliveryOrderService { @Transactional public int insertBizDeliveryOrder(BizDeliveryOrder record) { if (record.getDoNo() == null || record.getDoNo().isEmpty()) { - record.setDoNo("DO" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); + String prefix = "client".equals(record.getType()) ? "CD" : "DO"; + record.setDoNo(prefix + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); } if (record.getDeliveryStatus() == null || record.getDeliveryStatus().isEmpty()) { record.setDeliveryStatus("pending"); diff --git a/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml b/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml index c694e4e0..ec52700d 100644 --- a/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/bid/BizDeliveryOrderMapper.xml @@ -23,19 +23,27 @@ + + + @@ -48,8 +56,8 @@ - INSERT INTO biz_delivery_order(tenant_id,do_no,rfq_id,quotation_id,supplier_id,total_amount,currency,delivery_date,delay_date,actual_close_date,close_date_set_by,delivery_status,remark,create_by,create_time) - VALUES(#{tenantId},#{doNo},#{rfqId},#{quotationId},#{supplierId},#{totalAmount},#{currency},#{deliveryDate},#{delayDate},#{actualCloseDate},#{closeDateSetBy},#{deliveryStatus},#{remark},#{createBy},NOW()) + INSERT INTO biz_delivery_order(tenant_id,do_no,type,rfq_id,quotation_id,client_quote_id,supplier_id,total_amount,currency,delivery_date,delay_date,actual_close_date,close_date_set_by,delivery_status,remark,create_by,create_time) + VALUES(#{tenantId},#{doNo},#{type},#{rfqId},#{quotationId},#{clientQuoteId},#{supplierId},#{totalAmount},#{currency},#{deliveryDate},#{delayDate},#{actualCloseDate},#{closeDateSetBy},#{deliveryStatus},#{remark},#{createBy},NOW()) @@ -119,8 +127,9 @@ diff --git a/ruoyi-ui/src/assets/styles/index.scss b/ruoyi-ui/src/assets/styles/index.scss index f5278563..f63a1b51 100644 --- a/ruoyi-ui/src/assets/styles/index.scss +++ b/ruoyi-ui/src/assets/styles/index.scss @@ -5,6 +5,11 @@ @import './sidebar.scss'; @import './btn.scss'; +/* ═══════════════════════════════════════════ + 主题系统 — 取消注释即可切换 + ═══════════════════════════════════════════ */ +// @import './theme-jd.scss'; /* 京东红主题 */ + body { height: 100%; -moz-osx-font-smoothing: grayscale; diff --git a/ruoyi-ui/src/assets/styles/theme-jd.scss b/ruoyi-ui/src/assets/styles/theme-jd.scss new file mode 100644 index 00000000..8d50515e --- /dev/null +++ b/ruoyi-ui/src/assets/styles/theme-jd.scss @@ -0,0 +1,83 @@ +/* ═══════════════════════════════════════════ + 京东风格主题 — CSS 变量定义 + 主色:红色 #E2231A + 辅色:白色 + 银灰色 + 用途:替换页面中所有硬编码的颜色值 + ═══════════════════════════════════════════ */ + +:root { + /* ═══ 品牌色(京东红) ═══ */ + --brand-primary: #E2231A; /* 京东红 —— 主按钮、链接、选中态 */ + --brand-primary-hover: #C01623; /* 深红 —— hover、激活 */ + --brand-primary-light: #FFF0F0; /* 浅红背景 —— 选中行、标签浅色背景 */ + + /* ═══ 银灰色(边框、背景、禁用) ═══ */ + --silver-border: #E0E0E0; /* 表格边框、卡片边框 */ + --silver-border-light: #F0F0F0; /* 更浅的边框 */ + --silver-bg: #F5F5F5; /* 页面背景、表头背景、卡片背景 */ + --silver-bg-light: #FAFAFA; /* 交替行背景、悬浮背景 */ + --silver-text: #9E9E9E; /* 禁用文字、placeholder、辅助信息 */ + + /* ═══ 背景色 ═══ */ + --bg-white: #FFFFFF; /* 纯白 — 内容区、卡片、弹窗 */ + --bg-page: #F5F5F5; /* 页面底色 */ + + /* ═══ 文字色 ═══ */ + --text-primary: #333333; /* 主文字 —— 标题、表格数据 */ + --text-secondary: #666666; /* 次要文字 —— 说明、次要信息 */ + --text-muted: #999999; /* 弱化文字 —— 辅助信息 */ + + /* ═══ 金额色 ═══ */ + --color-amount: #E2231A; /* 金额 —— 京东红色 */ + + /* ═══ 状态色 ═══ */ + --color-success: #67C23A; /* 成功绿 */ + --color-warning: #E6A23C; /* 警告橙 */ + --color-danger: #F56C6C; /* 危险红 */ + + /* ═══ 圆角 ═══ */ + --radius-base: 4px; /* 常规圆角 */ + --radius-small: 2px; /* 小圆角 */ + + /* ═══ 阴影 ═══ */ + --shadow-card: 0 1px 4px rgba(0,0,0,0.06); + --shadow-dialog: 0 4px 12px rgba(0,0,0,0.12); + + /* ═══ 间距 ═══ */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 12px; + --space-lg: 16px; + --space-xl: 20px; + + /* ═══ 表格 ═══ */ + --table-header-bg: #F5F5F5; + --table-header-text: #333333; + --table-row-hover: #FFF0F0; /* 浅红悬浮 */ + --table-stripe: #FAFAFA; + --table-border: #E0E0E0; + + /* ═══ 搜索栏 / 卡片 ═══ */ + --card-bg: #FFFFFF; + --card-border: #E0E0E0; +} + +/* ═══ 部分 Element UI 覆盖 ═══ */ +.el-button--primary { + background-color: var(--brand-primary) !important; + border-color: var(--brand-primary) !important; +} +.el-button--primary:hover, +.el-button--primary:focus { + background-color: var(--brand-primary-hover) !important; + border-color: var(--brand-primary-hover) !important; +} + +.el-table thead th { + background-color: var(--table-header-bg) !important; + color: var(--table-header-text) !important; +} + +.el-table__body .el-table__row:hover td { + background-color: var(--table-row-hover) !important; +} diff --git a/ruoyi-ui/src/router/index.js b/ruoyi-ui/src/router/index.js index d72bdff9..84480f8c 100644 --- a/ruoyi-ui/src/router/index.js +++ b/ruoyi-ui/src/router/index.js @@ -248,6 +248,26 @@ export const dynamicRoutes = [ }] }, + // ── 甲方履约 ── + { + path: '/bid/clientDelivery/pending', + component: Layout, + permissions: ['bid:clientdelivery:pending'], + children: [{ path: '', component: () => import('@/views/bid/clientDelivery/pending'), name: 'ClientDeliveryPending', meta: { title: '甲方待发', activeMenu: '/bid/clientDelivery' } }] + }, + { + path: '/bid/clientDelivery/transit', + component: Layout, + permissions: ['bid:clientdelivery:transit'], + children: [{ path: '', component: () => import('@/views/bid/clientDelivery/transit'), name: 'ClientDeliveryTransit', meta: { title: '甲方在途', activeMenu: '/bid/clientDelivery' } }] + }, + { + path: '/bid/clientDelivery/signed', + component: Layout, + permissions: ['bid:clientdelivery:signed'], + children: [{ path: '', component: () => import('@/views/bid/clientDelivery/signed'), name: 'ClientDeliverySigned', meta: { title: '甲方签收', activeMenu: '/bid/clientDelivery' } }] + }, + { path: '/bid/comparison/detail', component: Layout, diff --git a/ruoyi-ui/src/views/bid/clientDelivery/pending.vue b/ruoyi-ui/src/views/bid/clientDelivery/pending.vue new file mode 100644 index 00000000..ddccab84 --- /dev/null +++ b/ruoyi-ui/src/views/bid/clientDelivery/pending.vue @@ -0,0 +1,87 @@ + + + diff --git a/ruoyi-ui/src/views/bid/clientDelivery/signed.vue b/ruoyi-ui/src/views/bid/clientDelivery/signed.vue new file mode 100644 index 00000000..1c1c0fc1 --- /dev/null +++ b/ruoyi-ui/src/views/bid/clientDelivery/signed.vue @@ -0,0 +1,80 @@ + + + diff --git a/ruoyi-ui/src/views/bid/clientDelivery/transit.vue b/ruoyi-ui/src/views/bid/clientDelivery/transit.vue new file mode 100644 index 00000000..d83a74d3 --- /dev/null +++ b/ruoyi-ui/src/views/bid/clientDelivery/transit.vue @@ -0,0 +1,79 @@ + + + diff --git a/ruoyi-ui/src/views/bid/clientquote/index.vue b/ruoyi-ui/src/views/bid/clientquote/index.vue index 540cf5d5..b44d9aef 100644 --- a/ruoyi-ui/src/views/bid/clientquote/index.vue +++ b/ruoyi-ui/src/views/bid/clientquote/index.vue @@ -88,6 +88,7 @@ 编辑 快速新建 生成RFQ + 生成发货单 删除 @@ -260,6 +261,7 @@ import { listClientQuote, getClientQuote, addClientQuote, updateClientQuote, del getClientQuoteStatistics, quickCreateFromQuote } from "@/api/bid/clientquote"; import { listRfq, createRfqFromQuote } from "@/api/bid/rfq"; import { listMaterial } from "@/api/bid/material"; +import { addDelivery } from "@/api/bid/delivery"; export default { name: "ClientQuote", @@ -310,6 +312,14 @@ export default { handleCreateRfq(row) { this.$modal.confirm("确认基于【" + row.quoteNo + "】生成RFQ?").then(() => createRfqFromQuote(row.quoteId)).then(r => { this.detailOpen = false; this.$modal.msgSuccess("RFQ已创建"); this.$router.push({ path: '/bid/rfq/detail', query: { rfqId: r.data.rfqId, rfqNo: r.data.rfqNo, edit: '1' } }); }).catch(() => {}); }, + handleCreateDelivery(row) { + this.$modal.confirm("确认基于【" + row.quoteNo + "】生成甲方发货单?").then(() => getClientQuote(row.quoteId)).then(r => { + const q = r.data; if (!q || !q.items || !q.items.length) throw new Error("报价单无明细,无法生成发货单"); + return addDelivery({ type: "client", clientQuoteId: q.quoteId, totalAmount: q.totalAmount, deliveryStatus: "pending", + items: q.items.map(it => ({ materialId: it.materialId, materialName: it.materialName, spec: it.spec, unit: it.unit, quantity: it.quantity, unitPrice: it.unitPrice, totalPrice: (it.quantity||0)*(it.unitPrice||0) })) + }); + }).then(() => { this.$modal.msgSuccess("甲方发货单已生成"); this.getList() }).catch(e => { if (e.message) this.$modal.msgError(e.message) }); + }, handleDelete(row) { this.$modal.confirm("确认删除【" + row.quoteNo + "】?").then(() => delClientQuote(row.quoteId)).then(() => { this.$modal.msgSuccess("删除成功"); this.getList(); this.getStats(); }); }, loadRfqForDetail(quoteId) { this.detailRfqLoading = true; listRfq({ clientQuoteId: quoteId, pageSize: 50 }).then(r => { this.detailRfqList = r.rows || []; this.detailRfqLoading = false; }).catch(() => { this.detailRfqLoading = false; }); }, viewRfqDetail(rfq) { this.detailOpen = false; this.$router.push({ path: '/bid/rfq/detail', query: { rfqId: rfq.rfqId } }); }, diff --git a/ruoyi-ui/src/views/bid/material/index.vue b/ruoyi-ui/src/views/bid/material/index.vue index d4f32e9e..014881a4 100644 --- a/ruoyi-ui/src/views/bid/material/index.vue +++ b/ruoyi-ui/src/views/bid/material/index.vue @@ -77,21 +77,26 @@ - - - - - - + + - - + + - - - + + + + + + + + + + + + @@ -339,16 +344,19 @@ export default { .catch(() => { this.recordLoading = false }) }, recordStatusType(s) { return { pending: "warning", transit: "primary", history: "success" }[s] || "" }, - recordStatusLabel(s) { return { pending: "待发", transit: "在途", history: "已收货" }[s] || s || "-" } + recordStatusLabel(s) { return { pending: "待发", transit: "在途", history: "已收货" }[s] || s || "-" }, + // 兼容 snake_case 和 camelCase + fmtRow(r) { return r } } };