5077 lines
180 KiB
JavaScript
5077 lines
180 KiB
JavaScript
if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
|
||
Promise.prototype.finally = function(callback) {
|
||
const promise = this.constructor;
|
||
return this.then(
|
||
(value) => promise.resolve(callback()).then(() => value),
|
||
(reason) => promise.resolve(callback()).then(() => {
|
||
throw reason;
|
||
})
|
||
);
|
||
};
|
||
}
|
||
;
|
||
if (typeof uni !== "undefined" && uni && uni.requireGlobal) {
|
||
const global = uni.requireGlobal();
|
||
ArrayBuffer = global.ArrayBuffer;
|
||
Int8Array = global.Int8Array;
|
||
Uint8Array = global.Uint8Array;
|
||
Uint8ClampedArray = global.Uint8ClampedArray;
|
||
Int16Array = global.Int16Array;
|
||
Uint16Array = global.Uint16Array;
|
||
Int32Array = global.Int32Array;
|
||
Uint32Array = global.Uint32Array;
|
||
Float32Array = global.Float32Array;
|
||
Float64Array = global.Float64Array;
|
||
BigInt64Array = global.BigInt64Array;
|
||
BigUint64Array = global.BigUint64Array;
|
||
}
|
||
;
|
||
if (uni.restoreGlobal) {
|
||
uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval);
|
||
}
|
||
(function(vue) {
|
||
"use strict";
|
||
function formatAppLog(type, filename, ...args) {
|
||
if (uni.__log__) {
|
||
uni.__log__(type, filename, ...args);
|
||
} else {
|
||
console[type].apply(console, [...args, filename]);
|
||
}
|
||
}
|
||
var define_process_env_default = {};
|
||
const envBaseUrl = typeof process !== "undefined" && define_process_env_default && (define_process_env_default.VITE_APP_API_BASE_URL || define_process_env_default.API_BASE_URL) || "";
|
||
const storageBaseUrl = typeof uni !== "undefined" ? uni.getStorageSync("API_BASE_URL") || "" : "";
|
||
const fallbackBaseUrl = "http://127.0.0.1:8080";
|
||
const API_BASE_URL = (envBaseUrl || storageBaseUrl || fallbackBaseUrl).replace(/\/$/, "");
|
||
const candidateBases = [envBaseUrl, storageBaseUrl, fallbackBaseUrl, "http://127.0.0.1:8080", "http://localhost:8080"];
|
||
const API_BASE_URL_CANDIDATES = Array.from(new Set(candidateBases.filter(Boolean))).map((u) => String(u).replace(/\/$/, ""));
|
||
const envShopId = typeof process !== "undefined" && define_process_env_default && (define_process_env_default.VITE_APP_SHOP_ID || define_process_env_default.SHOP_ID) || "";
|
||
const storageShopId = typeof uni !== "undefined" ? uni.getStorageSync("SHOP_ID") || "" : "";
|
||
const SHOP_ID = Number(envShopId || storageShopId || 1);
|
||
const envEnableDefaultUser = typeof process !== "undefined" && define_process_env_default && (define_process_env_default.VITE_APP_ENABLE_DEFAULT_USER || define_process_env_default.ENABLE_DEFAULT_USER) || "";
|
||
const storageEnableDefaultUser = typeof uni !== "undefined" ? uni.getStorageSync("ENABLE_DEFAULT_USER") || "" : "";
|
||
const ENABLE_DEFAULT_USER = String(envEnableDefaultUser || storageEnableDefaultUser || "true").toLowerCase() === "true";
|
||
const envDefaultUserId = typeof process !== "undefined" && define_process_env_default && (define_process_env_default.VITE_APP_DEFAULT_USER_ID || define_process_env_default.DEFAULT_USER_ID) || "";
|
||
const storageDefaultUserId = typeof uni !== "undefined" ? uni.getStorageSync("DEFAULT_USER_ID") || "" : "";
|
||
const DEFAULT_USER_ID = Number(envDefaultUserId || storageDefaultUserId || 2);
|
||
function buildUrl(path) {
|
||
if (!path)
|
||
return API_BASE_URL;
|
||
if (path.startsWith("http"))
|
||
return path;
|
||
return API_BASE_URL + (path.startsWith("/") ? path : "/" + path);
|
||
}
|
||
function requestWithFallback(options, candidates, idx, resolve, reject) {
|
||
const base = candidates[idx] || API_BASE_URL;
|
||
const url = options.url.replace(/^https?:\/\/[^/]+/, base);
|
||
uni.request({ ...options, url, success: (res) => {
|
||
const { statusCode, data } = res;
|
||
if (statusCode >= 200 && statusCode < 300)
|
||
return resolve(data);
|
||
const msg = data && (data.message || data.error || data.msg) || "HTTP " + statusCode;
|
||
uni.showToast({ title: msg, icon: "none" });
|
||
if (idx + 1 < candidates.length)
|
||
return requestWithFallback(options, candidates, idx + 1, resolve, reject);
|
||
reject(new Error(msg));
|
||
}, fail: (err) => {
|
||
if (idx + 1 < candidates.length)
|
||
return requestWithFallback(options, candidates, idx + 1, resolve, reject);
|
||
reject(err);
|
||
} });
|
||
}
|
||
function get(path, params = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const headers = { "X-Shop-Id": SHOP_ID };
|
||
if (ENABLE_DEFAULT_USER && DEFAULT_USER_ID)
|
||
headers["X-User-Id"] = DEFAULT_USER_ID;
|
||
const options = { url: buildUrl(path), method: "GET", data: params, header: headers };
|
||
requestWithFallback(options, API_BASE_URL_CANDIDATES, 0, resolve, reject);
|
||
});
|
||
}
|
||
function post(path, body = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const headers = { "Content-Type": "application/json", "X-Shop-Id": SHOP_ID };
|
||
if (ENABLE_DEFAULT_USER && DEFAULT_USER_ID)
|
||
headers["X-User-Id"] = DEFAULT_USER_ID;
|
||
const options = { url: buildUrl(path), method: "POST", data: body, header: headers };
|
||
requestWithFallback(options, API_BASE_URL_CANDIDATES, 0, resolve, reject);
|
||
});
|
||
}
|
||
function put(path, body = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const headers = { "Content-Type": "application/json", "X-Shop-Id": SHOP_ID };
|
||
if (ENABLE_DEFAULT_USER && DEFAULT_USER_ID)
|
||
headers["X-User-Id"] = DEFAULT_USER_ID;
|
||
const options = { url: buildUrl(path), method: "PUT", data: body, header: headers };
|
||
requestWithFallback(options, API_BASE_URL_CANDIDATES, 0, resolve, reject);
|
||
});
|
||
}
|
||
function del(path, body = {}) {
|
||
return new Promise((resolve, reject) => {
|
||
const headers = { "Content-Type": "application/json", "X-Shop-Id": SHOP_ID };
|
||
if (ENABLE_DEFAULT_USER && DEFAULT_USER_ID)
|
||
headers["X-User-Id"] = DEFAULT_USER_ID;
|
||
const options = { url: buildUrl(path), method: "DELETE", data: body, header: headers };
|
||
requestWithFallback(options, API_BASE_URL_CANDIDATES, 0, resolve, reject);
|
||
});
|
||
}
|
||
function uploadWithFallback(options, candidates, idx, resolve, reject) {
|
||
const base = candidates[idx] || API_BASE_URL;
|
||
const url = options.url.replace(/^https?:\/\/[^/]+/, base);
|
||
const uploadOptions = { ...options, url };
|
||
uni.uploadFile({
|
||
...uploadOptions,
|
||
success: (res) => {
|
||
const statusCode = res.statusCode || 0;
|
||
if (statusCode >= 200 && statusCode < 300) {
|
||
try {
|
||
const data = typeof res.data === "string" ? JSON.parse(res.data) : res.data;
|
||
return resolve(data);
|
||
} catch (e) {
|
||
return resolve(res.data);
|
||
}
|
||
}
|
||
if (idx + 1 < candidates.length)
|
||
return uploadWithFallback(options, candidates, idx + 1, resolve, reject);
|
||
reject(new Error("HTTP " + statusCode));
|
||
},
|
||
fail: (err) => {
|
||
if (idx + 1 < candidates.length)
|
||
return uploadWithFallback(options, candidates, idx + 1, resolve, reject);
|
||
reject(err);
|
||
}
|
||
});
|
||
}
|
||
function upload(path, filePath, formData = {}, name = "file") {
|
||
return new Promise((resolve, reject) => {
|
||
const header = { "X-Shop-Id": SHOP_ID };
|
||
if (ENABLE_DEFAULT_USER && DEFAULT_USER_ID)
|
||
header["X-User-Id"] = DEFAULT_USER_ID;
|
||
const options = { url: buildUrl(path), filePath, name, formData, header };
|
||
uploadWithFallback(options, API_BASE_URL_CANDIDATES, 0, resolve, reject);
|
||
});
|
||
}
|
||
const INCOME_CATEGORIES = [
|
||
{ key: "sale_income", label: "销售收入" },
|
||
{ key: "operation_income", label: "经营所得" },
|
||
{ key: "interest_income", label: "利息收入" },
|
||
{ key: "investment_income", label: "投资收入" },
|
||
{ key: "other_income", label: "其它收入" }
|
||
];
|
||
const EXPENSE_CATEGORIES = [
|
||
{ key: "operation_expense", label: "经营支出" },
|
||
{ key: "office_supplies", label: "办公用品" },
|
||
{ key: "rent", label: "房租" },
|
||
{ key: "interest_expense", label: "利息支出" },
|
||
{ key: "other_expense", label: "其它支出" }
|
||
];
|
||
const ROUTES = {
|
||
home: "/pages/index/index",
|
||
productList: "/pages/product/list",
|
||
productForm: "/pages/product/form",
|
||
productSelect: "/pages/product/select",
|
||
productSettings: "/pages/product/settings",
|
||
orderCreate: "/pages/order/create",
|
||
detail: "/pages/detail/index",
|
||
my: "/pages/my/index",
|
||
myAbout: "/pages/my/about",
|
||
report: "/pages/report/index",
|
||
customerSelect: "/pages/customer/select",
|
||
supplierSelect: "/pages/supplier/select",
|
||
accountSelect: "/pages/account/select"
|
||
};
|
||
const _imports_0$1 = "/static/metal-bg.jpg";
|
||
const _export_sfc = (sfc, props) => {
|
||
const target = sfc.__vccOpts || sfc;
|
||
for (const [key, val] of props) {
|
||
target[key] = val;
|
||
}
|
||
return target;
|
||
};
|
||
const _sfc_main$l = {
|
||
data() {
|
||
return {
|
||
kpi: { todaySales: "0.00", monthSales: "0.00", monthProfit: "0.00", stockCount: "0" },
|
||
activeTab: "home",
|
||
notices: [],
|
||
loadingNotices: false,
|
||
noticeError: "",
|
||
features: [
|
||
{ key: "product", title: "货品", img: "/static/icons/product.png", emoji: "📦" },
|
||
{ key: "customer", title: "客户", img: "/static/icons/customer.png", emoji: "👥" },
|
||
{ key: "sale", title: "销售", img: "/static/icons/sale.png", emoji: "💰" },
|
||
{ key: "account", title: "账户", img: "/static/icons/account.png", emoji: "💳" },
|
||
{ key: "supplier", title: "供应商", img: "/static/icons/supplier.png", emoji: "🚚" },
|
||
{ key: "purchase", title: "进货", img: "/static/icons/purchase.png", emoji: "🛒" },
|
||
{ key: "otherPay", title: "其他支出", img: "/static/icons/other-pay.png", emoji: "💸" },
|
||
{ key: "vip", title: "VIP会员", img: "/static/icons/vip.png", emoji: "👑" },
|
||
{ key: "report", title: "报表", img: "/static/icons/report.png", emoji: "📊" },
|
||
{ key: "more", title: "更多", img: "/static/icons/more.png", emoji: "⋯" }
|
||
]
|
||
};
|
||
},
|
||
onLoad() {
|
||
this.fetchMetrics();
|
||
this.fetchNotices();
|
||
},
|
||
methods: {
|
||
async fetchMetrics() {
|
||
try {
|
||
const d = await get("/api/dashboard/overview");
|
||
const toNum = (v) => typeof v === "number" ? v : Number(v || 0);
|
||
this.kpi = {
|
||
...this.kpi,
|
||
todaySales: toNum(d && d.todaySalesAmount).toFixed(2),
|
||
monthSales: toNum(d && d.monthSalesAmount).toFixed(2),
|
||
monthProfit: toNum(d && d.monthGrossProfit).toFixed(2),
|
||
stockCount: String((d && d.stockTotalQuantity) != null ? d.stockTotalQuantity : 0)
|
||
};
|
||
} catch (e) {
|
||
}
|
||
},
|
||
async fetchNotices() {
|
||
this.loadingNotices = true;
|
||
this.noticeError = "";
|
||
try {
|
||
const list = await get("/api/notices");
|
||
this.notices = Array.isArray(list) ? list.map((n) => ({
|
||
text: n.content || n.title || "",
|
||
tag: n.tag || ""
|
||
})) : [];
|
||
} catch (e) {
|
||
this.noticeError = e && e.message || "公告加载失败";
|
||
} finally {
|
||
this.loadingNotices = false;
|
||
}
|
||
},
|
||
onFeatureTap(item) {
|
||
if (item.key === "product") {
|
||
uni.switchTab({ url: "/pages/product/list" });
|
||
return;
|
||
}
|
||
if (item.key === "sale") {
|
||
try {
|
||
uni.setStorageSync("ORDER_DEFAULT_PARAMS", { biz: "sale", type: "out" });
|
||
} catch (e) {
|
||
}
|
||
uni.switchTab({ url: "/pages/order/create" });
|
||
return;
|
||
}
|
||
if (item.key === "customer") {
|
||
uni.navigateTo({ url: "/pages/customer/select" });
|
||
return;
|
||
}
|
||
if (item.key === "account") {
|
||
uni.navigateTo({ url: "/pages/account/select" });
|
||
return;
|
||
}
|
||
if (item.key === "supplier") {
|
||
uni.navigateTo({ url: "/pages/supplier/select" });
|
||
return;
|
||
}
|
||
if (item.key === "purchase") {
|
||
try {
|
||
uni.setStorageSync("ORDER_DEFAULT_PARAMS", { biz: "purchase", type: "in" });
|
||
} catch (e) {
|
||
}
|
||
uni.switchTab({ url: "/pages/order/create" });
|
||
return;
|
||
}
|
||
if (item.key === "report") {
|
||
uni.navigateTo({ url: ROUTES.report });
|
||
return;
|
||
}
|
||
if (item.key === "otherPay") {
|
||
try {
|
||
uni.setStorageSync("ORDER_DEFAULT_PARAMS", { biz: "expense" });
|
||
} catch (e) {
|
||
}
|
||
uni.switchTab({ url: "/pages/order/create" });
|
||
return;
|
||
}
|
||
uni.showToast({ title: item.title + "(开发中)", icon: "none" });
|
||
},
|
||
goProduct() {
|
||
uni.switchTab({ url: "/pages/product/list" });
|
||
},
|
||
onCreateOrder() {
|
||
uni.switchTab({ url: "/pages/order/create" });
|
||
},
|
||
goDetail() {
|
||
try {
|
||
formatAppLog("log", "at pages/index/index.vue:177", "[index] goDetail → /pages/detail/index");
|
||
} catch (e) {
|
||
}
|
||
uni.switchTab({ url: "/pages/detail/index" });
|
||
},
|
||
goMe() {
|
||
uni.switchTab({ url: "/pages/my/index" });
|
||
},
|
||
onNoticeTap(n) {
|
||
uni.showModal({
|
||
title: "广告",
|
||
content: n && (n.text || n.title || n.content) || "",
|
||
showCancel: false
|
||
});
|
||
},
|
||
onIconError(item) {
|
||
item.img = "";
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "home" }, [
|
||
vue.createElementVNode("image", {
|
||
class: "home-bg",
|
||
src: _imports_0$1,
|
||
mode: "aspectFill"
|
||
}),
|
||
vue.createCommentVNode(" 顶部统计卡片 "),
|
||
vue.createElementVNode("view", { class: "hero" }, [
|
||
vue.createElementVNode("view", { class: "hero-top" }, [
|
||
vue.createElementVNode("text", { class: "brand" }, "五金配件管家"),
|
||
vue.createElementVNode("view", { class: "cta" }, [
|
||
vue.createElementVNode("text", { class: "cta-text" }, "咨询")
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "kpi" }, [
|
||
vue.createElementVNode("view", { class: "kpi-item" }, [
|
||
vue.createElementVNode("text", { class: "kpi-label" }, "今日销售额"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "kpi-value" },
|
||
vue.toDisplayString($data.kpi.todaySales),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "kpi-item" }, [
|
||
vue.createElementVNode("text", { class: "kpi-label" }, "本月销售额"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "kpi-value" },
|
||
vue.toDisplayString($data.kpi.monthSales),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "kpi-item" }, [
|
||
vue.createElementVNode("text", { class: "kpi-label" }, "本月利润"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "kpi-value" },
|
||
vue.toDisplayString($data.kpi.monthProfit),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "kpi-item" }, [
|
||
vue.createElementVNode("text", { class: "kpi-label" }, "库存商品数量"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "kpi-value" },
|
||
vue.toDisplayString($data.kpi.stockCount),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
])
|
||
]),
|
||
vue.createCommentVNode(" 广告栏:自动轮播,可点击查看详情 "),
|
||
vue.createElementVNode("view", { class: "notice" }, [
|
||
vue.createElementVNode("view", { class: "notice-left" }, "广告"),
|
||
$data.loadingNotices ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "notice-swiper",
|
||
style: { "display": "flex", "align-items": "center", "color": "#6b5a2a" }
|
||
}, "加载中...")) : $data.noticeError ? (vue.openBlock(), vue.createElementBlock(
|
||
"view",
|
||
{
|
||
key: 1,
|
||
class: "notice-swiper",
|
||
style: { "display": "flex", "align-items": "center", "color": "#dd524d" }
|
||
},
|
||
vue.toDisplayString($data.noticeError),
|
||
1
|
||
/* TEXT */
|
||
)) : !$data.notices.length ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 2,
|
||
class: "notice-swiper",
|
||
style: { "display": "flex", "align-items": "center", "color": "#6b5a2a" }
|
||
}, "暂无公告")) : (vue.openBlock(), vue.createElementBlock("swiper", {
|
||
key: 3,
|
||
class: "notice-swiper",
|
||
circular: "",
|
||
autoplay: "",
|
||
interval: "4000",
|
||
duration: "400",
|
||
vertical: ""
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.notices, (n, idx) => {
|
||
return vue.openBlock(), vue.createElementBlock("swiper-item", { key: idx }, [
|
||
vue.createElementVNode("view", {
|
||
class: "notice-item",
|
||
onClick: ($event) => $options.onNoticeTap(n)
|
||
}, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "notice-text" },
|
||
vue.toDisplayString(n.text),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
n.tag ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "notice-tag"
|
||
},
|
||
vue.toDisplayString(n.tag),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.createCommentVNode("v-if", true)
|
||
], 8, ["onClick"])
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]))
|
||
]),
|
||
vue.createCommentVNode(" 分割标题:产品与功能 "),
|
||
vue.createElementVNode("view", { class: "section-title" }, [
|
||
vue.createElementVNode("text", { class: "section-text" }, "常用功能")
|
||
]),
|
||
vue.createCommentVNode(" 功能九宫格(玻璃容器 + 圆角方形图标) "),
|
||
vue.createElementVNode("view", { class: "grid-wrap" }, [
|
||
vue.createElementVNode("view", { class: "grid" }, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.features, (item) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "grid-item",
|
||
key: item.key,
|
||
onClick: ($event) => $options.onFeatureTap(item)
|
||
}, [
|
||
vue.createElementVNode("view", { class: "icon icon-squircle" }, [
|
||
item.img ? (vue.openBlock(), vue.createElementBlock("image", {
|
||
key: 0,
|
||
src: item.img,
|
||
class: "icon-img",
|
||
mode: "aspectFit",
|
||
onError: ($event) => $options.onIconError(item)
|
||
}, null, 40, ["src", "onError"])) : item.emoji ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 1,
|
||
class: "icon-emoji"
|
||
},
|
||
vue.toDisplayString(item.emoji),
|
||
1
|
||
/* TEXT */
|
||
)) : (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 2,
|
||
class: "icon-placeholder"
|
||
}))
|
||
]),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "grid-chip" },
|
||
vue.toDisplayString(item.title),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
]),
|
||
vue.createCommentVNode(" 底部操作条改为原生 tabBar,移除自定义栏 ")
|
||
]);
|
||
}
|
||
const PagesIndexIndex = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$k], ["__file", "D:/wx/PartsInquiry/frontend/pages/index/index.vue"]]);
|
||
const _imports_0 = "/static/logo.png";
|
||
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$k = {
|
||
data() {
|
||
return {
|
||
biz: "sale",
|
||
saleType: "out",
|
||
purchaseType: "in",
|
||
order: {
|
||
orderTime: todayString(),
|
||
customerId: null,
|
||
supplierId: null,
|
||
remark: ""
|
||
},
|
||
customerName: "",
|
||
customerPriceLevel: "零售价",
|
||
_lastCustomerId: null,
|
||
_priceCache: {},
|
||
supplierName: "",
|
||
items: [],
|
||
activeCategory: "sale_income",
|
||
counterpartyType: "customer",
|
||
trxAmount: 0,
|
||
selectedAccountId: null,
|
||
selectedAccountName: "",
|
||
// 收款/付款输入
|
||
payments: { cash: 0, bank: 0, wechat: 0 },
|
||
showMore: false
|
||
};
|
||
},
|
||
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 this._incomeCategories || INCOME_CATEGORIES;
|
||
},
|
||
expenseCategories() {
|
||
return this._expenseCategories || EXPENSE_CATEGORIES;
|
||
},
|
||
accountLabel() {
|
||
return this.selectedAccountName || "现金";
|
||
},
|
||
counterpartyLabel() {
|
||
return this.counterpartyType === "customer" ? this.customerName || "—" : this.supplierName || "—";
|
||
},
|
||
// 收款/付款合计
|
||
payTotal() {
|
||
const p = this.payments || { cash: 0, bank: 0, wechat: 0 };
|
||
return Number(p.cash || 0) + Number(p.bank || 0) + Number(p.wechat || 0);
|
||
}
|
||
},
|
||
onLoad(query) {
|
||
try {
|
||
const preset = uni.getStorageSync("ORDER_DEFAULT_PARAMS") || {};
|
||
const biz = query && query.biz || preset.biz;
|
||
const type = query && query.type || preset.type;
|
||
if (biz === "sale" || biz === "purchase" || biz === "income" || biz === "expense") {
|
||
this.biz = biz;
|
||
}
|
||
if (this.biz === "sale" && (type === "out" || type === "return" || type === "collect")) {
|
||
this.saleType = type;
|
||
}
|
||
if (this.biz === "purchase" && (type === "in" || type === "return" || type === "pay")) {
|
||
this.purchaseType = type;
|
||
}
|
||
try {
|
||
uni.removeStorageSync("ORDER_DEFAULT_PARAMS");
|
||
} catch (_) {
|
||
}
|
||
} catch (e) {
|
||
}
|
||
this.fetchCategories();
|
||
},
|
||
onShow() {
|
||
if (this.biz === "sale") {
|
||
if (this.order.customerId && this.order.customerId !== this._lastCustomerId) {
|
||
this.loadCustomerLevel(this.order.customerId).then(() => {
|
||
this._lastCustomerId = this.order.customerId;
|
||
for (const it of this.items) {
|
||
if (it && (it._autoPrice || !it.unitPrice))
|
||
this.autoPriceItem(it);
|
||
}
|
||
});
|
||
}
|
||
for (const it of this.items) {
|
||
if (it && !it.unitPrice)
|
||
this.autoPriceItem(it);
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
async fetchCategories() {
|
||
try {
|
||
const res = await get("/api/finance/categories");
|
||
if (res && Array.isArray(res.incomeCategories))
|
||
this._incomeCategories = res.incomeCategories;
|
||
if (res && Array.isArray(res.expenseCategories))
|
||
this._expenseCategories = res.expenseCategories;
|
||
this.ensureActiveCategory();
|
||
} catch (_) {
|
||
this.ensureActiveCategory();
|
||
}
|
||
},
|
||
ensureActiveCategory() {
|
||
const list = this.biz === "income" ? this.incomeCategories || [] : this.expenseCategories || [];
|
||
if (!list.length)
|
||
return;
|
||
const exists = list.some((it) => it && it.key === this.activeCategory);
|
||
if (!exists)
|
||
this.activeCategory = list[0].key;
|
||
},
|
||
async loadCustomerLevel(customerId) {
|
||
try {
|
||
const d = await get(`/api/customers/${customerId}`);
|
||
this.customerPriceLevel = d && d.priceLevel ? d.priceLevel : "零售价";
|
||
} catch (e) {
|
||
this.customerPriceLevel = "零售价";
|
||
}
|
||
},
|
||
priceFieldForLevel() {
|
||
const lvl = this.customerPriceLevel || "零售价";
|
||
if (lvl === "批发价")
|
||
return "wholesalePrice";
|
||
if (lvl === "大单报价")
|
||
return "bigClientPrice";
|
||
return "retailPrice";
|
||
},
|
||
async autoPriceItem(it) {
|
||
if (this.biz !== "sale")
|
||
return;
|
||
if (!it || !it.productId)
|
||
return;
|
||
const pid = it.productId;
|
||
let detail = this._priceCache[pid];
|
||
if (!detail) {
|
||
try {
|
||
detail = await get(`/api/products/${pid}`);
|
||
this._priceCache[pid] = detail;
|
||
} catch (e) {
|
||
return;
|
||
}
|
||
}
|
||
const field = this.priceFieldForLevel();
|
||
let price = Number(detail && detail[field] != null ? detail[field] : 0);
|
||
if (!price && field !== "retailPrice") {
|
||
price = Number(detail && detail.retailPrice != null ? detail.retailPrice : 0);
|
||
}
|
||
it.unitPrice = price;
|
||
it._autoPrice = true;
|
||
this.recalc();
|
||
},
|
||
onPriceInput(it) {
|
||
if (it) {
|
||
it._autoPrice = false;
|
||
this.recalc();
|
||
}
|
||
},
|
||
switchBiz(type) {
|
||
this.biz = type;
|
||
this.ensureActiveCategory();
|
||
},
|
||
onDateChange(e) {
|
||
this.order.orderTime = e.detail.value;
|
||
},
|
||
chooseCustomer() {
|
||
uni.navigateTo({ url: "/pages/customer/select" });
|
||
},
|
||
chooseSupplier() {
|
||
uni.navigateTo({ url: "/pages/supplier/select" });
|
||
},
|
||
chooseProduct() {
|
||
uni.navigateTo({ url: "/pages/product/select" });
|
||
},
|
||
chooseAccount() {
|
||
uni.navigateTo({ url: "/pages/account/select?mode=pick" });
|
||
},
|
||
chooseCounterparty() {
|
||
if (!(this.biz === "income" || this.biz === "expense"))
|
||
return;
|
||
if (this.counterpartyType === "customer") {
|
||
uni.navigateTo({ url: "/pages/customer/select" });
|
||
} else {
|
||
uni.navigateTo({ url: "/pages/supplier/select" });
|
||
}
|
||
},
|
||
setCounterparty(t) {
|
||
this.counterpartyType = t;
|
||
this.ensureActiveCategory();
|
||
},
|
||
recalc() {
|
||
this.$forceUpdate();
|
||
},
|
||
recalcPay() {
|
||
this.$forceUpdate();
|
||
},
|
||
async submit() {
|
||
const isSaleOrPurchase = this.biz === "sale" || this.biz === "purchase";
|
||
const isCollectOrPay = this.biz === "sale" && this.saleType === "collect" || this.biz === "purchase" && this.purchaseType === "pay";
|
||
const saleTypeValue = this.biz === "sale" ? "sale." + this.saleType : "purchase." + this.purchaseType;
|
||
if (isSaleOrPurchase && !isCollectOrPay) {
|
||
if (!this.items.length) {
|
||
uni.showToast({ title: "请先选择商品", icon: "none" });
|
||
return;
|
||
}
|
||
const invalid = this.items.find((it) => !it.productId || Number(it.quantity || 0) <= 0);
|
||
if (invalid) {
|
||
uni.showToast({ title: "数量需大于0", icon: "none" });
|
||
return;
|
||
}
|
||
}
|
||
const payload = isSaleOrPurchase ? isCollectOrPay ? [
|
||
{ method: "cash", amount: Number(this.payments.cash || 0) },
|
||
{ method: "bank", amount: Number(this.payments.bank || 0) },
|
||
{ method: "wechat", amount: Number(this.payments.wechat || 0) }
|
||
].filter((p) => p.amount > 0) : {
|
||
type: saleTypeValue,
|
||
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,
|
||
counterpartyType: this.counterpartyType,
|
||
counterpartyId: this.counterpartyType === "customer" ? this.order.customerId || null : this.order.supplierId || null,
|
||
accountId: this.selectedAccountId || null,
|
||
amount: Number(this.trxAmount || 0),
|
||
txTime: this.order.orderTime,
|
||
remark: this.order.remark
|
||
};
|
||
try {
|
||
const url = isSaleOrPurchase ? isCollectOrPay ? `/api/payments/${this.biz}` : "/api/orders" : "/api/other-transactions";
|
||
await post(url, payload);
|
||
uni.showToast({ title: "已保存", icon: "success" });
|
||
setTimeout(() => {
|
||
uni.navigateBack();
|
||
}, 600);
|
||
} catch (e) {
|
||
uni.showToast({ title: e && e.message || "保存失败", icon: "none" });
|
||
}
|
||
},
|
||
saveAndReset() {
|
||
this.items = [];
|
||
this.trxAmount = 0;
|
||
this.order.remark = "";
|
||
this.payments = { cash: 0, bank: 0, wechat: 0 };
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "order" }, [
|
||
vue.createCommentVNode(" 顶部 Tab "),
|
||
vue.createElementVNode("view", { class: "tabs" }, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
{
|
||
class: vue.normalizeClass({ active: $data.biz === "sale" }),
|
||
onClick: _cache[0] || (_cache[0] = ($event) => $options.switchBiz("sale"))
|
||
},
|
||
"销售",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{
|
||
class: vue.normalizeClass({ active: $data.biz === "purchase" }),
|
||
onClick: _cache[1] || (_cache[1] = ($event) => $options.switchBiz("purchase"))
|
||
},
|
||
"进货",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{
|
||
class: vue.normalizeClass({ active: $data.biz === "income" }),
|
||
onClick: _cache[2] || (_cache[2] = ($event) => $options.switchBiz("income"))
|
||
},
|
||
"其他收入",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{
|
||
class: vue.normalizeClass({ active: $data.biz === "expense" }),
|
||
onClick: _cache[3] || (_cache[3] = ($event) => $options.switchBiz("expense"))
|
||
},
|
||
"其他支出",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
]),
|
||
vue.createCommentVNode(" 子类目按钮 "),
|
||
$data.biz === "sale" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "subtabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.saleType === "out" }]),
|
||
onClick: _cache[4] || (_cache[4] = ($event) => $data.saleType = "out")
|
||
},
|
||
"出货",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.saleType === "return" }]),
|
||
onClick: _cache[5] || (_cache[5] = ($event) => $data.saleType = "return")
|
||
},
|
||
"退货",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.saleType === "collect" }]),
|
||
onClick: _cache[6] || (_cache[6] = ($event) => $data.saleType = "collect")
|
||
},
|
||
"收款",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : $data.biz === "purchase" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "subtabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.purchaseType === "in" }]),
|
||
onClick: _cache[7] || (_cache[7] = ($event) => $data.purchaseType = "in")
|
||
},
|
||
"进货",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.purchaseType === "return" }]),
|
||
onClick: _cache[8] || (_cache[8] = ($event) => $data.purchaseType = "return")
|
||
},
|
||
"退货",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.purchaseType === "pay" }]),
|
||
onClick: _cache[9] || (_cache[9] = ($event) => $data.purchaseType = "pay")
|
||
},
|
||
"付款",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : vue.createCommentVNode("v-if", true),
|
||
vue.createCommentVNode(" 日期与客户 "),
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.order.orderTime,
|
||
onChange: _cache[10] || (_cache[10] = (...args) => $options.onDateChange && $options.onDateChange(...args))
|
||
}, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "时间"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($data.order.orderTime),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
], 40, ["value"]),
|
||
$data.biz === "sale" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 2,
|
||
class: "field",
|
||
onClick: _cache[11] || (_cache[11] = (...args) => $options.chooseCustomer && $options.chooseCustomer(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "客户"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.customerLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])) : $data.biz === "purchase" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 3,
|
||
class: "field",
|
||
onClick: _cache[12] || (_cache[12] = (...args) => $options.chooseSupplier && $options.chooseSupplier(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "供应商"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.supplierLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])) : vue.createCommentVNode("v-if", true),
|
||
vue.createCommentVNode(" 销售/进货:收款/付款 专用页面 "),
|
||
$data.biz === "sale" && $data.saleType === "collect" || $data.biz === "purchase" && $data.purchaseType === "pay" ? (vue.openBlock(), vue.createElementBlock("view", { key: 4 }, [
|
||
vue.createCommentVNode(" 客户 / 供应商 "),
|
||
$data.biz === "sale" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "field",
|
||
onClick: _cache[13] || (_cache[13] = (...args) => $options.chooseCustomer && $options.chooseCustomer(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "客户"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.customerLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])) : (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "field",
|
||
onClick: _cache[14] || (_cache[14] = (...args) => $options.chooseSupplier && $options.chooseSupplier(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "供应商"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.supplierLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])),
|
||
vue.createCommentVNode(" 三种收付款方式 "),
|
||
vue.createElementVNode("view", { class: "field pay-row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "现金"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "pay-input",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[15] || (_cache[15] = ($event) => $data.payments.cash = $event),
|
||
placeholder: "0.00",
|
||
onInput: _cache[16] || (_cache[16] = ($event) => $options.recalcPay())
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.payments.cash,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field pay-row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "银行存款"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "pay-input",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[17] || (_cache[17] = ($event) => $data.payments.bank = $event),
|
||
placeholder: "0.00",
|
||
onInput: _cache[18] || (_cache[18] = ($event) => $options.recalcPay())
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.payments.bank,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field pay-row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "微信"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "pay-input",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[19] || (_cache[19] = ($event) => $data.payments.wechat = $event),
|
||
placeholder: "0.00",
|
||
onInput: _cache[20] || (_cache[20] = ($event) => $options.recalcPay())
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.payments.wechat,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: "collapse-trigger",
|
||
onClick: _cache[21] || (_cache[21] = ($event) => $data.showMore = !$data.showMore)
|
||
},
|
||
vue.toDisplayString($data.showMore ? "收起" : ""),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createCommentVNode(" 备注与日期 "),
|
||
vue.createElementVNode("view", { class: "textarea" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "amount-badge" },
|
||
"总金额:" + vue.toDisplayString($options.payTotal.toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"textarea",
|
||
{
|
||
"onUpdate:modelValue": _cache[22] || (_cache[22] = ($event) => $data.order.remark = $event),
|
||
maxlength: "200",
|
||
placeholder: "备注(最多输入200个字)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.order.remark]
|
||
]),
|
||
vue.createElementVNode("view", { class: "date-mini" }, [
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.order.orderTime,
|
||
onChange: _cache[23] || (_cache[23] = (...args) => $options.onDateChange && $options.onDateChange(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
null,
|
||
vue.toDisplayString($data.order.orderTime),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["value"])
|
||
])
|
||
])
|
||
])) : $data.biz === "sale" || $data.biz === "purchase" ? (vue.openBlock(), vue.createElementBlock(
|
||
vue.Fragment,
|
||
{ key: 5 },
|
||
[
|
||
vue.createCommentVNode(" 已选商品与合计(销售/进货 出入库) "),
|
||
vue.createElementVNode("view", null, [
|
||
vue.createElementVNode("view", { class: "summary" }, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
null,
|
||
"选中货品(" + vue.toDisplayString($options.totalQuantity) + ")",
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
null,
|
||
"合计金额:¥ " + vue.toDisplayString($options.totalAmount.toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createCommentVNode(" 加号添加商品 "),
|
||
vue.createElementVNode("view", {
|
||
class: "add",
|
||
onClick: _cache[24] || (_cache[24] = (...args) => $options.chooseProduct && $options.chooseProduct(...args))
|
||
}, "+")
|
||
])
|
||
],
|
||
2112
|
||
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
||
)) : (vue.openBlock(), vue.createElementBlock(
|
||
vue.Fragment,
|
||
{ key: 6 },
|
||
[
|
||
vue.createCommentVNode(" 其它收入/支出 表单 "),
|
||
vue.createElementVNode("view", null, [
|
||
vue.createCommentVNode(" 往来单位类型切换 "),
|
||
vue.createElementVNode("view", { class: "subtabs" }, [
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.counterpartyType === "customer" }]),
|
||
onClick: _cache[25] || (_cache[25] = ($event) => $options.setCounterparty("customer"))
|
||
},
|
||
"客户",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: vue.normalizeClass(["subbtn", { active: $data.counterpartyType === "supplier" }]),
|
||
onClick: _cache[26] || (_cache[26] = ($event) => $options.setCounterparty("supplier"))
|
||
},
|
||
"供应商",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "chips" }, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.biz === "income" ? $options.incomeCategories : $options.expenseCategories, (c) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
key: c.key,
|
||
class: vue.normalizeClass(["chip", { active: $data.activeCategory === c.key }]),
|
||
onClick: ($event) => $data.activeCategory = c.key
|
||
}, vue.toDisplayString(c.label), 11, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "field",
|
||
onClick: _cache[27] || (_cache[27] = (...args) => $options.chooseCounterparty && $options.chooseCounterparty(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "往来单位"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.counterpartyLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "field",
|
||
onClick: _cache[28] || (_cache[28] = (...args) => $options.chooseAccount && $options.chooseAccount(...args))
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "结算账户"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.accountLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "金额"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[29] || (_cache[29] = ($event) => $data.trxAmount = $event),
|
||
placeholder: "0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.trxAmount,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "textarea" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"textarea",
|
||
{
|
||
"onUpdate:modelValue": _cache[30] || (_cache[30] = ($event) => $data.order.remark = $event),
|
||
maxlength: "200",
|
||
placeholder: "备注(最多输入200个字)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.order.remark]
|
||
])
|
||
])
|
||
])
|
||
],
|
||
2112
|
||
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
||
)),
|
||
vue.createCommentVNode(" 购物车空态 "),
|
||
!$data.items.length ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 7,
|
||
class: "empty"
|
||
}, [
|
||
vue.createElementVNode("image", {
|
||
src: _imports_0,
|
||
mode: "widthFix",
|
||
class: "empty-img"
|
||
}),
|
||
vue.createElementVNode("text", { class: "empty-text" }, "购物车里空空如也"),
|
||
vue.createElementVNode("text", { class: "empty-sub" }, "扫描或点击 “+” 选择商品吧")
|
||
])) : (vue.openBlock(), vue.createElementBlock(
|
||
vue.Fragment,
|
||
{ key: 8 },
|
||
[
|
||
vue.createCommentVNode(" 商品列表 "),
|
||
vue.createElementVNode("view", { class: "list" }, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.items, (it, idx) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "row",
|
||
key: idx
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "col name" },
|
||
vue.toDisplayString(it.productName),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("view", { class: "col qty" }, [
|
||
vue.withDirectives(vue.createElementVNode("input", {
|
||
type: "number",
|
||
"onUpdate:modelValue": ($event) => it.quantity = $event,
|
||
onInput: _cache[31] || (_cache[31] = ($event) => $options.recalc())
|
||
}, null, 40, ["onUpdate:modelValue"]), [
|
||
[
|
||
vue.vModelText,
|
||
it.quantity,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "col price" }, [
|
||
vue.withDirectives(vue.createElementVNode("input", {
|
||
type: "number",
|
||
"onUpdate:modelValue": ($event) => it.unitPrice = $event,
|
||
onInput: ($event) => $options.onPriceInput(it)
|
||
}, null, 40, ["onUpdate:modelValue", "onInput"]), [
|
||
[
|
||
vue.vModelText,
|
||
it.unitPrice,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "col amount" },
|
||
"¥ " + vue.toDisplayString((Number(it.quantity) * Number(it.unitPrice)).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
],
|
||
2112
|
||
/* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
|
||
)),
|
||
vue.createCommentVNode(" 底部提交栏 "),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "ghost",
|
||
onClick: _cache[32] || (_cache[32] = (...args) => $options.saveAndReset && $options.saveAndReset(...args))
|
||
}, "再记一笔"),
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[33] || (_cache[33] = (...args) => $options.submit && $options.submit(...args))
|
||
}, "保存")
|
||
])
|
||
]);
|
||
}
|
||
const PagesOrderCreate = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$j], ["__file", "D:/wx/PartsInquiry/frontend/pages/order/create.vue"]]);
|
||
const _sfc_main$j = {
|
||
data() {
|
||
return { kw: "", products: [] };
|
||
},
|
||
onLoad() {
|
||
this.search();
|
||
},
|
||
methods: {
|
||
async search() {
|
||
try {
|
||
const res = await get("/api/products", { kw: this.kw, page: 1, size: 50 });
|
||
this.products = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
select(p) {
|
||
const opener = getCurrentPages()[getCurrentPages().length - 2];
|
||
if (opener && opener.$vm && opener.$vm.items) {
|
||
const initPrice = Number(p.retailPrice != null ? p.retailPrice : p.price || 0);
|
||
opener.$vm.items.push({ productId: p.id, productName: p.name, quantity: 1, unitPrice: initPrice, _autoPrice: true });
|
||
}
|
||
uni.navigateBack();
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "search" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.kw = $event),
|
||
placeholder: "搜索商品名称/编码",
|
||
onConfirm: _cache[1] || (_cache[1] = (...args) => $options.search && $options.search(...args))
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.kw]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.search && $options.search(...args))
|
||
}, "搜索")
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.products, (p) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: p.id,
|
||
onClick: ($event) => $options.select(p)
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(p.name),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "meta" },
|
||
vue.toDisplayString((p.brand || "") + " " + (p.model || "") + " " + (p.spec || "")) + " · 库存:" + vue.toDisplayString(p.stock ?? 0),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
]);
|
||
}
|
||
const PagesProductSelect = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$i], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/select.vue"]]);
|
||
const _sfc_main$i = {
|
||
data() {
|
||
return {
|
||
items: [],
|
||
query: { kw: "", page: 1, size: 20, categoryId: "" },
|
||
finished: false,
|
||
loading: false,
|
||
tab: "all",
|
||
categories: []
|
||
};
|
||
},
|
||
onLoad() {
|
||
this.fetchCategories();
|
||
this.reload();
|
||
},
|
||
onShow() {
|
||
this.reload();
|
||
},
|
||
computed: {
|
||
categoryNames() {
|
||
return this.categories.map((c) => c.name);
|
||
},
|
||
categoryLabel() {
|
||
const c = this.categories.find((x) => String(x.id) === String(this.query.categoryId));
|
||
return c ? "类别:" + c.name : "选择类别";
|
||
}
|
||
},
|
||
methods: {
|
||
switchTab(t) {
|
||
this.tab = t;
|
||
this.query.categoryId = "";
|
||
this.reload();
|
||
},
|
||
onPickCategory(e) {
|
||
const idx = Number(e.detail.value);
|
||
const c = this.categories[idx];
|
||
this.query.categoryId = c ? c.id : "";
|
||
this.reload();
|
||
},
|
||
async fetchCategories() {
|
||
try {
|
||
const res = await get("/api/product-categories", {});
|
||
this.categories = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (_) {
|
||
}
|
||
},
|
||
reload() {
|
||
this.items = [];
|
||
this.query.page = 1;
|
||
this.finished = false;
|
||
this.loadMore();
|
||
},
|
||
async loadMore() {
|
||
if (this.loading || this.finished)
|
||
return;
|
||
this.loading = true;
|
||
try {
|
||
const params = { kw: this.query.kw, page: this.query.page, size: this.query.size };
|
||
if (this.tab === "category" && this.query.categoryId)
|
||
params.categoryId = this.query.categoryId;
|
||
const res = await get("/api/products", params);
|
||
const list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
this.items = this.items.concat(list);
|
||
if (list.length < this.query.size)
|
||
this.finished = true;
|
||
this.query.page += 1;
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
openForm(id) {
|
||
const url = "/pages/product/form" + (id ? "?id=" + id : "");
|
||
uni.navigateTo({ url });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "tabs" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.tab === "all" }]),
|
||
onClick: _cache[0] || (_cache[0] = ($event) => $options.switchTab("all"))
|
||
},
|
||
"全部",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.tab === "category" }]),
|
||
onClick: _cache[1] || (_cache[1] = ($event) => $options.switchTab("category"))
|
||
},
|
||
"按类别",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "search" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.query.kw = $event),
|
||
placeholder: "输入名称/条码/规格查询",
|
||
onConfirm: _cache[3] || (_cache[3] = (...args) => $options.reload && $options.reload(...args))
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.query.kw,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
$data.tab === "category" ? (vue.openBlock(), vue.createElementBlock("picker", {
|
||
key: 0,
|
||
mode: "selector",
|
||
range: $options.categoryNames,
|
||
onChange: _cache[4] || (_cache[4] = (...args) => $options.onPickCategory && $options.onPickCategory(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "picker" },
|
||
vue.toDisplayString($options.categoryLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["range"])) : vue.createCommentVNode("v-if", true),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[5] || (_cache[5] = (...args) => $options.reload && $options.reload(...args))
|
||
}, "查询")
|
||
]),
|
||
vue.createElementVNode(
|
||
"scroll-view",
|
||
{
|
||
"scroll-y": "",
|
||
class: "list",
|
||
onScrolltolower: _cache[6] || (_cache[6] = (...args) => $options.loadMore && $options.loadMore(...args))
|
||
},
|
||
[
|
||
$data.items.length ? (vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
{ key: 0 },
|
||
vue.renderList($data.items, (it) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: it.id,
|
||
onClick: ($event) => $options.openForm(it.id)
|
||
}, [
|
||
it.cover ? (vue.openBlock(), vue.createElementBlock("image", {
|
||
key: 0,
|
||
src: it.cover,
|
||
class: "thumb",
|
||
mode: "aspectFill"
|
||
}, null, 8, ["src"])) : vue.createCommentVNode("v-if", true),
|
||
vue.createElementVNode("view", { class: "content" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(it.name),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "meta" },
|
||
vue.toDisplayString(it.brand || "-") + " " + vue.toDisplayString(it.model || "") + " " + vue.toDisplayString(it.spec || ""),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("view", { class: "meta" }, [
|
||
vue.createTextVNode(
|
||
"库存:" + vue.toDisplayString(it.stock ?? 0) + " ",
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "price" },
|
||
"零售价:¥" + vue.toDisplayString((it.retailPrice ?? it.price ?? 0).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
])
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
)) : (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "empty"
|
||
}, [
|
||
vue.createElementVNode("text", null, "暂无数据,点击右上角“+”新增")
|
||
]))
|
||
],
|
||
32
|
||
/* NEED_HYDRATION */
|
||
),
|
||
vue.createElementVNode("view", {
|
||
class: "fab",
|
||
onClick: _cache[7] || (_cache[7] = ($event) => $options.openForm())
|
||
}, "+")
|
||
]);
|
||
}
|
||
const PagesProductList = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$h], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/list.vue"]]);
|
||
const ITEM_SIZE = 210;
|
||
const GAP = 18;
|
||
const COLS = 3;
|
||
function px(rpx) {
|
||
return rpx;
|
||
}
|
||
const _sfc_main$h = {
|
||
name: "ImageUploader",
|
||
props: {
|
||
modelValue: { type: Array, default: () => [] },
|
||
max: { type: Number, default: 9 },
|
||
uploadPath: { type: String, default: "/api/attachments" },
|
||
uploadFieldName: { type: String, default: "file" },
|
||
formData: { type: Object, default: () => ({ ownerType: "product" }) }
|
||
},
|
||
data() {
|
||
return {
|
||
innerList: []
|
||
};
|
||
},
|
||
computed: {
|
||
areaHeight() {
|
||
const rows = Math.ceil((this.innerList.length + 1) / COLS) || 1;
|
||
return rows * ITEM_SIZE + (rows - 1) * GAP;
|
||
}
|
||
},
|
||
watch: {
|
||
modelValue: {
|
||
immediate: true,
|
||
handler(list) {
|
||
const mapped = (list || []).map((u, i) => ({
|
||
uid: String(i) + "_" + (u.id || u.url || Math.random().toString(36).slice(2)),
|
||
url: typeof u === "string" ? u : u.url || "",
|
||
x: this.posOf(i).x,
|
||
y: this.posOf(i).y
|
||
}));
|
||
this.innerList = mapped;
|
||
}
|
||
}
|
||
},
|
||
methods: {
|
||
posOf(index) {
|
||
const row = Math.floor(index / COLS);
|
||
const col = index % COLS;
|
||
return { x: px(col * (ITEM_SIZE + GAP)), y: px(row * (ITEM_SIZE + GAP)) };
|
||
},
|
||
cellStyle(index) {
|
||
return {
|
||
width: ITEM_SIZE + "rpx",
|
||
height: ITEM_SIZE + "rpx"
|
||
};
|
||
},
|
||
preview(index) {
|
||
uni.previewImage({ urls: this.innerList.map((i) => i.url), current: index });
|
||
},
|
||
remove(index) {
|
||
this.innerList.splice(index, 1);
|
||
this.reflow();
|
||
this.emit();
|
||
},
|
||
choose() {
|
||
const remain = this.max - this.innerList.length;
|
||
if (remain <= 0)
|
||
return;
|
||
uni.chooseImage({ count: remain, success: async (res) => {
|
||
for (const path of res.tempFilePaths) {
|
||
await this.doUpload(path);
|
||
}
|
||
} });
|
||
},
|
||
async doUpload(filePath) {
|
||
var _a;
|
||
try {
|
||
const resp = await upload(this.uploadPath, filePath, this.formData, this.uploadFieldName);
|
||
const url = (resp == null ? void 0 : resp.url) || ((_a = resp == null ? void 0 : resp.data) == null ? void 0 : _a.url) || (resp == null ? void 0 : resp.path) || "";
|
||
if (!url)
|
||
throw new Error("上传响应无 url");
|
||
this.innerList.push({ uid: Math.random().toString(36).slice(2), url, ...this.posOf(this.innerList.length) });
|
||
this.reflow();
|
||
this.emit();
|
||
} catch (e) {
|
||
uni.showToast({ title: "上传失败", icon: "none" });
|
||
}
|
||
},
|
||
onMoving(index, e) {
|
||
const { x, y } = e.detail;
|
||
this.innerList[index].x = x;
|
||
this.innerList[index].y = y;
|
||
},
|
||
onMoveEnd(index) {
|
||
const mv = this.innerList[index];
|
||
const col = Math.round(mv.x / (ITEM_SIZE + GAP));
|
||
const row = Math.round(mv.y / (ITEM_SIZE + GAP));
|
||
let newIndex = row * COLS + col;
|
||
newIndex = Math.max(0, Math.min(newIndex, this.innerList.length - 1));
|
||
if (newIndex !== index) {
|
||
const moved = this.innerList.splice(index, 1)[0];
|
||
this.innerList.splice(newIndex, 0, moved);
|
||
}
|
||
this.reflow();
|
||
this.emit();
|
||
},
|
||
reflow() {
|
||
this.innerList.forEach((it, i) => {
|
||
const p = this.posOf(i);
|
||
it.x = p.x;
|
||
it.y = p.y;
|
||
});
|
||
},
|
||
emit() {
|
||
this.$emit("update:modelValue", this.innerList.map((i) => i.url));
|
||
this.$emit("change", this.innerList.map((i) => i.url));
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "uploader" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: "grid",
|
||
style: vue.normalizeStyle({ height: $options.areaHeight + "rpx" })
|
||
},
|
||
[
|
||
vue.createElementVNode(
|
||
"movable-area",
|
||
{
|
||
class: "area",
|
||
style: vue.normalizeStyle({ height: $options.areaHeight + "rpx" })
|
||
},
|
||
[
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.innerList, (img, index) => {
|
||
return vue.openBlock(), vue.createElementBlock("movable-view", {
|
||
key: img.uid,
|
||
class: "cell",
|
||
style: vue.normalizeStyle($options.cellStyle(index)),
|
||
direction: "all",
|
||
damping: 40,
|
||
friction: 2,
|
||
x: img.x,
|
||
y: img.y,
|
||
onChange: ($event) => $options.onMoving(index, $event),
|
||
onTouchend: ($event) => $options.onMoveEnd(index)
|
||
}, [
|
||
vue.createElementVNode("image", {
|
||
src: img.url,
|
||
mode: "aspectFill",
|
||
class: "thumb",
|
||
onClick: ($event) => $options.preview(index)
|
||
}, null, 8, ["src", "onClick"]),
|
||
vue.createElementVNode("view", {
|
||
class: "remove",
|
||
onClick: vue.withModifiers(($event) => $options.remove(index), ["stop"])
|
||
}, "×", 8, ["onClick"])
|
||
], 44, ["x", "y", "onChange", "onTouchend"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
)),
|
||
$data.innerList.length < $props.max ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "adder",
|
||
onClick: _cache[0] || (_cache[0] = (...args) => $options.choose && $options.choose(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "+")
|
||
])) : vue.createCommentVNode("v-if", true)
|
||
],
|
||
4
|
||
/* STYLE */
|
||
)
|
||
],
|
||
4
|
||
/* STYLE */
|
||
)
|
||
]);
|
||
}
|
||
const ImageUploader = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$g], ["__scopeId", "data-v-7bd1ddd2"], ["__file", "D:/wx/PartsInquiry/frontend/components/ImageUploader.vue"]]);
|
||
const _sfc_main$g = {
|
||
components: { ImageUploader },
|
||
data() {
|
||
return {
|
||
id: "",
|
||
form: {
|
||
name: "",
|
||
barcode: "",
|
||
brand: "",
|
||
model: "",
|
||
spec: "",
|
||
origin: "",
|
||
categoryId: "",
|
||
unitId: "",
|
||
stock: null,
|
||
safeMin: null,
|
||
safeMax: null,
|
||
purchasePrice: null,
|
||
retailPrice: null,
|
||
wholesalePrice: null,
|
||
bigClientPrice: null,
|
||
images: [],
|
||
remark: ""
|
||
},
|
||
units: [],
|
||
categories: []
|
||
};
|
||
},
|
||
onLoad(query) {
|
||
this.id = (query == null ? void 0 : query.id) || "";
|
||
this.bootstrap();
|
||
},
|
||
computed: {
|
||
unitNames() {
|
||
return this.units.map((u) => u.name);
|
||
},
|
||
categoryNames() {
|
||
return this.categories.map((c) => c.name);
|
||
},
|
||
unitLabel() {
|
||
const u = this.units.find((x) => String(x.id) === String(this.form.unitId));
|
||
return u ? u.name : "选择单位";
|
||
},
|
||
categoryLabel() {
|
||
const c = this.categories.find((x) => String(x.id) === String(this.form.categoryId));
|
||
return c ? c.name : "选择类别";
|
||
}
|
||
},
|
||
methods: {
|
||
async bootstrap() {
|
||
await Promise.all([this.fetchUnits(), this.fetchCategories()]);
|
||
if (this.id)
|
||
this.loadDetail();
|
||
},
|
||
async fetchUnits() {
|
||
try {
|
||
const res = await get("/api/product-units");
|
||
this.units = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (_) {
|
||
}
|
||
},
|
||
async fetchCategories() {
|
||
try {
|
||
const res = await get("/api/product-categories");
|
||
this.categories = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (_) {
|
||
}
|
||
},
|
||
onPickUnit(e) {
|
||
const idx = Number(e.detail.value);
|
||
const u = this.units[idx];
|
||
this.form.unitId = u ? u.id : "";
|
||
},
|
||
onPickCategory(e) {
|
||
const idx = Number(e.detail.value);
|
||
const c = this.categories[idx];
|
||
this.form.categoryId = c ? c.id : "";
|
||
},
|
||
scan() {
|
||
uni.scanCode({ onlyFromCamera: false, success: (res) => {
|
||
this.form.barcode = res.result;
|
||
} });
|
||
},
|
||
async loadDetail() {
|
||
try {
|
||
const data = await get("/api/products/" + this.id);
|
||
Object.assign(this.form, {
|
||
name: data.name,
|
||
barcode: data.barcode,
|
||
brand: data.brand,
|
||
model: data.model,
|
||
spec: data.spec,
|
||
origin: data.origin,
|
||
categoryId: data.categoryId,
|
||
unitId: data.unitId,
|
||
stock: data.stock,
|
||
safeMin: data.safeMin,
|
||
safeMax: data.safeMax,
|
||
purchasePrice: data.purchasePrice,
|
||
retailPrice: data.retailPrice,
|
||
wholesalePrice: data.wholesalePrice,
|
||
bigClientPrice: data.bigClientPrice,
|
||
images: (data.images || []).map((i) => i.url || i)
|
||
});
|
||
} catch (_) {
|
||
}
|
||
},
|
||
validate() {
|
||
if (!this.form.name) {
|
||
uni.showToast({ title: "请填写名称", icon: "none" });
|
||
return false;
|
||
}
|
||
if (this.form.safeMin != null && this.form.safeMax != null && Number(this.form.safeMin) > Number(this.form.safeMax)) {
|
||
uni.showToast({ title: "安全库存区间不合法", icon: "none" });
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
buildPayload() {
|
||
const f = this.form;
|
||
return {
|
||
name: f.name,
|
||
barcode: f.barcode,
|
||
brand: f.brand,
|
||
model: f.model,
|
||
spec: f.spec,
|
||
origin: f.origin,
|
||
categoryId: f.categoryId || null,
|
||
unitId: f.unitId,
|
||
safeMin: f.safeMin,
|
||
safeMax: f.safeMax,
|
||
prices: {
|
||
purchasePrice: f.purchasePrice,
|
||
retailPrice: f.retailPrice,
|
||
wholesalePrice: f.wholesalePrice,
|
||
bigClientPrice: f.bigClientPrice
|
||
},
|
||
stock: f.stock,
|
||
images: f.images,
|
||
remark: f.remark
|
||
};
|
||
},
|
||
async save(goOn) {
|
||
if (!this.validate())
|
||
return;
|
||
const payload = this.buildPayload();
|
||
try {
|
||
if (this.id)
|
||
await put("/api/products/" + this.id, payload);
|
||
else
|
||
await post("/api/products", payload);
|
||
uni.showToast({ title: "保存成功", icon: "success" });
|
||
if (goOn && !this.id) {
|
||
this.form = { name: "", barcode: "", brand: "", model: "", spec: "", origin: "", categoryId: "", unitId: "", stock: null, safeMin: null, safeMax: null, purchasePrice: null, retailPrice: null, wholesalePrice: null, bigClientPrice: null, images: [], remark: "" };
|
||
} else {
|
||
setTimeout(() => uni.navigateBack(), 400);
|
||
}
|
||
} catch (e) {
|
||
uni.showToast({ title: "保存失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
|
||
const _component_ImageUploader = vue.resolveComponent("ImageUploader");
|
||
return vue.openBlock(), vue.createElementBlock("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "page"
|
||
}, [
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "商品名称"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.form.name = $event),
|
||
placeholder: "必填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.name,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "条形码"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.form.barcode = $event),
|
||
placeholder: "可扫码或输入"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.barcode,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.scan && $options.scan(...args))
|
||
}, "扫码")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "品牌/型号/规格/产地")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.form.brand = $event),
|
||
placeholder: "品牌"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.brand,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.form.model = $event),
|
||
placeholder: "型号"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.model,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.form.spec = $event),
|
||
placeholder: "规格"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.spec,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $data.form.origin = $event),
|
||
placeholder: "产地"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.origin,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("picker", {
|
||
mode: "selector",
|
||
range: $options.unitNames,
|
||
onChange: _cache[7] || (_cache[7] = (...args) => $options.onPickUnit && $options.onPickUnit(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "picker" },
|
||
"主单位:" + vue.toDisplayString($options.unitLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["range"]),
|
||
vue.createElementVNode("picker", {
|
||
mode: "selector",
|
||
range: $options.categoryNames,
|
||
onChange: _cache[8] || (_cache[8] = (...args) => $options.onPickCategory && $options.onPickCategory(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "picker" },
|
||
"类别:" + vue.toDisplayString($options.categoryLabel),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["range"])
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "库存与安全库存")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => $data.form.stock = $event),
|
||
placeholder: "当前库存"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.stock,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
]),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => $data.form.safeMin = $event),
|
||
placeholder: "安全库存下限"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.safeMin,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
]),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => $data.form.safeMax = $event),
|
||
placeholder: "安全库存上限"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.safeMax,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "价格(进价/零售/批发/大单)")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row prices" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => $data.form.purchasePrice = $event),
|
||
placeholder: "进货价"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.purchasePrice,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
]),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => $data.form.retailPrice = $event),
|
||
placeholder: "零售价"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.retailPrice,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
]),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => $data.form.wholesalePrice = $event),
|
||
placeholder: "批发价"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.wholesalePrice,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
]),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[15] || (_cache[15] = ($event) => $data.form.bigClientPrice = $event),
|
||
placeholder: "大单价"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.bigClientPrice,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "图片"),
|
||
vue.createVNode(_component_ImageUploader, {
|
||
modelValue: $data.form.images,
|
||
"onUpdate:modelValue": _cache[16] || (_cache[16] = ($event) => $data.form.images = $event),
|
||
formData: { ownerType: "product" }
|
||
}, null, 8, ["modelValue"])
|
||
]),
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "备注"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"textarea",
|
||
{
|
||
"onUpdate:modelValue": _cache[17] || (_cache[17] = ($event) => $data.form.remark = $event),
|
||
placeholder: "可选",
|
||
"auto-height": ""
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.remark,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "fixed" }, [
|
||
vue.createElementVNode("button", {
|
||
type: "default",
|
||
onClick: _cache[18] || (_cache[18] = ($event) => $options.save(false))
|
||
}, "保存"),
|
||
vue.createElementVNode("button", {
|
||
type: "primary",
|
||
onClick: _cache[19] || (_cache[19] = ($event) => $options.save(true))
|
||
}, "保存并继续")
|
||
])
|
||
]);
|
||
}
|
||
const PagesProductForm = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$f], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/form.vue"]]);
|
||
const _sfc_main$f = {
|
||
data() {
|
||
return { name: "", list: [] };
|
||
},
|
||
onLoad() {
|
||
this.reload();
|
||
},
|
||
methods: {
|
||
async reload() {
|
||
try {
|
||
const res = await get("/api/product-categories");
|
||
this.list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (_) {
|
||
}
|
||
},
|
||
async create() {
|
||
if (!this.name)
|
||
return;
|
||
await post("/api/product-categories", { name: this.name });
|
||
this.name = "";
|
||
this.reload();
|
||
},
|
||
async update(c) {
|
||
await put("/api/product-categories/" + c.id, { name: c.name });
|
||
uni.showToast({ title: "已保存", icon: "success" });
|
||
},
|
||
async remove(c) {
|
||
uni.showModal({ content: "确定删除该类别?", success: async (r) => {
|
||
if (!r.confirm)
|
||
return;
|
||
await del("/api/product-categories/" + c.id);
|
||
this.reload();
|
||
} });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "toolbar" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.name = $event),
|
||
placeholder: "新类别名称"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.name,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[1] || (_cache[1] = (...args) => $options.create && $options.create(...args))
|
||
}, "新增")
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.list, (c) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: c.id
|
||
}, [
|
||
vue.withDirectives(vue.createElementVNode("input", {
|
||
"onUpdate:modelValue": ($event) => c.name = $event
|
||
}, null, 8, ["onUpdate:modelValue"]), [
|
||
[
|
||
vue.vModelText,
|
||
c.name,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
vue.createElementVNode("view", { class: "ops" }, [
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: ($event) => $options.update(c)
|
||
}, "保存", 8, ["onClick"]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
type: "warn",
|
||
onClick: ($event) => $options.remove(c)
|
||
}, "删除", 8, ["onClick"])
|
||
])
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
]);
|
||
}
|
||
const PagesProductCategories = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$e], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/categories.vue"]]);
|
||
const _sfc_main$e = {
|
||
data() {
|
||
return { name: "", list: [] };
|
||
},
|
||
onLoad() {
|
||
this.reload();
|
||
},
|
||
methods: {
|
||
async reload() {
|
||
try {
|
||
const res = await get("/api/product-units");
|
||
this.list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (_) {
|
||
}
|
||
},
|
||
async create() {
|
||
if (!this.name)
|
||
return;
|
||
await post("/api/product-units", { name: this.name });
|
||
this.name = "";
|
||
this.reload();
|
||
},
|
||
async update(u) {
|
||
await put("/api/product-units/" + u.id, { name: u.name });
|
||
uni.showToast({ title: "已保存", icon: "success" });
|
||
},
|
||
async remove(u) {
|
||
uni.showModal({ content: "确定删除该单位?", success: async (r) => {
|
||
if (!r.confirm)
|
||
return;
|
||
await del("/api/product-units/" + u.id);
|
||
this.reload();
|
||
} });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "toolbar" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.name = $event),
|
||
placeholder: "新单位名称"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.name,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[1] || (_cache[1] = (...args) => $options.create && $options.create(...args))
|
||
}, "新增")
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.list, (u) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: u.id
|
||
}, [
|
||
vue.withDirectives(vue.createElementVNode("input", {
|
||
"onUpdate:modelValue": ($event) => u.name = $event
|
||
}, null, 8, ["onUpdate:modelValue"]), [
|
||
[
|
||
vue.vModelText,
|
||
u.name,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
]),
|
||
vue.createElementVNode("view", { class: "ops" }, [
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: ($event) => $options.update(u)
|
||
}, "保存", 8, ["onClick"]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
type: "warn",
|
||
onClick: ($event) => $options.remove(u)
|
||
}, "删除", 8, ["onClick"])
|
||
])
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
]);
|
||
}
|
||
const PagesProductUnits = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$d], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/units.vue"]]);
|
||
const _sfc_main$d = {
|
||
data() {
|
||
return { settings: { hideZeroStock: false, hidePurchasePrice: false } };
|
||
},
|
||
onLoad() {
|
||
this.load();
|
||
},
|
||
methods: {
|
||
async load() {
|
||
try {
|
||
const res = await get("/api/product-settings");
|
||
this.settings = { hideZeroStock: !!(res == null ? void 0 : res.hideZeroStock), hidePurchasePrice: !!(res == null ? void 0 : res.hidePurchasePrice) };
|
||
} catch (_) {
|
||
}
|
||
},
|
||
async update(key, val) {
|
||
const next = { ...this.settings, [key]: val };
|
||
this.settings = next;
|
||
try {
|
||
await put("/api/product-settings", next);
|
||
} catch (_) {
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", null, "隐藏零库存商品"),
|
||
vue.createElementVNode("switch", {
|
||
checked: $data.settings.hideZeroStock,
|
||
onChange: _cache[0] || (_cache[0] = (e) => $options.update("hideZeroStock", e.detail.value))
|
||
}, null, 40, ["checked"])
|
||
]),
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", null, "隐藏进货价"),
|
||
vue.createElementVNode("switch", {
|
||
checked: $data.settings.hidePurchasePrice,
|
||
onChange: _cache[1] || (_cache[1] = (e) => $options.update("hidePurchasePrice", e.detail.value))
|
||
}, null, 40, ["checked"])
|
||
])
|
||
]);
|
||
}
|
||
const PagesProductSettings = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$c], ["__file", "D:/wx/PartsInquiry/frontend/pages/product/settings.vue"]]);
|
||
const _sfc_main$c = {
|
||
data() {
|
||
return { kw: "", debtOnly: false, customers: [] };
|
||
},
|
||
onLoad() {
|
||
this.search();
|
||
},
|
||
onShow() {
|
||
this.search();
|
||
},
|
||
methods: {
|
||
toggleDebtOnly() {
|
||
this.debtOnly = !this.debtOnly;
|
||
this.search();
|
||
},
|
||
async search() {
|
||
try {
|
||
const res = await get("/api/customers", { kw: this.kw, debtOnly: this.debtOnly, page: 1, size: 50 });
|
||
this.customers = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
createCustomer() {
|
||
uni.navigateTo({ url: "/pages/customer/form" });
|
||
},
|
||
select(c) {
|
||
const pages = getCurrentPages();
|
||
const prev = pages.length >= 2 ? pages[pages.length - 2] : null;
|
||
const vm = prev && prev.$vm ? prev.$vm : null;
|
||
if (vm && vm.order) {
|
||
vm.order.customerId = c.id;
|
||
vm.customerName = c.name;
|
||
}
|
||
uni.navigateBack();
|
||
},
|
||
openDetail(c) {
|
||
uni.navigateTo({ url: "/pages/customer/detail?id=" + c.id });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "search" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.kw = $event),
|
||
placeholder: "搜索客户名称/电话",
|
||
onConfirm: _cache[1] || (_cache[1] = (...args) => $options.search && $options.search(...args))
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.kw]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.search && $options.search(...args))
|
||
}, "搜索"),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
type: $data.debtOnly ? "primary" : "default",
|
||
onClick: _cache[3] || (_cache[3] = (...args) => $options.toggleDebtOnly && $options.toggleDebtOnly(...args))
|
||
}, "只看欠款", 8, ["type"])
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.customers, (c) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: c.id,
|
||
onClick: ($event) => $options.openDetail(c)
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(c.name),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("view", { class: "meta" }, [
|
||
vue.createTextVNode(
|
||
vue.toDisplayString(c.mobile || "—") + " ",
|
||
1
|
||
/* TEXT */
|
||
),
|
||
typeof c.receivable === "number" ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{ key: 0 },
|
||
"|应收:¥ " + vue.toDisplayString(Number(c.receivable).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.createCommentVNode("v-if", true)
|
||
])
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[4] || (_cache[4] = (...args) => $options.createCustomer && $options.createCustomer(...args))
|
||
}, "新增客户")
|
||
])
|
||
]);
|
||
}
|
||
const PagesCustomerSelect = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$b], ["__file", "D:/wx/PartsInquiry/frontend/pages/customer/select.vue"]]);
|
||
const _sfc_main$b = {
|
||
data() {
|
||
return {
|
||
id: null,
|
||
form: { name: "", level: "", priceLevel: "retail", contactName: "", mobile: "", phone: "", address: "", arOpening: 0, remark: "" },
|
||
priceLevels: ["零售价", "批发价", "大单报价"],
|
||
priceLabels: ["零售价", "批发价", "大单报价"],
|
||
priceIdx: 0
|
||
};
|
||
},
|
||
onLoad(query) {
|
||
if (query && query.id) {
|
||
this.id = Number(query.id);
|
||
}
|
||
},
|
||
methods: {
|
||
onPriceChange(e) {
|
||
this.priceIdx = Number(e.detail.value);
|
||
this.form.priceLevel = this.priceLevels[this.priceIdx];
|
||
},
|
||
async save() {
|
||
if (!this.form.name)
|
||
return uni.showToast({ title: "请填写客户名称", icon: "none" });
|
||
try {
|
||
if (this.id)
|
||
await put(`/api/customers/${this.id}`, this.form);
|
||
else
|
||
await post("/api/customers", this.form);
|
||
uni.showToast({ title: "保存成功", icon: "success" });
|
||
setTimeout(() => uni.navigateBack(), 500);
|
||
} catch (e) {
|
||
uni.showToast({ title: (e == null ? void 0 : e.message) || "保存失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "客户名称"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.form.name = $event),
|
||
placeholder: "必填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.name]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "客户等级"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.form.level = $event),
|
||
placeholder: "可选,如 VIP/A/B"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.level]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "售价档位"),
|
||
vue.createElementVNode("picker", {
|
||
range: $data.priceLabels,
|
||
value: $data.priceIdx,
|
||
onChange: _cache[2] || (_cache[2] = (...args) => $options.onPriceChange && $options.onPriceChange(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "value" },
|
||
vue.toDisplayString($data.priceLabels[$data.priceIdx]),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["range", "value"])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "联系人"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.form.contactName = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.contactName]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "手机"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.form.mobile = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.mobile]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "电话"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.form.phone = $event),
|
||
placeholder: "可选(座机)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.phone]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "送货地址"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $data.form.address = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.address]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "初始应收"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.form.arOpening = $event),
|
||
placeholder: "默认 0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.arOpening,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "textarea" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"textarea",
|
||
{
|
||
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $data.form.remark = $event),
|
||
maxlength: "200",
|
||
placeholder: "备注(最多200字)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.remark]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[9] || (_cache[9] = (...args) => $options.save && $options.save(...args))
|
||
}, "保存")
|
||
])
|
||
]);
|
||
}
|
||
const PagesCustomerForm = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$a], ["__file", "D:/wx/PartsInquiry/frontend/pages/customer/form.vue"]]);
|
||
const _sfc_main$a = {
|
||
data() {
|
||
return { id: null, d: {}, editing: false, form: { name: "", contactName: "", mobile: "", phone: "", address: "", level: "", priceLevel: "零售价", arOpening: 0, remark: "" }, priceLevels: ["零售价", "批发价", "大单报价"], priceLabels: ["零售价", "批发价", "大单报价"], priceIdx: 0 };
|
||
},
|
||
onLoad(q) {
|
||
if (q && q.id) {
|
||
this.id = Number(q.id);
|
||
this.fetch();
|
||
}
|
||
},
|
||
methods: {
|
||
async fetch() {
|
||
try {
|
||
this.d = await get(`/api/customers/${this.id}`);
|
||
this.form = {
|
||
name: this.d.name || "",
|
||
contactName: this.d.contactName || "",
|
||
mobile: this.d.mobile || "",
|
||
phone: this.d.phone || "",
|
||
address: this.d.address || "",
|
||
level: this.d.level || "",
|
||
priceLevel: this.d.priceLevel || "retail",
|
||
arOpening: Number(this.d.arOpening || 0),
|
||
remark: this.d.remark || ""
|
||
};
|
||
const idx = this.priceLevels.indexOf(this.form.priceLevel);
|
||
this.priceIdx = idx >= 0 ? idx : 0;
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
toggleEdit() {
|
||
this.editing = !this.editing;
|
||
},
|
||
onPriceChange(e) {
|
||
this.priceIdx = Number(e.detail.value);
|
||
this.form.priceLevel = this.priceLevels[this.priceIdx];
|
||
},
|
||
choose() {
|
||
const pages = getCurrentPages();
|
||
let targetIdx = -1;
|
||
for (let i = pages.length - 2; i >= 0; i--) {
|
||
const vm = pages[i] && pages[i].$vm ? pages[i].$vm : null;
|
||
if (vm && vm.order) {
|
||
vm.order.customerId = this.d.id;
|
||
vm.customerName = this.d.name;
|
||
targetIdx = i;
|
||
break;
|
||
}
|
||
}
|
||
if (targetIdx >= 0) {
|
||
const delta = pages.length - 1 - targetIdx;
|
||
uni.navigateBack({ delta });
|
||
} else {
|
||
uni.navigateBack();
|
||
}
|
||
},
|
||
async save() {
|
||
if (!this.form.name)
|
||
return uni.showToast({ title: "请填写客户名称", icon: "none" });
|
||
try {
|
||
await put(`/api/customers/${this.id}`, this.form);
|
||
uni.showToast({ title: "已保存", icon: "success" });
|
||
this.editing = false;
|
||
await this.fetch();
|
||
} catch (e) {
|
||
uni.showToast({ title: (e == null ? void 0 : e.message) || "保存失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "名称"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.name),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.form.name = $event),
|
||
placeholder: "必填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.name]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "联系人"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.contactName || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.form.contactName = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.contactName]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "手机"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.mobile || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.form.mobile = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.mobile]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "电话"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.phone || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.form.phone = $event),
|
||
placeholder: "可选(座机)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.phone]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "地址"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.address || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.form.address = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.address]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "等级"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.level || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.form.level = $event),
|
||
placeholder: "可选,如 VIP/A/B"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.level]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "售价档位"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.priceLevel),
|
||
1
|
||
/* TEXT */
|
||
)) : (vue.openBlock(), vue.createElementBlock("picker", {
|
||
key: 1,
|
||
range: $data.priceLabels,
|
||
value: $data.priceIdx,
|
||
onChange: _cache[6] || (_cache[6] = (...args) => $options.onPriceChange && $options.onPriceChange(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "value" },
|
||
vue.toDisplayString($data.priceLabels[$data.priceIdx]),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["range", "value"]))
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "初始应收"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
"¥ " + vue.toDisplayString(Number($data.d.arOpening || 0).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.form.arOpening = $event),
|
||
placeholder: "0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.arOpening,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "当前应收"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value emp" },
|
||
"¥ " + vue.toDisplayString(Number($data.d.receivable || 0).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "备注"),
|
||
!$data.editing ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{
|
||
key: 0,
|
||
class: "value"
|
||
},
|
||
vue.toDisplayString($data.d.remark || "—"),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.withDirectives((vue.openBlock(), vue.createElementBlock(
|
||
"input",
|
||
{
|
||
key: 1,
|
||
class: "value-input",
|
||
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => $data.form.remark = $event),
|
||
placeholder: "—"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
)), [
|
||
[vue.vModelText, $data.form.remark]
|
||
])
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode(
|
||
"button",
|
||
{
|
||
class: "ghost",
|
||
onClick: _cache[9] || (_cache[9] = (...args) => $options.toggleEdit && $options.toggleEdit(...args))
|
||
},
|
||
vue.toDisplayString($data.editing ? "取消" : "编辑"),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
$data.editing ? (vue.openBlock(), vue.createElementBlock("button", {
|
||
key: 0,
|
||
class: "primary",
|
||
onClick: _cache[10] || (_cache[10] = (...args) => $options.save && $options.save(...args))
|
||
}, "保存")) : (vue.openBlock(), vue.createElementBlock("button", {
|
||
key: 1,
|
||
class: "primary",
|
||
onClick: _cache[11] || (_cache[11] = (...args) => $options.choose && $options.choose(...args))
|
||
}, "选择此客户"))
|
||
])
|
||
]);
|
||
}
|
||
const PagesCustomerDetail = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$9], ["__file", "D:/wx/PartsInquiry/frontend/pages/customer/detail.vue"]]);
|
||
const _sfc_main$9 = {
|
||
data() {
|
||
return { kw: "", debtOnly: false, suppliers: [] };
|
||
},
|
||
onLoad() {
|
||
this.search();
|
||
},
|
||
methods: {
|
||
toggleDebtOnly() {
|
||
this.debtOnly = !this.debtOnly;
|
||
this.search();
|
||
},
|
||
async search() {
|
||
try {
|
||
const res = await get("/api/suppliers", { kw: this.kw, debtOnly: this.debtOnly, page: 1, size: 50 });
|
||
this.suppliers = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
createSupplier() {
|
||
uni.navigateTo({ url: "/pages/supplier/form" });
|
||
},
|
||
select(s) {
|
||
const opener = getCurrentPages()[getCurrentPages().length - 2];
|
||
if (opener && opener.$vm) {
|
||
opener.$vm.order.supplierId = s.id;
|
||
opener.$vm.supplierName = s.name;
|
||
}
|
||
uni.navigateBack();
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "search" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.kw = $event),
|
||
placeholder: "搜索供应商名称/电话",
|
||
onConfirm: _cache[1] || (_cache[1] = (...args) => $options.search && $options.search(...args))
|
||
},
|
||
null,
|
||
544
|
||
/* NEED_HYDRATION, NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.kw]
|
||
]),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.search && $options.search(...args))
|
||
}, "搜索"),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
type: $data.debtOnly ? "primary" : "default",
|
||
onClick: _cache[3] || (_cache[3] = (...args) => $options.toggleDebtOnly && $options.toggleDebtOnly(...args))
|
||
}, "只看欠款", 8, ["type"])
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.suppliers, (s) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: s.id,
|
||
onClick: ($event) => $options.select(s)
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(s.name),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("view", { class: "meta" }, [
|
||
vue.createTextVNode(
|
||
vue.toDisplayString(s.mobile || "—") + " ",
|
||
1
|
||
/* TEXT */
|
||
),
|
||
typeof s.apPayable === "number" ? (vue.openBlock(), vue.createElementBlock(
|
||
"text",
|
||
{ key: 0 },
|
||
"|应付:¥ " + vue.toDisplayString(Number(s.apPayable).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
)) : vue.createCommentVNode("v-if", true)
|
||
])
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[4] || (_cache[4] = (...args) => $options.createSupplier && $options.createSupplier(...args))
|
||
}, "新增供应商")
|
||
])
|
||
]);
|
||
}
|
||
const PagesSupplierSelect = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$8], ["__file", "D:/wx/PartsInquiry/frontend/pages/supplier/select.vue"]]);
|
||
const _sfc_main$8 = {
|
||
data() {
|
||
return {
|
||
id: null,
|
||
form: { name: "", contactName: "", mobile: "", phone: "", address: "", apOpening: 0, apPayable: 0, remark: "" }
|
||
};
|
||
},
|
||
onLoad(query) {
|
||
if (query && query.id) {
|
||
this.id = Number(query.id);
|
||
}
|
||
},
|
||
methods: {
|
||
async save() {
|
||
if (!this.form.name)
|
||
return uni.showToast({ title: "请填写供应商名称", icon: "none" });
|
||
try {
|
||
if (this.id)
|
||
await put(`/api/suppliers/${this.id}`, this.form);
|
||
else
|
||
await post("/api/suppliers", this.form);
|
||
uni.showToast({ title: "保存成功", icon: "success" });
|
||
setTimeout(() => uni.navigateBack(), 500);
|
||
} catch (e) {
|
||
uni.showToast({ title: (e == null ? void 0 : e.message) || "保存失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "供应商名称"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.form.name = $event),
|
||
placeholder: "必填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.name]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "联系人"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.form.contactName = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.contactName]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "手机"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.form.mobile = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.mobile]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "电话"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.form.phone = $event),
|
||
placeholder: "可选(座机)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.phone]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "经营地址"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.form.address = $event),
|
||
placeholder: "可选"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.address]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "初始应付款"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.form.apOpening = $event),
|
||
placeholder: "默认 0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.apOpening,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "应付款"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "value",
|
||
type: "digit",
|
||
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => $data.form.apPayable = $event),
|
||
placeholder: "默认 0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[
|
||
vue.vModelText,
|
||
$data.form.apPayable,
|
||
void 0,
|
||
{ number: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "textarea" }, [
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"textarea",
|
||
{
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.form.remark = $event),
|
||
maxlength: "200",
|
||
placeholder: "备注(最多200字)"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.remark]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "bottom" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[8] || (_cache[8] = (...args) => $options.save && $options.save(...args))
|
||
}, "保存")
|
||
])
|
||
]);
|
||
}
|
||
const PagesSupplierForm = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$7], ["__file", "D:/wx/PartsInquiry/frontend/pages/supplier/form.vue"]]);
|
||
const TYPE_MAP = { cash: "现金", bank: "银行", alipay: "支付宝", wechat: "微信", other: "其他" };
|
||
const _sfc_main$7 = {
|
||
data() {
|
||
return { accounts: [], mode: "view" };
|
||
},
|
||
async onLoad(q) {
|
||
this.mode = q && q.mode || "view";
|
||
try {
|
||
const res = await get("/api/accounts");
|
||
this.accounts = Array.isArray(res) ? res : (res == null ? void 0 : res.list) || [];
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
methods: {
|
||
select(a) {
|
||
if (this.mode === "pick") {
|
||
const opener = getCurrentPages()[getCurrentPages().length - 2];
|
||
if (opener && opener.$vm) {
|
||
opener.$vm.selectedAccountId = a.id;
|
||
opener.$vm.selectedAccountName = a.name;
|
||
}
|
||
uni.navigateBack();
|
||
} else {
|
||
uni.navigateTo({ url: `/pages/account/ledger?id=${a.id}` });
|
||
}
|
||
},
|
||
create() {
|
||
uni.navigateTo({ url: "/pages/account/form" });
|
||
},
|
||
typeLabel(t) {
|
||
return TYPE_MAP[t] || t;
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.accounts, (a) => {
|
||
var _a;
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: a.id,
|
||
onClick: ($event) => $options.select(a)
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(a.name),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "meta" },
|
||
vue.toDisplayString($options.typeLabel(a.type)) + " · 余额:" + vue.toDisplayString(((_a = a.balance) == null ? void 0 : _a.toFixed) ? a.balance.toFixed(2) : a.balance),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "fab",
|
||
onClick: _cache[0] || (_cache[0] = (...args) => $options.create && $options.create(...args))
|
||
}, "+")
|
||
]);
|
||
}
|
||
const PagesAccountSelect = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$6], ["__file", "D:/wx/PartsInquiry/frontend/pages/account/select.vue"]]);
|
||
const _sfc_main$6 = {
|
||
data() {
|
||
return { accountId: null, startDate: "", endDate: "", list: [], opening: 0, income: 0, expense: 0, ending: 0 };
|
||
},
|
||
onLoad(query) {
|
||
this.accountId = Number(query && query.id);
|
||
this.quickInit();
|
||
this.load();
|
||
},
|
||
methods: {
|
||
quickInit() {
|
||
const now = /* @__PURE__ */ new Date();
|
||
const y = now.getFullYear(), m = now.getMonth() + 1;
|
||
this.startDate = `${y}-${String(m).padStart(2, "0")}-01`;
|
||
const lastDay = new Date(y, m, 0).getDate();
|
||
this.endDate = `${y}-${String(m).padStart(2, "0")}-${String(lastDay).padStart(2, "0")}`;
|
||
},
|
||
async load(page = 1, size = 50) {
|
||
try {
|
||
const res = await get(`/api/accounts/${this.accountId}/ledger`, { startDate: this.startDate, endDate: this.endDate, page, size });
|
||
this.list = res && res.list || [];
|
||
this.opening = Number(res && res.opening || 0);
|
||
this.income = Number(res && res.income || 0);
|
||
this.expense = Number(res && res.expense || 0);
|
||
this.ending = Number(res && res.ending || 0);
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
fmt(v) {
|
||
return (typeof v === "number" ? v : Number(v || 0)).toFixed(2);
|
||
},
|
||
formatDate(s) {
|
||
if (!s)
|
||
return "-";
|
||
try {
|
||
const d = new Date(s);
|
||
const pad = (n) => String(n).padStart(2, "0");
|
||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||
} catch (e) {
|
||
return s;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "filters" }, [
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.startDate,
|
||
onChange: _cache[0] || (_cache[0] = (e) => {
|
||
$data.startDate = e.detail.value;
|
||
$options.load();
|
||
})
|
||
}, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "开始"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($data.startDate || "—"),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
], 40, ["value"]),
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.endDate,
|
||
onChange: _cache[1] || (_cache[1] = (e) => {
|
||
$data.endDate = e.detail.value;
|
||
$options.load();
|
||
})
|
||
}, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "结束"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($data.endDate || "—"),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
], 40, ["value"])
|
||
]),
|
||
vue.createElementVNode("view", { class: "summary" }, [
|
||
vue.createElementVNode("view", { class: "sum-item" }, [
|
||
vue.createElementVNode("text", { class: "k" }, "收入"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "v" },
|
||
vue.toDisplayString($options.fmt($data.income)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "sum-item" }, [
|
||
vue.createElementVNode("text", { class: "k" }, "支出"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "v" },
|
||
vue.toDisplayString($options.fmt($data.expense)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "sum-item" }, [
|
||
vue.createElementVNode("text", { class: "k" }, "期初"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "v" },
|
||
vue.toDisplayString($options.fmt($data.opening)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "sum-item" }, [
|
||
vue.createElementVNode("text", { class: "k" }, "期末"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "v" },
|
||
vue.toDisplayString($options.fmt($data.ending)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
]),
|
||
vue.createElementVNode("scroll-view", {
|
||
"scroll-y": "",
|
||
class: "list"
|
||
}, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.list, (it) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: it.id
|
||
}, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "title" },
|
||
vue.toDisplayString(it.src === "other" ? it.category || "其他" : it.remark || "收付款"),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{
|
||
class: vue.normalizeClass(["amount", { in: it.direction === "in", out: it.direction === "out" }])
|
||
},
|
||
vue.toDisplayString(it.direction === "in" ? "+" : "-") + vue.toDisplayString($options.fmt(it.amount)),
|
||
3
|
||
/* TEXT, CLASS */
|
||
)
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "meta" },
|
||
vue.toDisplayString($options.formatDate(it.tx_time || it.txTime)) + " · " + vue.toDisplayString(it.remark || "-"),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
])
|
||
]);
|
||
}
|
||
const PagesAccountLedger = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$5], ["__file", "D:/wx/PartsInquiry/frontend/pages/account/ledger.vue"]]);
|
||
const _sfc_main$5 = {
|
||
data() {
|
||
return {
|
||
id: null,
|
||
form: { name: "", type: "cash", bankName: "", bankAccount: "", openingBalance: "" },
|
||
showType: false,
|
||
types: [
|
||
{ key: "cash", name: "现金" },
|
||
{ key: "bank", name: "银行存款" },
|
||
{ key: "wechat", name: "微信" },
|
||
{ key: "alipay", name: "支付宝" },
|
||
{ key: "other", name: "其他" }
|
||
]
|
||
};
|
||
},
|
||
onLoad(q) {
|
||
this.id = q && q.id ? Number(q.id) : null;
|
||
if (this.id)
|
||
this.load();
|
||
},
|
||
methods: {
|
||
typeLabel(t) {
|
||
const m = { cash: "现金", bank: "银行存款", wechat: "微信", alipay: "支付宝", other: "其他" };
|
||
return m[t] || t;
|
||
},
|
||
async load() {
|
||
try {
|
||
const list = await get("/api/accounts");
|
||
const a = (Array.isArray(list) ? list : (list == null ? void 0 : list.list) || []).find((x) => x.id == this.id);
|
||
if (a) {
|
||
this.form = { name: a.name, type: a.type, bankName: a.bank_name || a.bankName || "", bankAccount: a.bank_account || a.bankAccount || "", openingBalance: "" };
|
||
}
|
||
} catch (e) {
|
||
}
|
||
},
|
||
async save() {
|
||
if (!this.form.name) {
|
||
uni.showToast({ title: "请输入名称", icon: "none" });
|
||
return;
|
||
}
|
||
try {
|
||
const body = { ...this.form, openingBalance: Number(this.form.openingBalance || 0) };
|
||
if (this.id)
|
||
await put(`/api/accounts/${this.id}`, body);
|
||
else
|
||
await post("/api/accounts", { ...body, status: 1 });
|
||
uni.showToast({ title: "已保存", icon: "success" });
|
||
setTimeout(() => uni.navigateBack(), 300);
|
||
} catch (e) {
|
||
uni.showToast({ title: "保存失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
||
const _component_uni_popup = vue.resolveComponent("uni-popup");
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createElementVNode("view", { class: "form" }, [
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "账户名称"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "input",
|
||
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.form.name = $event),
|
||
placeholder: "必填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.name]
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "field",
|
||
onClick: _cache[1] || (_cache[1] = ($event) => $data.showType = true)
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "账户类型"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.typeLabel($data.form.type)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
$data.form.type === "bank" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "field"
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "银行名称"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "input",
|
||
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.form.bankName = $event),
|
||
placeholder: "选填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.bankName]
|
||
])
|
||
])) : vue.createCommentVNode("v-if", true),
|
||
$data.form.type === "bank" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "field"
|
||
}, [
|
||
vue.createElementVNode("text", { class: "label" }, "银行账号"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "input",
|
||
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.form.bankAccount = $event),
|
||
placeholder: "选填"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.bankAccount]
|
||
])
|
||
])) : vue.createCommentVNode("v-if", true),
|
||
vue.createElementVNode("view", { class: "field" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "当前余额"),
|
||
vue.withDirectives(vue.createElementVNode(
|
||
"input",
|
||
{
|
||
class: "input",
|
||
type: "number",
|
||
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => $data.form.openingBalance = $event),
|
||
placeholder: "0.00"
|
||
},
|
||
null,
|
||
512
|
||
/* NEED_PATCH */
|
||
), [
|
||
[vue.vModelText, $data.form.openingBalance]
|
||
])
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "actions" }, [
|
||
vue.createElementVNode("button", {
|
||
class: "primary",
|
||
onClick: _cache[5] || (_cache[5] = (...args) => $options.save && $options.save(...args))
|
||
}, "保存")
|
||
]),
|
||
vue.createVNode(_component_uni_popup, {
|
||
ref: "popup",
|
||
type: "bottom",
|
||
modelValue: $data.showType,
|
||
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => $data.showType = $event)
|
||
}, {
|
||
default: vue.withCtx(() => [
|
||
vue.createElementVNode("view", { class: "sheet" }, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.types, (t) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "sheet-item",
|
||
key: t.key,
|
||
onClick: ($event) => {
|
||
$data.form.type = t.key;
|
||
$data.showType = false;
|
||
}
|
||
}, vue.toDisplayString(t.name), 9, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
)),
|
||
vue.createElementVNode("view", {
|
||
class: "sheet-cancel",
|
||
onClick: _cache[6] || (_cache[6] = ($event) => $data.showType = false)
|
||
}, "取消")
|
||
])
|
||
]),
|
||
_: 1
|
||
/* STABLE */
|
||
}, 8, ["modelValue"])
|
||
]);
|
||
}
|
||
const PagesAccountForm = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$4], ["__file", "D:/wx/PartsInquiry/frontend/pages/account/form.vue"]]);
|
||
const API_OF = {
|
||
sale: "/api/orders",
|
||
purchase: "/api/purchase-orders",
|
||
collect: "/api/payments",
|
||
fund: "/api/other-transactions",
|
||
stock: "/api/inventories/logs"
|
||
};
|
||
const _sfc_main$4 = {
|
||
data() {
|
||
return {
|
||
biz: "sale",
|
||
bizList: [
|
||
{ key: "sale", name: "出货" },
|
||
{ key: "purchase", name: "进货" },
|
||
{ key: "collect", name: "收款" },
|
||
{ key: "fund", name: "资金" },
|
||
{ key: "stock", name: "盘点" }
|
||
],
|
||
range: "month",
|
||
query: { kw: "" },
|
||
items: [],
|
||
page: 1,
|
||
size: 20,
|
||
finished: false,
|
||
loading: false,
|
||
startDate: "",
|
||
endDate: ""
|
||
};
|
||
},
|
||
computed: {
|
||
placeholder() {
|
||
return "单据号/客户名称/品名规格/备注";
|
||
},
|
||
periodLabel() {
|
||
return this.startDate && this.endDate ? `${this.startDate}~${this.endDate}` : "";
|
||
},
|
||
totalAmount() {
|
||
return this.items.reduce((s, it) => s + Number(it.amount || 0), 0);
|
||
}
|
||
},
|
||
onLoad() {
|
||
try {
|
||
formatAppLog("log", "at pages/detail/index.vue:92", "[detail] onLoad route = pages/detail/index");
|
||
} catch (e) {
|
||
}
|
||
this.computeRange();
|
||
this.reload();
|
||
},
|
||
methods: {
|
||
switchBiz(k) {
|
||
if (this.biz === k)
|
||
return;
|
||
this.biz = k;
|
||
this.reload();
|
||
},
|
||
switchRange(r) {
|
||
this.range = r;
|
||
this.computeRange();
|
||
this.reload();
|
||
},
|
||
computeRange() {
|
||
const now = /* @__PURE__ */ new Date();
|
||
const pad = (n) => String(n).padStart(2, "0");
|
||
const fmt = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
||
let start = now, end = now;
|
||
if (this.range === "today") {
|
||
start = end = now;
|
||
} else if (this.range === "week") {
|
||
const day = now.getDay() || 7;
|
||
start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - day + 1);
|
||
end = now;
|
||
} else if (this.range === "month") {
|
||
start = new Date(now.getFullYear(), now.getMonth(), 1);
|
||
end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
||
} else if (this.range === "year") {
|
||
start = new Date(now.getFullYear(), 0, 1);
|
||
end = new Date(now.getFullYear(), 11, 31);
|
||
} else {
|
||
start = new Date(now.getFullYear(), now.getMonth(), 1);
|
||
end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
||
}
|
||
this.startDate = fmt(start);
|
||
this.endDate = fmt(end);
|
||
},
|
||
reload() {
|
||
this.items = [];
|
||
this.page = 1;
|
||
this.finished = false;
|
||
this.loadMore();
|
||
},
|
||
async loadMore() {
|
||
if (this.loading || this.finished)
|
||
return;
|
||
this.loading = true;
|
||
try {
|
||
const path = API_OF[this.biz] || "/api/orders";
|
||
const params = { kw: this.query.kw, page: this.page, size: this.size, startDate: this.startDate, endDate: this.endDate, biz: this.biz };
|
||
if (this.biz === "sale")
|
||
params.type = "out";
|
||
const res = await get(path, params);
|
||
const list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
this.items = this.items.concat(list);
|
||
if (list.length < this.size)
|
||
this.finished = true;
|
||
this.page += 1;
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
formatDate(s) {
|
||
if (!s)
|
||
return "";
|
||
try {
|
||
const d = new Date(s);
|
||
const pad = (n) => String(n).padStart(2, "0");
|
||
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
||
} catch (_) {
|
||
return String(s).slice(0, 10);
|
||
}
|
||
},
|
||
onCreate() {
|
||
if (this.biz === "sale") {
|
||
uni.switchTab({ url: "/pages/order/create" });
|
||
return;
|
||
}
|
||
uni.showToast({ title: "该类型创建页待实现", icon: "none" });
|
||
},
|
||
openDetail(it) {
|
||
uni.showToast({ title: "详情开发中", icon: "none" });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "page" }, [
|
||
vue.createCommentVNode(" 顶部时间维度筛选 "),
|
||
vue.createElementVNode("view", { class: "seg" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["seg-item", $data.range === "custom" && "active"]),
|
||
onClick: _cache[0] || (_cache[0] = ($event) => $options.switchRange("custom"))
|
||
},
|
||
"自定义",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["seg-item", $data.range === "week" && "active"]),
|
||
onClick: _cache[1] || (_cache[1] = ($event) => $options.switchRange("week"))
|
||
},
|
||
"本周",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["seg-item", $data.range === "today" && "active"]),
|
||
onClick: _cache[2] || (_cache[2] = ($event) => $options.switchRange("today"))
|
||
},
|
||
"今日",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["seg-item", $data.range === "month" && "active"]),
|
||
onClick: _cache[3] || (_cache[3] = ($event) => $options.switchRange("month"))
|
||
},
|
||
"本月",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["seg-item", $data.range === "year" && "active"]),
|
||
onClick: _cache[4] || (_cache[4] = ($event) => $options.switchRange("year"))
|
||
},
|
||
"本年",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
]),
|
||
vue.createCommentVNode(" 业务类型侧边切换:销售/进货/收款/资金/盘点 "),
|
||
vue.createElementVNode("view", { class: "content" }, [
|
||
vue.createElementVNode("view", { class: "biz-tabs" }, [
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.bizList, (b) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
key: b.key,
|
||
class: vue.normalizeClass(["biz", $data.biz === b.key && "active"]),
|
||
onClick: ($event) => $options.switchBiz(b.key)
|
||
}, vue.toDisplayString(b.name), 11, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]),
|
||
vue.createElementVNode("view", { class: "panel" }, [
|
||
vue.createCommentVNode(" 搜索框与期间显示、总额 "),
|
||
vue.createElementVNode("view", { class: "toolbar" }, [
|
||
vue.createElementVNode("view", { class: "search" }, [
|
||
vue.withDirectives(vue.createElementVNode("input", {
|
||
class: "search-input",
|
||
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => $data.query.kw = $event),
|
||
placeholder: $options.placeholder,
|
||
onConfirm: _cache[6] || (_cache[6] = (...args) => $options.reload && $options.reload(...args))
|
||
}, null, 40, ["placeholder"]), [
|
||
[
|
||
vue.vModelText,
|
||
$data.query.kw,
|
||
void 0,
|
||
{ trim: true }
|
||
]
|
||
])
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "period" },
|
||
vue.toDisplayString($options.periodLabel),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("button", {
|
||
size: "mini",
|
||
onClick: _cache[7] || (_cache[7] = (...args) => $options.reload && $options.reload(...args))
|
||
}, "查询")
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "total" },
|
||
"合计:¥" + vue.toDisplayString($options.totalAmount.toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createCommentVNode(" 列表 "),
|
||
vue.createElementVNode(
|
||
"scroll-view",
|
||
{
|
||
"scroll-y": "",
|
||
class: "list",
|
||
onScrolltolower: _cache[8] || (_cache[8] = (...args) => $options.loadMore && $options.loadMore(...args))
|
||
},
|
||
[
|
||
$data.items.length ? (vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
{ key: 0 },
|
||
vue.renderList($data.items, (it) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
class: "item",
|
||
key: it.id,
|
||
onClick: ($event) => $options.openDetail(it)
|
||
}, [
|
||
vue.createElementVNode("view", { class: "item-left" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "date" },
|
||
vue.toDisplayString($options.formatDate(it.orderTime || it.txTime || it.createdAt)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "name" },
|
||
vue.toDisplayString(it.customerName || it.supplierName || it.accountName || it.remark || "-"),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "no" },
|
||
vue.toDisplayString(it.orderNo || it.code || it.id),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "amount" },
|
||
"¥ " + vue.toDisplayString((it.amount || 0).toFixed(2)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("view", { class: "arrow" }, "›")
|
||
], 8, ["onClick"]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
)) : (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "empty"
|
||
}, "暂无数据"))
|
||
],
|
||
32
|
||
/* NEED_HYDRATION */
|
||
),
|
||
vue.createCommentVNode(" 右下角新增按钮:根据业务类型跳转对应开单页或创建页 "),
|
||
vue.createElementVNode("view", {
|
||
class: "fab",
|
||
onClick: _cache[9] || (_cache[9] = (...args) => $options.onCreate && $options.onCreate(...args))
|
||
}, "+")
|
||
])
|
||
])
|
||
]);
|
||
}
|
||
const PagesDetailIndex = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$3], ["__file", "D:/wx/PartsInquiry/frontend/pages/detail/index.vue"]]);
|
||
const _sfc_main$3 = {
|
||
data() {
|
||
return {
|
||
avatarUrl: "/static/logo.png",
|
||
shopName: "我的店铺",
|
||
mobile: ""
|
||
};
|
||
},
|
||
onLoad() {
|
||
this.fetchProfile();
|
||
},
|
||
computed: {
|
||
mobileDisplay() {
|
||
const m = String(this.mobile || "");
|
||
return m.length === 11 ? m.slice(0, 3) + "****" + m.slice(7) : m || "未绑定手机号";
|
||
}
|
||
},
|
||
methods: {
|
||
async fetchProfile() {
|
||
try {
|
||
await get("/api/dashboard/overview");
|
||
} catch (e) {
|
||
}
|
||
try {
|
||
const storeName = uni.getStorageSync("SHOP_NAME") || "";
|
||
const avatar = uni.getStorageSync("USER_AVATAR") || "";
|
||
const phone = uni.getStorageSync("USER_MOBILE") || "";
|
||
if (storeName)
|
||
this.shopName = storeName;
|
||
if (avatar)
|
||
this.avatarUrl = avatar;
|
||
this.mobile = phone;
|
||
} catch (e) {
|
||
}
|
||
},
|
||
onAvatarError() {
|
||
this.avatarUrl = "/static/logo.png";
|
||
},
|
||
goVip() {
|
||
uni.showToast({ title: "VIP会员(开发中)", icon: "none" });
|
||
},
|
||
goMyOrders() {
|
||
uni.switchTab({ url: "/pages/detail/index" });
|
||
},
|
||
goSupplier() {
|
||
uni.navigateTo({ url: "/pages/supplier/select" });
|
||
},
|
||
goCustomer() {
|
||
uni.navigateTo({ url: "/pages/customer/select" });
|
||
},
|
||
goCustomerQuote() {
|
||
uni.showToast({ title: "客户报价(开发中)", icon: "none" });
|
||
},
|
||
goShop() {
|
||
uni.showToast({ title: "店铺管理(开发中)", icon: "none" });
|
||
},
|
||
editProfile() {
|
||
uni.showToast({ title: "账号与安全(开发中)", icon: "none" });
|
||
},
|
||
goProductSettings() {
|
||
uni.navigateTo({ url: "/pages/product/settings" });
|
||
},
|
||
goSystemParams() {
|
||
uni.showToast({ title: "系统参数(开发中)", icon: "none" });
|
||
},
|
||
goAbout() {
|
||
uni.navigateTo({ url: "/pages/my/about" });
|
||
},
|
||
logout() {
|
||
try {
|
||
uni.removeStorageSync("TOKEN");
|
||
uni.removeStorageSync("USER_AVATAR");
|
||
uni.removeStorageSync("USER_NAME");
|
||
uni.removeStorageSync("USER_MOBILE");
|
||
uni.removeStorageSync("SHOP_NAME");
|
||
uni.showToast({ title: "已退出", icon: "none" });
|
||
setTimeout(() => {
|
||
uni.reLaunch({ url: "/pages/index/index" });
|
||
}, 300);
|
||
} catch (e) {
|
||
uni.reLaunch({ url: "/pages/index/index" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "me" }, [
|
||
vue.createElementVNode("view", { class: "card user" }, [
|
||
vue.createElementVNode("image", {
|
||
class: "avatar",
|
||
src: $data.avatarUrl,
|
||
mode: "aspectFill",
|
||
onError: _cache[0] || (_cache[0] = (...args) => $options.onAvatarError && $options.onAvatarError(...args))
|
||
}, null, 40, ["src"]),
|
||
vue.createElementVNode("view", { class: "meta" }, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "name" },
|
||
vue.toDisplayString($data.shopName),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "phone" },
|
||
vue.toDisplayString($options.mobileDisplay),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode("text", { class: "role" }, "老板")
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "group" }, [
|
||
vue.createElementVNode("view", { class: "group-title" }, "会员与订单"),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[1] || (_cache[1] = (...args) => $options.goVip && $options.goVip(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "VIP会员"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.goMyOrders && $options.goMyOrders(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "我的订单"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "group" }, [
|
||
vue.createElementVNode("view", { class: "group-title" }, "基础管理"),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[3] || (_cache[3] = (...args) => $options.goSupplier && $options.goSupplier(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "供应商管理"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[4] || (_cache[4] = (...args) => $options.goCustomer && $options.goCustomer(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "客户管理"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[5] || (_cache[5] = (...args) => $options.goCustomerQuote && $options.goCustomerQuote(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "客户报价"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[6] || (_cache[6] = (...args) => $options.goShop && $options.goShop(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "店铺管理"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
])
|
||
]),
|
||
vue.createElementVNode("view", { class: "group" }, [
|
||
vue.createElementVNode("view", { class: "group-title" }, "设置中心"),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[7] || (_cache[7] = (...args) => $options.editProfile && $options.editProfile(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "账号与安全"),
|
||
vue.createElementVNode("text", { class: "desc" }, "修改头像、姓名、密码"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[8] || (_cache[8] = (...args) => $options.goProductSettings && $options.goProductSettings(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "商品设置"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[9] || (_cache[9] = (...args) => $options.goSystemParams && $options.goSystemParams(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "系统参数"),
|
||
vue.createElementVNode("text", { class: "desc" }, "低价提示、默认收款、单行折扣等"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell",
|
||
onClick: _cache[10] || (_cache[10] = (...args) => $options.goAbout && $options.goAbout(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "关于与协议"),
|
||
vue.createElementVNode("text", { class: "arrow" }, "›")
|
||
]),
|
||
vue.createElementVNode("view", {
|
||
class: "cell danger",
|
||
onClick: _cache[11] || (_cache[11] = (...args) => $options.logout && $options.logout(...args))
|
||
}, [
|
||
vue.createElementVNode("text", null, "退出登录")
|
||
])
|
||
])
|
||
]);
|
||
}
|
||
const PagesMyIndex = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__file", "D:/wx/PartsInquiry/frontend/pages/my/index.vue"]]);
|
||
const _sfc_main$2 = {
|
||
methods: {
|
||
openPolicy() {
|
||
uni.showModal({ title: "隐私协议", content: "隐私协议(静态占位)", showCancel: false });
|
||
},
|
||
openTerms() {
|
||
uni.showModal({ title: "用户协议", content: "用户协议(静态占位)", showCancel: false });
|
||
},
|
||
openComplaint() {
|
||
uni.showToast({ title: "暂未开通", icon: "none" });
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "about" }, [
|
||
vue.createElementVNode("view", { class: "hero" }, [
|
||
vue.createElementVNode("image", {
|
||
class: "logo",
|
||
src: _imports_0,
|
||
mode: "aspectFit"
|
||
}),
|
||
vue.createElementVNode("text", { class: "title" }, "五金配件管家"),
|
||
vue.createElementVNode("text", { class: "subtitle" }, "专注小微门店的极简进销存")
|
||
]),
|
||
vue.createElementVNode("view", { class: "card" }, [
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "版本"),
|
||
vue.createElementVNode("text", { class: "value" }, "1.0.0")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "隐私协议"),
|
||
vue.createElementVNode("text", {
|
||
class: "link",
|
||
onClick: _cache[0] || (_cache[0] = (...args) => $options.openPolicy && $options.openPolicy(...args))
|
||
}, "查看")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "用户协议"),
|
||
vue.createElementVNode("text", {
|
||
class: "link",
|
||
onClick: _cache[1] || (_cache[1] = (...args) => $options.openTerms && $options.openTerms(...args))
|
||
}, "查看")
|
||
]),
|
||
vue.createElementVNode("view", { class: "row" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "个人信息安全投诉"),
|
||
vue.createElementVNode("text", {
|
||
class: "link",
|
||
onClick: _cache[2] || (_cache[2] = (...args) => $options.openComplaint && $options.openComplaint(...args))
|
||
}, "提交")
|
||
])
|
||
])
|
||
]);
|
||
}
|
||
const PagesMyAbout = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__file", "D:/wx/PartsInquiry/frontend/pages/my/about.vue"]]);
|
||
function formatDate(d) {
|
||
const y = d.getFullYear();
|
||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||
const day = String(d.getDate()).padStart(2, "0");
|
||
return `${y}-${m}-${day}`;
|
||
}
|
||
const _sfc_main$1 = {
|
||
data() {
|
||
const now = /* @__PURE__ */ new Date();
|
||
const start = new Date(now.getFullYear(), now.getMonth(), 1);
|
||
return {
|
||
startDate: formatDate(start),
|
||
endDate: formatDate(now),
|
||
mode: "sale",
|
||
dim: "customer",
|
||
rows: [],
|
||
total: { sales: 0, cost: 0, profit: 0 }
|
||
};
|
||
},
|
||
onLoad(query) {
|
||
try {
|
||
const m = query && query.mode;
|
||
const d = query && query.dim;
|
||
if (m)
|
||
this.mode = m;
|
||
if (d)
|
||
this.dim = d;
|
||
} catch (e) {
|
||
}
|
||
this.refresh();
|
||
},
|
||
computed: {
|
||
profitRate() {
|
||
const { sales, profit } = this.total;
|
||
if (!sales)
|
||
return "0.00%";
|
||
return (profit / sales * 100).toFixed(2) + "%";
|
||
}
|
||
},
|
||
methods: {
|
||
fmt(n) {
|
||
return Number(n || 0).toFixed(2);
|
||
},
|
||
setMode(m) {
|
||
this.mode = m;
|
||
this.dim = m === "sale" ? "customer" : m === "purchase" ? "supplier" : m === "inventory" ? "qty" : "ar";
|
||
this.refresh();
|
||
},
|
||
onStartChange(e) {
|
||
this.startDate = e.detail.value;
|
||
this.refresh();
|
||
},
|
||
onEndChange(e) {
|
||
this.endDate = e.detail.value;
|
||
this.refresh();
|
||
},
|
||
async refresh() {
|
||
if (this.mode === "sale") {
|
||
if (this.dim === "customer")
|
||
return this.loadByCustomer();
|
||
if (this.dim === "product")
|
||
return this.loadByProduct();
|
||
}
|
||
if (this.mode === "purchase") {
|
||
if (this.dim === "supplier")
|
||
return this.loadPurchaseBySupplier();
|
||
if (this.dim === "product")
|
||
return this.loadPurchaseByProduct();
|
||
}
|
||
if (this.mode === "inventory") {
|
||
if (this.dim === "qty")
|
||
return this.loadInventoryByQty();
|
||
if (this.dim === "amount")
|
||
return this.loadInventoryByAmount();
|
||
}
|
||
if (this.mode === "arap") {
|
||
if (this.dim === "ar")
|
||
return this.loadAR();
|
||
if (this.dim === "ap")
|
||
return this.loadAP();
|
||
}
|
||
},
|
||
async loadByCustomer() {
|
||
try {
|
||
const listResp = await get("/api/orders", { biz: "sale", type: "out", startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = listResp && (listResp.list || listResp) || [];
|
||
const map = /* @__PURE__ */ new Map();
|
||
let totalSales = 0;
|
||
for (const it of list) {
|
||
const name = it.customerName || "未知客户";
|
||
const amount = Number(it.amount || 0);
|
||
totalSales += amount;
|
||
if (!map.has(name))
|
||
map.set(name, { name, sales: 0, cost: 0, profit: 0 });
|
||
const row = map.get(name);
|
||
row.sales += amount;
|
||
}
|
||
const rows = Array.from(map.values()).map((r) => ({ ...r, profit: r.sales - r.cost }));
|
||
const total = { sales: totalSales, cost: 0, profit: totalSales };
|
||
this.rows = rows;
|
||
this.total = total;
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadByProduct() {
|
||
try {
|
||
const listResp = await get("/api/orders", { biz: "sale", type: "out", startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = listResp && (listResp.list || listResp) || [];
|
||
const agg = /* @__PURE__ */ new Map();
|
||
for (const it of list) {
|
||
try {
|
||
const d = await get(`/api/orders/${it.id}`);
|
||
const items = d && d.items || [];
|
||
for (const m of items) {
|
||
const key = String(m.productId || m.name);
|
||
if (!agg.has(key))
|
||
agg.set(key, { name: m.name || "#" + key, sales: 0, cost: 0, profit: 0 });
|
||
const row = agg.get(key);
|
||
const sales = Number(m.amount || 0);
|
||
row.sales += sales;
|
||
}
|
||
} catch (_) {
|
||
}
|
||
}
|
||
const rows = Array.from(agg.values()).map((r) => ({ ...r, profit: r.sales - r.cost }));
|
||
const totalSales = rows.reduce((s, r) => s + r.sales, 0);
|
||
this.rows = rows;
|
||
this.total = { sales: totalSales, cost: 0, profit: totalSales };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadPurchaseBySupplier() {
|
||
try {
|
||
const listResp = await get("/api/purchase-orders", { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = listResp && (listResp.list || listResp) || [];
|
||
const map = /* @__PURE__ */ new Map();
|
||
let total = 0;
|
||
for (const it of list) {
|
||
const name = it.supplierName || "未知供应商";
|
||
const amount = Number(it.amount || 0);
|
||
total += amount;
|
||
if (!map.has(name))
|
||
map.set(name, { name, sales: 0, cost: 0, profit: 0 });
|
||
const row = map.get(name);
|
||
row.sales += amount;
|
||
}
|
||
this.rows = Array.from(map.values());
|
||
this.total = { sales: total, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadPurchaseByProduct() {
|
||
try {
|
||
const listResp = await get("/api/purchase-orders", { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = listResp && (listResp.list || listResp) || [];
|
||
const agg = /* @__PURE__ */ new Map();
|
||
for (const it of list) {
|
||
try {
|
||
const d = await get(`/api/purchase-orders/${it.id}`);
|
||
for (const m of (d == null ? void 0 : d.items) || []) {
|
||
const key = String(m.productId || m.name);
|
||
if (!agg.has(key))
|
||
agg.set(key, { name: m.name || "#" + key, sales: 0, cost: 0, profit: 0 });
|
||
const row = agg.get(key);
|
||
row.sales += Number(m.amount || 0);
|
||
}
|
||
} catch (_) {
|
||
}
|
||
}
|
||
const rows = Array.from(agg.values());
|
||
const total = rows.reduce((s, r) => s + r.sales, 0);
|
||
this.rows = rows;
|
||
this.total = { sales: total, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadInventoryByQty() {
|
||
try {
|
||
const resp = await get("/api/inventories/logs", { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = resp && (resp.list || resp) || [];
|
||
const map = /* @__PURE__ */ new Map();
|
||
let totalQty = 0;
|
||
for (const it of list) {
|
||
const key = it.productId || "未知";
|
||
if (!map.has(key))
|
||
map.set(key, { name: String(key), sales: 0, cost: 0, profit: 0 });
|
||
const row = map.get(key);
|
||
const q = Number(it.qtyDelta || 0);
|
||
row.sales += q;
|
||
totalQty += q;
|
||
}
|
||
this.rows = Array.from(map.values());
|
||
this.total = { sales: totalQty, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadInventoryByAmount() {
|
||
try {
|
||
const resp = await get("/api/inventories/logs", { startDate: this.startDate, endDate: this.endDate, page: 1, size: 200 });
|
||
const list = resp && (resp.list || resp) || [];
|
||
const map = /* @__PURE__ */ new Map();
|
||
let totalAmt = 0;
|
||
for (const it of list) {
|
||
const key = it.productId || "未知";
|
||
if (!map.has(key))
|
||
map.set(key, { name: String(key), sales: 0, cost: 0, profit: 0 });
|
||
const row = map.get(key);
|
||
const a = Number(it.amount || it.amountDelta || 0);
|
||
row.sales += a;
|
||
totalAmt += a;
|
||
}
|
||
this.rows = Array.from(map.values());
|
||
this.total = { sales: totalAmt, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadAR() {
|
||
try {
|
||
const res = await get("/api/customers", { page: 1, size: 100, debtOnly: false });
|
||
const list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
const rows = list.map((c) => ({ name: c.name, sales: Number(c.receivable || 0), cost: 0, profit: 0 }));
|
||
const total = rows.reduce((s, r) => s + r.sales, 0);
|
||
this.rows = rows;
|
||
this.total = { sales: total, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
},
|
||
async loadAP() {
|
||
try {
|
||
const res = await get("/api/suppliers", { page: 1, size: 100 });
|
||
const list = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||
const rows = list.map((s) => ({ name: s.name, sales: Number(s.apPayable || 0), cost: 0, profit: 0 }));
|
||
const total = rows.reduce((s, r) => s + r.sales, 0);
|
||
this.rows = rows;
|
||
this.total = { sales: total, cost: 0, profit: 0 };
|
||
} catch (e) {
|
||
uni.showToast({ title: "加载失败", icon: "none" });
|
||
}
|
||
}
|
||
}
|
||
};
|
||
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||
return vue.openBlock(), vue.createElementBlock("view", { class: "report" }, [
|
||
vue.createElementVNode("view", { class: "modes" }, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["mode-tab", { active: $data.mode === "sale" }]),
|
||
onClick: _cache[0] || (_cache[0] = ($event) => $options.setMode("sale"))
|
||
},
|
||
"销售统计",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["mode-tab", { active: $data.mode === "purchase" }]),
|
||
onClick: _cache[1] || (_cache[1] = ($event) => $options.setMode("purchase"))
|
||
},
|
||
"进货统计",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["mode-tab", { active: $data.mode === "inventory" }]),
|
||
onClick: _cache[2] || (_cache[2] = ($event) => $options.setMode("inventory"))
|
||
},
|
||
"库存统计",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["mode-tab", { active: $data.mode === "arap" }]),
|
||
onClick: _cache[3] || (_cache[3] = ($event) => $options.setMode("arap"))
|
||
},
|
||
"应收/应付对账",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "toolbar" }, [
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.startDate,
|
||
onChange: _cache[4] || (_cache[4] = (...args) => $options.onStartChange && $options.onStartChange(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "date" },
|
||
vue.toDisplayString($data.startDate),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["value"]),
|
||
vue.createElementVNode("text", { style: { "margin": "0 8rpx" } }, "—"),
|
||
vue.createElementVNode("picker", {
|
||
mode: "date",
|
||
value: $data.endDate,
|
||
onChange: _cache[5] || (_cache[5] = (...args) => $options.onEndChange && $options.onEndChange(...args))
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "date" },
|
||
vue.toDisplayString($data.endDate),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
], 40, ["value"])
|
||
]),
|
||
$data.mode === "sale" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 0,
|
||
class: "tabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "customer" }]),
|
||
onClick: _cache[6] || (_cache[6] = ($event) => {
|
||
$data.dim = "customer";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按客户",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "product" }]),
|
||
onClick: _cache[7] || (_cache[7] = ($event) => {
|
||
$data.dim = "product";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按货品",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : $data.mode === "purchase" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 1,
|
||
class: "tabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "supplier" }]),
|
||
onClick: _cache[8] || (_cache[8] = ($event) => {
|
||
$data.dim = "supplier";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按供应商",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "product" }]),
|
||
onClick: _cache[9] || (_cache[9] = ($event) => {
|
||
$data.dim = "product";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按货品",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : $data.mode === "inventory" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 2,
|
||
class: "tabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "qty" }]),
|
||
onClick: _cache[10] || (_cache[10] = ($event) => {
|
||
$data.dim = "qty";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按数量",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "amount" }]),
|
||
onClick: _cache[11] || (_cache[11] = ($event) => {
|
||
$data.dim = "amount";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"按金额",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : $data.mode === "arap" ? (vue.openBlock(), vue.createElementBlock("view", {
|
||
key: 3,
|
||
class: "tabs"
|
||
}, [
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "ar" }]),
|
||
onClick: _cache[12] || (_cache[12] = ($event) => {
|
||
$data.dim = "ar";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"应收对账",
|
||
2
|
||
/* CLASS */
|
||
),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{
|
||
class: vue.normalizeClass(["tab", { active: $data.dim === "ap" }]),
|
||
onClick: _cache[13] || (_cache[13] = ($event) => {
|
||
$data.dim = "ap";
|
||
$options.refresh();
|
||
})
|
||
},
|
||
"应付对账",
|
||
2
|
||
/* CLASS */
|
||
)
|
||
])) : vue.createCommentVNode("v-if", true),
|
||
vue.createElementVNode("view", { class: "summary" }, [
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "销售额"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
"¥ " + vue.toDisplayString($options.fmt($data.total.sales)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "成本"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
"¥ " + vue.toDisplayString($options.fmt($data.total.cost)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "利润"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
"¥ " + vue.toDisplayString($options.fmt($data.total.profit)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "item" }, [
|
||
vue.createElementVNode("text", { class: "label" }, "利润率"),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ class: "value" },
|
||
vue.toDisplayString($options.profitRate),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
]),
|
||
(vue.openBlock(true), vue.createElementBlock(
|
||
vue.Fragment,
|
||
null,
|
||
vue.renderList($data.rows, (row, idx) => {
|
||
return vue.openBlock(), vue.createElementBlock("view", {
|
||
key: idx,
|
||
class: "card"
|
||
}, [
|
||
vue.createElementVNode("view", { class: "row-head" }, [
|
||
row.avatar ? (vue.openBlock(), vue.createElementBlock("image", {
|
||
key: 0,
|
||
class: "thumb",
|
||
src: row.avatar
|
||
}, null, 8, ["src"])) : vue.createCommentVNode("v-if", true),
|
||
vue.createElementVNode(
|
||
"view",
|
||
{ class: "title" },
|
||
vue.toDisplayString(row.name),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
]),
|
||
vue.createElementVNode("view", { class: "row-body" }, [
|
||
vue.createElementVNode(
|
||
"text",
|
||
null,
|
||
"销售额:¥ " + vue.toDisplayString($options.fmt(row.sales)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ style: { "margin-left": "18rpx" } },
|
||
"成本:¥ " + vue.toDisplayString($options.fmt(row.cost)),
|
||
1
|
||
/* TEXT */
|
||
),
|
||
vue.createElementVNode(
|
||
"text",
|
||
{ style: { "margin-left": "18rpx" } },
|
||
"利润:¥ " + vue.toDisplayString($options.fmt(row.profit)),
|
||
1
|
||
/* TEXT */
|
||
)
|
||
])
|
||
]);
|
||
}),
|
||
128
|
||
/* KEYED_FRAGMENT */
|
||
))
|
||
]);
|
||
}
|
||
const PagesReportIndex = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__file", "D:/wx/PartsInquiry/frontend/pages/report/index.vue"]]);
|
||
__definePage("pages/index/index", PagesIndexIndex);
|
||
__definePage("pages/order/create", PagesOrderCreate);
|
||
__definePage("pages/product/select", PagesProductSelect);
|
||
__definePage("pages/product/list", PagesProductList);
|
||
__definePage("pages/product/form", PagesProductForm);
|
||
__definePage("pages/product/categories", PagesProductCategories);
|
||
__definePage("pages/product/units", PagesProductUnits);
|
||
__definePage("pages/product/settings", PagesProductSettings);
|
||
__definePage("pages/customer/select", PagesCustomerSelect);
|
||
__definePage("pages/customer/form", PagesCustomerForm);
|
||
__definePage("pages/customer/detail", PagesCustomerDetail);
|
||
__definePage("pages/supplier/select", PagesSupplierSelect);
|
||
__definePage("pages/supplier/form", PagesSupplierForm);
|
||
__definePage("pages/account/select", PagesAccountSelect);
|
||
__definePage("pages/account/ledger", PagesAccountLedger);
|
||
__definePage("pages/account/form", PagesAccountForm);
|
||
__definePage("pages/detail/index", PagesDetailIndex);
|
||
__definePage("pages/my/index", PagesMyIndex);
|
||
__definePage("pages/my/about", PagesMyAbout);
|
||
__definePage("pages/report/index", PagesReportIndex);
|
||
const _sfc_main = {
|
||
onLaunch: function() {
|
||
formatAppLog("log", "at App.vue:4", "App Launch");
|
||
},
|
||
onShow: function() {
|
||
formatAppLog("log", "at App.vue:7", "App Show");
|
||
},
|
||
onHide: function() {
|
||
formatAppLog("log", "at App.vue:10", "App Hide");
|
||
}
|
||
};
|
||
const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "D:/wx/PartsInquiry/frontend/App.vue"]]);
|
||
function createApp() {
|
||
const app = vue.createVueApp(App);
|
||
return {
|
||
app
|
||
};
|
||
}
|
||
const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp();
|
||
uni.Vuex = __Vuex__;
|
||
uni.Pinia = __Pinia__;
|
||
__app__.provide("__globalStyles", __uniConfig.styles);
|
||
__app__._component.mpType = "app";
|
||
__app__._component.render = () => {
|
||
};
|
||
__app__.mount("#app");
|
||
})(Vue);
|