This commit is contained in:
2025-09-16 22:11:19 +08:00
parent 562ec4abf9
commit 46c5682960
65 changed files with 1997 additions and 56 deletions

View File

@@ -0,0 +1,212 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_http = require("../../common/http.js");
const common_constants = require("../../common/constants.js");
const common_assets = require("../../common/assets.js");
function todayString() {
const d = /* @__PURE__ */ new Date();
const m = (d.getMonth() + 1).toString().padStart(2, "0");
const day = d.getDate().toString().padStart(2, "0");
return `${d.getFullYear()}-${m}-${day}`;
}
const _sfc_main = {
data() {
return {
biz: "sale",
saleType: "out",
purchaseType: "in",
order: {
orderTime: todayString(),
customerId: null,
supplierId: null,
remark: ""
},
customerName: "",
supplierName: "",
items: [],
activeCategory: "sale_income",
trxAmount: 0,
selectedAccountId: null,
selectedAccountName: ""
};
},
computed: {
totalQuantity() {
return this.items.reduce((s, it) => s + Number(it.quantity || 0), 0);
},
totalAmount() {
return this.items.reduce((s, it) => s + Number(it.quantity || 0) * Number(it.unitPrice || 0), 0);
},
customerLabel() {
return this.customerName || "零售客户";
},
supplierLabel() {
return this.supplierName || "零散供应商";
},
incomeCategories() {
return common_constants.INCOME_CATEGORIES;
},
expenseCategories() {
return common_constants.EXPENSE_CATEGORIES;
},
accountLabel() {
return this.selectedAccountName || "现金";
},
counterpartyLabel() {
return this.customerName || this.supplierName || "—";
}
},
methods: {
switchBiz(type) {
this.biz = type;
},
onDateChange(e) {
this.order.orderTime = e.detail.value;
},
chooseCustomer() {
common_vendor.index.navigateTo({ url: "/pages/customer/select" });
},
chooseSupplier() {
common_vendor.index.navigateTo({ url: "/pages/supplier/select" });
},
chooseProduct() {
common_vendor.index.navigateTo({ url: "/pages/product/select" });
},
chooseAccount() {
common_vendor.index.navigateTo({ url: "/pages/account/select" });
},
chooseCounterparty() {
if (this.biz === "income" || this.biz === "expense") {
common_vendor.index.navigateTo({ url: "/pages/customer/select" });
}
},
recalc() {
this.$forceUpdate();
},
async submit() {
const isSaleOrPurchase = this.biz === "sale" || this.biz === "purchase";
const payload = isSaleOrPurchase ? {
type: this.biz === "sale" ? this.saleType : "purchase." + this.purchaseType,
orderTime: this.order.orderTime,
customerId: this.order.customerId,
supplierId: this.order.supplierId,
items: this.items.map((it) => ({ productId: it.productId, quantity: Number(it.quantity || 0), unitPrice: Number(it.unitPrice || 0) })),
amount: this.totalAmount
} : {
type: this.biz,
category: this.activeCategory,
counterpartyId: this.order.customerId || null,
accountId: this.selectedAccountId || null,
amount: Number(this.trxAmount || 0),
txTime: this.order.orderTime,
remark: this.order.remark
};
try {
const url = isSaleOrPurchase ? "/api/orders" : "/api/other-transactions";
await common_http.post(url, payload);
common_vendor.index.showToast({ title: "已保存", icon: "success" });
setTimeout(() => {
common_vendor.index.navigateBack();
}, 600);
} catch (e) {
common_vendor.index.showToast({ title: e && e.message || "保存失败", icon: "none" });
}
},
saveAndReset() {
this.items = [];
this.trxAmount = 0;
this.order.remark = "";
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
a: $data.biz === "sale" ? 1 : "",
b: common_vendor.o(($event) => $options.switchBiz("sale")),
c: $data.biz === "purchase" ? 1 : "",
d: common_vendor.o(($event) => $options.switchBiz("purchase")),
e: $data.biz === "income" ? 1 : "",
f: common_vendor.o(($event) => $options.switchBiz("income")),
g: $data.biz === "expense" ? 1 : "",
h: common_vendor.o(($event) => $options.switchBiz("expense")),
i: $data.biz === "sale"
}, $data.biz === "sale" ? {
j: $data.saleType === "out" ? 1 : "",
k: common_vendor.o(($event) => $data.saleType = "out"),
l: $data.saleType === "return" ? 1 : "",
m: common_vendor.o(($event) => $data.saleType = "return"),
n: $data.saleType === "collect" ? 1 : "",
o: common_vendor.o(($event) => $data.saleType = "collect")
} : $data.biz === "purchase" ? {
q: $data.purchaseType === "in" ? 1 : "",
r: common_vendor.o(($event) => $data.purchaseType = "in"),
s: $data.purchaseType === "return" ? 1 : "",
t: common_vendor.o(($event) => $data.purchaseType = "return"),
v: $data.purchaseType === "pay" ? 1 : "",
w: common_vendor.o(($event) => $data.purchaseType = "pay")
} : {}, {
p: $data.biz === "purchase",
x: common_vendor.t($data.order.orderTime),
y: $data.order.orderTime,
z: common_vendor.o((...args) => $options.onDateChange && $options.onDateChange(...args)),
A: $data.biz === "sale"
}, $data.biz === "sale" ? {
B: common_vendor.t($options.customerLabel),
C: common_vendor.o((...args) => $options.chooseCustomer && $options.chooseCustomer(...args))
} : $data.biz === "purchase" ? {
E: common_vendor.t($options.supplierLabel),
F: common_vendor.o((...args) => $options.chooseSupplier && $options.chooseSupplier(...args))
} : {}, {
D: $data.biz === "purchase",
G: $data.biz === "sale" || $data.biz === "purchase"
}, $data.biz === "sale" || $data.biz === "purchase" ? {
H: common_vendor.t($options.totalQuantity),
I: common_vendor.t($options.totalAmount.toFixed(2)),
J: common_vendor.o((...args) => $options.chooseProduct && $options.chooseProduct(...args))
} : {
K: common_vendor.f($data.biz === "income" ? $options.incomeCategories : $options.expenseCategories, (c, k0, i0) => {
return {
a: common_vendor.t(c.label),
b: c.key,
c: $data.activeCategory === c.key ? 1 : "",
d: common_vendor.o(($event) => $data.activeCategory = c.key, c.key)
};
}),
L: common_vendor.t($options.counterpartyLabel),
M: common_vendor.o((...args) => $options.chooseCounterparty && $options.chooseCounterparty(...args)),
N: common_vendor.t($options.accountLabel),
O: common_vendor.o((...args) => $options.chooseAccount && $options.chooseAccount(...args)),
P: $data.trxAmount,
Q: common_vendor.o(common_vendor.m(($event) => $data.trxAmount = $event.detail.value, {
number: true
})),
R: $data.order.remark,
S: common_vendor.o(($event) => $data.order.remark = $event.detail.value)
}, {
T: !$data.items.length
}, !$data.items.length ? {
U: common_assets._imports_0$1
} : {
V: common_vendor.f($data.items, (it, idx, i0) => {
return {
a: common_vendor.t(it.productName),
b: common_vendor.o([common_vendor.m(($event) => it.quantity = $event.detail.value, {
number: true
}), ($event) => $options.recalc()], idx),
c: it.quantity,
d: common_vendor.o([common_vendor.m(($event) => it.unitPrice = $event.detail.value, {
number: true
}), ($event) => $options.recalc()], idx),
e: it.unitPrice,
f: common_vendor.t((Number(it.quantity) * Number(it.unitPrice)).toFixed(2)),
g: idx
};
})
}, {
W: common_vendor.o((...args) => $options.saveAndReset && $options.saveAndReset(...args)),
X: common_vendor.o((...args) => $options.submit && $options.submit(...args))
});
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createPage(MiniProgramPage);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/order/create.js.map

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "开单",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="order"><view class="tabs"><text class="{{[a && 'active']}}" bindtap="{{b}}">销售</text><text class="{{[c && 'active']}}" bindtap="{{d}}">进货</text><text class="{{[e && 'active']}}" bindtap="{{f}}">其他收入</text><text class="{{[g && 'active']}}" bindtap="{{h}}">其他支出</text></view><view wx:if="{{i}}" class="subtabs"><button class="{{['subbtn', j && 'active']}}" bindtap="{{k}}">出货</button><button class="{{['subbtn', l && 'active']}}" bindtap="{{m}}">退货</button><button class="{{['subbtn', n && 'active']}}" bindtap="{{o}}">收款</button></view><view wx:elif="{{p}}" class="subtabs"><button class="{{['subbtn', q && 'active']}}" bindtap="{{r}}">进货</button><button class="{{['subbtn', s && 'active']}}" bindtap="{{t}}">退货</button><button class="{{['subbtn', v && 'active']}}" bindtap="{{w}}">付款</button></view><picker mode="date" value="{{y}}" bindchange="{{z}}"><view class="field"><text class="label">时间</text><text class="value">{{x}}</text></view></picker><view wx:if="{{A}}" class="field" bindtap="{{C}}"><text class="label">客户</text><text class="value">{{B}}</text></view><view wx:elif="{{D}}" class="field" bindtap="{{F}}"><text class="label">供应商</text><text class="value">{{E}}</text></view><view wx:if="{{G}}"><view class="summary"><text>选中货品({{H}}</text><text>合计金额:¥ {{I}}</text></view><view class="add" bindtap="{{J}}">+</view></view><view wx:else><view class="chips"><view wx:for="{{K}}" wx:for-item="c" wx:key="b" class="{{['chip', c.c && 'active']}}" bindtap="{{c.d}}">{{c.a}}</view></view><view class="field" bindtap="{{M}}"><text class="label">往来单位</text><text class="value">{{L}}</text></view><view class="field" bindtap="{{O}}"><text class="label">结算账户</text><text class="value">{{N}}</text></view><view class="field"><text class="label">金额</text><input class="value" type="digit" placeholder="0.00" value="{{P}}" bindinput="{{Q}}"/></view><view class="textarea"><block wx:if="{{r0}}"><textarea maxlength="200" placeholder="备注最多输入200个字" value="{{R}}" bindinput="{{S}}"></textarea></block></view></view><view wx:if="{{T}}" class="empty"><image src="{{U}}" mode="widthFix" class="empty-img"></image><text class="empty-text">购物车里空空如也</text><text class="empty-sub">扫描或点击 “+” 选择商品吧</text></view><view wx:else class="list"><view wx:for="{{V}}" wx:for-item="it" wx:key="g" class="row"><view class="col name">{{it.a}}</view><view class="col qty"><input type="number" bindinput="{{it.b}}" value="{{it.c}}"/></view><view class="col price"><input type="number" bindinput="{{it.d}}" value="{{it.e}}"/></view><view class="col amount">¥ {{it.f}}</view></view></view><view class="bottom"><button class="ghost" bindtap="{{W}}">再记一笔</button><button class="primary" bindtap="{{X}}">保存</button></view></view>

View File

@@ -0,0 +1,43 @@
.order { padding-bottom: 140rpx;
}
.tabs { display: flex; justify-content: space-around; padding: 16rpx 24rpx;
}
.tabs text { color: #666;
}
.tabs text.active { color: #333; font-weight: 700;
}
.subtabs { display: flex; gap: 16rpx; padding: 0 24rpx 16rpx;
}
.subbtn { padding: 10rpx 20rpx; border-radius: 999rpx; background: #f4f4f4; color: #666;
}
.subbtn.active { background: #ffe69a; color: #3f320f;
}
.field { display:flex; justify-content: space-between; padding: 22rpx 24rpx; background: #fff; border-bottom: 1rpx solid #eee;
}
.label { color:#666;
}
.value { color:#333;
}
.summary { display:flex; justify-content: space-between; padding: 22rpx 24rpx; color:#333;
}
.add { margin: 24rpx auto; width: 120rpx; height: 120rpx; border-radius: 20rpx; background: #c7eef7; color:#16a1c4; font-size: 72rpx; display:flex; align-items:center; justify-content:center;
}
.empty { display:flex; flex-direction: column; align-items:center; padding: 60rpx 0; color:#888;
}
.empty-img { width: 220rpx; margin-bottom: 20rpx;
}
.empty-text { margin-bottom: 8rpx;
}
.list { background:#fff;
}
.row { display:grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 12rpx; padding: 16rpx 12rpx; align-items:center; border-bottom: 1rpx solid #f3f3f3;
}
.col.name { padding-left: 12rpx;
}
.col.amount { text-align:right; padding-right: 12rpx; color:#333;
}
.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06);
}
.primary { width: 100%; background: linear-gradient(135deg, #FFE69A 0%, #F4CF62 45%, #D7A72E 100%); color:#493c1b; border-radius: 999rpx; padding: 20rpx 0; font-weight:800;
}