You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

220 lines
27 KiB

import { defineComponent, computed, ref, reactive, mergeProps, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderStyle, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrInterpolate, ssrRenderClass } from 'vue/server-renderer';
import { u as useApi } from './useApi-DMQewX5_.mjs';
import { u as useToast } from './useToast-CS21XT61.mjs';
import { u as useAuthStore } from './auth-QFkCoU1C.mjs';
import './server.mjs';
import '../nitro/nitro.mjs';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'node:fs';
import 'node:path';
import 'node:crypto';
import 'node:url';
import '../routes/renderer.mjs';
import 'vue-bundle-renderer/runtime';
import 'unhead/server';
import 'devalue';
import 'unhead/utils';
import 'pinia';
import 'perfect-debounce';
import './useLoading-D4zrSa2m.mjs';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "device",
__ssrInlineRender: true,
setup(__props) {
useApi();
useToast();
const auth = useAuthStore();
const isSuperAdmin = computed(() => auth.identity === 1);
const canCreate = computed(() => auth.identity > 0 && auth.identity <= 2);
const factories = ref([]);
const products = ref([]);
const allProducts = ref([]);
const notes = ref([]);
const devices = ref([]);
const devTotal = ref(0);
const devPage = ref(0);
const devPageSize = ref(200);
const activeTab = ref("production");
const view = ref("main");
const filterFactory = ref(0);
const filterProduct = ref(0);
const filterStart = ref("");
const filterEnd = ref("");
const statBatch = ref("-");
const statDevices = ref("-");
const statLast = ref("-");
const notesCountText = ref("");
const notesLoading = ref(false);
const notesError = ref("");
const codeStatus = ref("1");
const codeSort = ref("usedtime");
const codeBatch = ref("");
const codeCode = ref("");
const codeMac = ref("");
const codeUid = ref("");
const codePageSizeSel = ref("200");
const codePageSizeCustom = ref(null);
const devicesError = ref("");
const selectAll = ref(false);
const selectedCodes = ref([]);
const selectedCount = computed(() => selectedCodes.value.length);
ref(null);
const cFactory = ref(0);
const cProduct = ref(0);
const cBindmac = ref(false);
const cNumber = ref(null);
const cMacaddresses = ref("");
const submitting = ref(false);
ref(null);
const csvFileName = ref("");
ref(null);
const emailSending = ref(false);
const email = reactive({ to: "", cc: "", subject: "", content: "" });
ref(null);
const revokeCtx = ref(null);
const revokeConfirmInput = ref("");
const revokeError = ref("");
const revokeSubmitting = ref(false);
const revokeConfirmOk = computed(() => !!revokeCtx.value && revokeConfirmInput.value.trim() === String(revokeCtx.value.probatch));
const totalPages = computed(() => Math.max(1, Math.ceil(devTotal.value / devPageSize.value)));
const pgInfoText = computed(() => filterProduct.value ? "第 " + (devPage.value + 1) + " / " + totalPages.value + " 页" : "-");
const filterProductOptions = computed(() => {
return filterFactory.value ? products.value.filter((p) => p.factoryid === filterFactory.value) : products.value;
});
const createProductOptions = computed(() => {
return cFactory.value ? products.value.filter((p) => p.factoryid === cFactory.value) : [];
});
function fmtTime(ts) {
if (!ts) return "-";
const d = new Date(ts * 1e3);
return d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0") + " " + String(d.getHours()).padStart(2, "0") + ":" + String(d.getMinutes()).padStart(2, "0");
}
function nameOfFactory(id) {
const f = factories.value.find((x) => x.id === id);
return f ? f.factory : String(id || "");
}
function nameOfProduct(id) {
const p = allProducts.value.find((x) => x.id === id);
return p ? p.devicename : String(id || "");
}
function hexId(id) {
return id ? Number(id).toString(16).toUpperCase() : "";
}
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(mergeProps({ class: "space-y-6" }, _attrs))}><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-4"><div class="flex items-end gap-3 flex-wrap"><div class="form-control"><label class="label py-1"><span class="label-text text-xs">厂家</span></label><select class="select select-bordered select-sm" style="${ssrRenderStyle({ "min-width": "160px" })}"><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(filterFactory.value) ? ssrLooseContain(filterFactory.value, 0) : ssrLooseEqual(filterFactory.value, 0)) ? " selected" : ""}>全部</option><!--[-->`);
ssrRenderList(factories.value, (f) => {
_push(`<option${ssrRenderAttr("value", f.id)}${ssrIncludeBooleanAttr(Array.isArray(filterFactory.value) ? ssrLooseContain(filterFactory.value, f.id) : ssrLooseEqual(filterFactory.value, f.id)) ? " selected" : ""}>${ssrInterpolate(f.factory || "")}</option>`);
});
_push(`<!--]--></select></div><div class="form-control"><label class="label py-1"><span class="label-text text-xs">产品</span></label><select class="select select-bordered select-sm" style="${ssrRenderStyle({ "min-width": "200px" })}"><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(filterProduct.value) ? ssrLooseContain(filterProduct.value, 0) : ssrLooseEqual(filterProduct.value, 0)) ? " selected" : ""}>请选择产品</option><!--[-->`);
ssrRenderList(filterProductOptions.value, (p) => {
_push(`<option${ssrRenderAttr("value", p.id)}${ssrIncludeBooleanAttr(Array.isArray(filterProduct.value) ? ssrLooseContain(filterProduct.value, p.id) : ssrLooseEqual(filterProduct.value, p.id)) ? " selected" : ""}>${ssrInterpolate(p.devicename || "")}</option>`);
});
_push(`<!--]--></select></div><div class="form-control"><label class="label py-1"><span class="label-text text-xs">起始时间</span></label><input${ssrRenderAttr("value", filterStart.value)} type="date" class="input input-bordered input-sm"></div><div class="form-control"><label class="label py-1"><span class="label-text text-xs">结束时间</span></label><input${ssrRenderAttr("value", filterEnd.value)} type="date" class="input input-bordered input-sm"></div><button class="btn btn-primary btn-sm text-white">查询</button>`);
if (canCreate.value) {
_push(`<button class="btn btn-success btn-sm text-white">+ 生成授权码</button>`);
} else {
_push(`<!---->`);
}
_push(`</div></div><div style="${ssrRenderStyle(view.value === "main" ? null : { display: "none" })}"><div class="grid grid-cols-3 gap-4"><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-5"><div class="text-xs text-slate-400 mb-1">命中批次数</div><div class="text-2xl font-bold text-slate-800">${ssrInterpolate(statBatch.value)}</div></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-5"><div class="text-xs text-slate-400 mb-1">生产设备总数</div><div class="text-2xl font-bold text-indigo-600">${ssrInterpolate(statDevices.value)}</div></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-5"><div class="text-xs text-slate-400 mb-1">最近一次生产时间</div><div class="text-base font-semibold text-slate-700">${ssrInterpolate(statLast.value)}</div></div></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 mt-5"><div class="flex items-center justify-between px-5 py-3 border-b border-slate-100"><h3 class="text-sm font-semibold text-slate-700">生产记录(按批次)</h3><div class="flex items-center gap-2"><span class="text-xs text-slate-400">${ssrInterpolate(notesCountText.value)}</span><button class="btn btn-ghost btn-xs">导出CSV</button></div></div><div class="overflow-x-auto" style="${ssrRenderStyle({ "max-height": "360px" })}"><table class="table table-pin-rows text-sm"><thead><tr><th class="w-40">生产时间</th><th>厂家</th><th>产品</th><th>批次</th><th>起始MAC</th><th>结束MAC</th><th class="text-right">数量</th><th>操作</th></tr></thead><tbody>`);
if (notesLoading.value) {
_push(`<tr><td colspan="8" class="text-center text-slate-400 py-8">加载中…</td></tr>`);
} else if (notesError.value) {
_push(`<tr><td colspan="8" class="text-center text-red-400 py-8">查询失败: ${ssrInterpolate(notesError.value)}</td></tr>`);
} else if (!notes.value.length) {
_push(`<tr><td colspan="8" class="text-center text-slate-400 py-8">暂无数据</td></tr>`);
} else {
_push(`<!--[-->`);
ssrRenderList(notes.value, (n, i) => {
_push(`<tr class="hover"><td class="text-xs text-slate-500 whitespace-nowrap">${ssrInterpolate(fmtTime(n.ts))}</td><td class="text-xs">${ssrInterpolate(nameOfFactory(n.factoryid))}</td><td class="text-xs">${ssrInterpolate(nameOfProduct(n.productid))}</td><td class="text-xs">${ssrInterpolate(n.probatch || 0)}</td><td class="font-mono text-xs">${ssrInterpolate(n.startmac || "")}</td><td class="font-mono text-xs">${ssrInterpolate(n.endmac || "")}</td><td class="text-right font-medium">${ssrInterpolate(n.devicetnum || 0)}</td><td><div class="flex gap-1"><button class="btn btn-ghost btn-xs text-indigo-500">查看授权码</button>`);
if (isSuperAdmin.value) {
_push(`<button class="btn btn-ghost btn-xs text-red-500">撤销</button>`);
} else {
_push(`<!---->`);
}
_push(`</div></td></tr>`);
});
_push(`<!--]-->`);
}
_push(`</tbody></table></div></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 mt-5"><div class="flex items-center justify-between px-5 py-3 border-b border-slate-100 flex-wrap gap-2"><h3 class="text-sm font-semibold text-slate-700">授权码记录</h3><div class="flex items-end gap-2 flex-wrap"><div class="form-control"><label class="label py-0"><span class="label-text text-xs">状态</span></label><select class="select select-bordered select-xs"><option value="1"${ssrIncludeBooleanAttr(Array.isArray(codeStatus.value) ? ssrLooseContain(codeStatus.value, "1") : ssrLooseEqual(codeStatus.value, "1")) ? " selected" : ""}>已激活</option><option value="-1"${ssrIncludeBooleanAttr(Array.isArray(codeStatus.value) ? ssrLooseContain(codeStatus.value, "-1") : ssrLooseEqual(codeStatus.value, "-1")) ? " selected" : ""}>未使用</option><option value="2"${ssrIncludeBooleanAttr(Array.isArray(codeStatus.value) ? ssrLooseContain(codeStatus.value, "2") : ssrLooseEqual(codeStatus.value, "2")) ? " selected" : ""}>已过期</option><option value="0"${ssrIncludeBooleanAttr(Array.isArray(codeStatus.value) ? ssrLooseContain(codeStatus.value, "0") : ssrLooseEqual(codeStatus.value, "0")) ? " selected" : ""}>全部</option></select></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">排序</span></label><select class="select select-bordered select-xs"><option value="usedtime"${ssrIncludeBooleanAttr(Array.isArray(codeSort.value) ? ssrLooseContain(codeSort.value, "usedtime") : ssrLooseEqual(codeSort.value, "usedtime")) ? " selected" : ""}>激活时间</option><option value="createtime"${ssrIncludeBooleanAttr(Array.isArray(codeSort.value) ? ssrLooseContain(codeSort.value, "createtime") : ssrLooseEqual(codeSort.value, "createtime")) ? " selected" : ""}>创建时间</option></select></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">批次</span></label><input${ssrRenderAttr("value", codeBatch.value)} type="number" class="input input-bordered input-xs" placeholder="批次号" style="${ssrRenderStyle({ "width": "90px" })}"></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">授权码</span></label><input${ssrRenderAttr("value", codeCode.value)} type="text" class="input input-bordered input-xs" placeholder="授权码"></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">MAC</span></label><input${ssrRenderAttr("value", codeMac.value)} type="text" class="input input-bordered input-xs" placeholder="MAC"></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">用户UID</span></label><input${ssrRenderAttr("value", codeUid.value)} type="text" class="input input-bordered input-xs" placeholder="UID"></div><div class="form-control"><label class="label py-0"><span class="label-text text-xs">每页数量</span></label><select class="select select-bordered select-xs"><option value="20"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "20") : ssrLooseEqual(codePageSizeSel.value, "20")) ? " selected" : ""}>20</option><option value="50"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "50") : ssrLooseEqual(codePageSizeSel.value, "50")) ? " selected" : ""}>50</option><option value="100"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "100") : ssrLooseEqual(codePageSizeSel.value, "100")) ? " selected" : ""}>100</option><option value="200"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "200") : ssrLooseEqual(codePageSizeSel.value, "200")) ? " selected" : ""}>200</option><option value="500"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "500") : ssrLooseEqual(codePageSizeSel.value, "500")) ? " selected" : ""}>500</option><option value="custom"${ssrIncludeBooleanAttr(Array.isArray(codePageSizeSel.value) ? ssrLooseContain(codePageSizeSel.value, "custom") : ssrLooseEqual(codePageSizeSel.value, "custom")) ? " selected" : ""}>自定义</option></select></div><div class="form-control" style="${ssrRenderStyle(codePageSizeSel.value === "custom" ? null : { display: "none" })}"><label class="label py-0"><span class="label-text text-xs">自定义</span></label><input${ssrRenderAttr("value", codePageSizeCustom.value)} type="number" min="1" max="2000" class="input input-bordered input-xs" placeholder="1-2000" style="${ssrRenderStyle({ "width": "90px" })}"></div><button class="btn btn-primary btn-xs text-white">搜索</button><button class="btn btn-error btn-xs text-white"${ssrIncludeBooleanAttr(selectedCount.value === 0) ? " disabled" : ""}>批量禁用</button><button class="btn btn-warning btn-xs text-white"${ssrIncludeBooleanAttr(selectedCount.value === 0) ? " disabled" : ""}>批量恢复</button><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(!devices.value.length) ? " disabled" : ""}>导出</button><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(!devices.value.length) ? " disabled" : ""}>发邮件</button></div></div><div class="overflow-x-auto"><table class="table table-zebra text-sm"><thead><tr><th class="w-8"><input${ssrIncludeBooleanAttr(Array.isArray(selectAll.value) ? ssrLooseContain(selectAll.value, null) : selectAll.value) ? " checked" : ""} type="checkbox" class="checkbox checkbox-xs"></th><th>授权码</th><th>类型</th><th>批次</th><th>MAC</th><th>状态</th><th>封禁</th><th>用户UID</th><th>激活时间</th><th>操作</th></tr></thead><tbody>`);
if (!filterProduct.value) {
_push(`<tr><td colspan="10" class="text-center text-slate-400 py-8">请先选择产品</td></tr>`);
} else if (devicesError.value) {
_push(`<tr><td colspan="10" class="text-center text-red-400 py-8">查询失败: ${ssrInterpolate(devicesError.value)}</td></tr>`);
} else if (!devices.value.length) {
_push(`<tr><td colspan="10" class="text-center text-slate-400 py-8">暂无数据</td></tr>`);
} else {
_push(`<!--[-->`);
ssrRenderList(devices.value, (d, i) => {
_push(`<tr><td><input${ssrIncludeBooleanAttr(Array.isArray(selectedCodes.value) ? ssrLooseContain(selectedCodes.value, d.code || "") : selectedCodes.value) ? " checked" : ""} type="checkbox" class="checkbox checkbox-xs"${ssrRenderAttr("value", d.code || "")}></td><td class="font-mono text-xs">${ssrInterpolate(d.code || "")}</td><td>${ssrInterpolate(d.codetype === 0 ? "授权码" : "设备码")}</td><td>${ssrInterpolate(d.probatch)}</td><td class="font-mono text-xs">${ssrInterpolate(d.devicemac || "")}</td><td>`);
if (d.status === 0) {
_push(`<span class="badge badge-success badge-sm">未使用</span>`);
} else if (d.status === 1) {
_push(`<span class="badge badge-warning badge-sm">已使用</span>`);
} else {
_push(`<span class="badge badge-error badge-sm">已过期</span>`);
}
_push(`</td><td>`);
if (d.disabled !== 0) {
_push(`<span class="badge badge-error badge-sm">已禁用</span>`);
} else {
_push(`<span class="badge badge-ghost badge-sm">正常</span>`);
}
_push(`</td><td class="text-xs">${ssrInterpolate(d.uid || "")}</td><td class="text-xs text-slate-500">${ssrInterpolate(d.usedtime ? fmtTime(d.usedtime) : "-")}</td><td><div class="flex gap-1">`);
if (d.disabled !== 0) {
_push(`<button class="btn btn-ghost btn-xs text-warning">恢复</button>`);
} else {
_push(`<button class="btn btn-ghost btn-xs text-error">禁用</button>`);
}
if (d.status !== 0) {
_push(`<button class="btn btn-ghost btn-xs text-orange-500">重置</button>`);
} else {
_push(`<!---->`);
}
_push(`</div></td></tr>`);
});
_push(`<!--]-->`);
}
_push(`</tbody></table></div><div class="flex items-center justify-between px-5 py-3 border-t border-slate-100"><span class="text-xs text-slate-500">${ssrInterpolate(filterProduct.value ? "共 " + devTotal.value + " 条" : "-")}</span><div class="flex items-center gap-2"><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(devPage.value <= 0 || !filterProduct.value) ? " disabled" : ""}>上一页</button><span class="text-xs text-slate-500">${ssrInterpolate(pgInfoText.value)}</span><button class="btn btn-ghost btn-xs"${ssrIncludeBooleanAttr(!filterProduct.value || devPage.value + 1 >= totalPages.value) ? " disabled" : ""}>下一页</button></div></div></div></div><div style="${ssrRenderStyle(view.value === "create" ? null : { display: "none" })}"><div class="flex items-center gap-3 mb-5"><button class="btn btn-ghost btn-sm">← 返回</button><h2 class="text-lg font-semibold text-slate-800">生成授权码</h2></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl"><form><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">厂家 *</span></label><select class="select select-bordered w-full" required><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(cFactory.value) ? ssrLooseContain(cFactory.value, 0) : ssrLooseEqual(cFactory.value, 0)) ? " selected" : ""}>请选择厂家</option><!--[-->`);
ssrRenderList(factories.value, (f) => {
_push(`<option${ssrRenderAttr("value", f.id)}${ssrIncludeBooleanAttr(Array.isArray(cFactory.value) ? ssrLooseContain(cFactory.value, f.id) : ssrLooseEqual(cFactory.value, f.id)) ? " selected" : ""}>${ssrInterpolate((f.factory || "") + " (" + hexId(f.id) + ")")}</option>`);
});
_push(`<!--]--></select></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">产品 *</span></label><select class="select select-bordered w-full" required${ssrIncludeBooleanAttr(!createProductOptions.value.length) ? " disabled" : ""}><option${ssrRenderAttr("value", 0)}${ssrIncludeBooleanAttr(Array.isArray(cProduct.value) ? ssrLooseContain(cProduct.value, 0) : ssrLooseEqual(cProduct.value, 0)) ? " selected" : ""}>${ssrInterpolate(cFactory.value ? "请选择产品" : "请先选择厂家")}</option><!--[-->`);
ssrRenderList(createProductOptions.value, (p) => {
_push(`<option${ssrRenderAttr("value", p.id)}${ssrIncludeBooleanAttr(Array.isArray(cProduct.value) ? ssrLooseContain(cProduct.value, p.id) : ssrLooseEqual(cProduct.value, p.id)) ? " selected" : ""}>${ssrInterpolate((p.devicename || "") + " (" + hexId(p.id) + ")")}</option>`);
});
_push(`<!--]--></select></div><div class="tabs tabs-boxed mb-4 bg-slate-100 inline-flex"><a class="${ssrRenderClass([{ "tab-active": activeTab.value === "production" }, "tab"])}">生产</a><a class="${ssrRenderClass([{ "tab-active": activeTab.value === "import" }, "tab"])}">导入</a></div><div style="${ssrRenderStyle(activeTab.value === "production" ? null : { display: "none" })}"><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">绑定MAC地址</span></label><input${ssrIncludeBooleanAttr(Array.isArray(cBindmac.value) ? ssrLooseContain(cBindmac.value, null) : cBindmac.value) ? " checked" : ""} type="checkbox" class="toggle toggle-primary"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">数量 *</span></label><input${ssrRenderAttr("value", cNumber.value)} type="number" class="input input-bordered w-full" min="1" max="10000" placeholder="请输入生产数量"${ssrIncludeBooleanAttr(activeTab.value === "production") ? " required" : ""}></div></div><div style="${ssrRenderStyle(activeTab.value === "import" ? null : { display: "none" })}"><div class="form-control mb-2"><label class="label"><span class="label-text font-medium">上传 CSV 文件</span></label><input type="file" class="file-input file-input-bordered file-input-sm w-full" accept=".csv"><p class="text-xs text-slate-400 mt-1">上传 CSV 文件,系统将读取第一列作为 MAC 地址</p></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">MAC 地址列表 *</span></label><textarea class="textarea textarea-bordered w-full" rows="4" placeholder="MAC 地址以逗号分隔,可手动输入或通过CSV导入">${ssrInterpolate(cMacaddresses.value)}</textarea></div></div><div class="flex gap-3 mt-2"><button type="button" class="btn btn-ghost">取消</button><button type="submit" class="btn btn-primary text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""}>`);
if (submitting.value) {
_push(`<span class="loading loading-spinner loading-xs"></span>`);
} else {
_push(`<!---->`);
}
_push(`生成 </button></div></form></div></div><dialog class="modal"><div class="modal-box w-11/12 max-w-2xl"><h3 class="font-bold text-lg mb-4 flex items-center gap-2"><svg class="h-5 w-5 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg> 发送邮件通知 </h3><form><div class="grid grid-cols-2 gap-4 mb-3"><div class="form-control"><label class="label"><span class="label-text text-xs">收件人 *</span></label><input${ssrRenderAttr("value", email.to)} type="email" class="input input-bordered input-sm w-full" required></div><div class="form-control"><label class="label"><span class="label-text text-xs">抄送</span></label><input${ssrRenderAttr("value", email.cc)} type="text" class="input input-bordered input-sm w-full" placeholder="多个邮箱用逗号分隔"></div></div><div class="form-control mb-3"><label class="label"><span class="label-text text-xs">主题 *</span></label><input${ssrRenderAttr("value", email.subject)} type="text" class="input input-bordered input-sm w-full" required></div><div class="form-control mb-3"><label class="label"><span class="label-text text-xs">内容 *</span></label><textarea class="textarea textarea-bordered w-full" rows="10" required>${ssrInterpolate(email.content)}</textarea></div><div class="form-control mb-4"><label class="label"><span class="label-text text-xs">附件</span></label><div class="text-sm text-slate-500">${ssrInterpolate(csvFileName.value ? "📎 " + csvFileName.value : "无附件")}</div></div><div class="modal-action"><button type="button" class="btn btn-ghost btn-sm">取消</button><button type="submit" class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(emailSending.value) ? " disabled" : ""}>`);
if (emailSending.value) {
_push(`<span class="loading loading-spinner loading-xs"></span>`);
} else {
_push(`<!---->`);
}
_push(`发送邮件 </button></div></form></div><form method="dialog" class="modal-backdrop"><button>close</button></form></dialog><dialog class="modal"><div class="modal-box max-w-md"><h3 class="font-bold text-lg mb-3 flex items-center gap-2 text-red-600"><svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01M4.93 19h14.14a2 2 0 001.74-3L13.74 4a2 2 0 00-3.48 0L3.19 16a2 2 0 001.74 3z"></path></svg> 撤销生产批次 </h3><div class="bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-700 mb-4"> 此操作将<strong>删除该批次的全部设备码</strong>以及对应的生产出货记录,<strong>不可恢复</strong>。<br> 若该批次中已有任意设备码被激活/绑定,撤销会被拒绝。 </div><div class="text-sm space-y-1 mb-4"><div><span class="text-slate-500">厂家:</span><span class="font-medium">${ssrInterpolate(revokeCtx.value ? nameOfFactory(revokeCtx.value.factoryid) : "")}</span></div><div><span class="text-slate-500">产品:</span><span class="font-medium">${ssrInterpolate(revokeCtx.value ? nameOfProduct(revokeCtx.value.productid) : "")}</span></div><div><span class="text-slate-500">批次:</span><span class="font-mono font-medium text-red-600">${ssrInterpolate(revokeCtx.value ? revokeCtx.value.probatch : "")}</span></div><div><span class="text-slate-500">设备码数量:</span><span class="font-medium">${ssrInterpolate(revokeCtx.value ? revokeCtx.value.devicetnum : "")}</span></div></div><div class="form-control mb-2"><label class="label"><span class="label-text text-xs">请输入批次号 <span class="font-mono text-red-600">${ssrInterpolate(revokeCtx.value ? revokeCtx.value.probatch : "")}</span> 以确认撤销</span></label><input${ssrRenderAttr("value", revokeConfirmInput.value)} type="text" class="input input-bordered input-sm w-full" autocomplete="off"></div><p class="text-xs text-red-500 min-h-[1em] mb-2">${ssrInterpolate(revokeError.value)}</p><div class="modal-action"><button type="button" class="btn btn-ghost btn-sm">取消</button><button type="button" class="btn btn-error btn-sm text-white"${ssrIncludeBooleanAttr(!revokeConfirmOk.value || revokeSubmitting.value) ? " disabled" : ""}>`);
if (revokeSubmitting.value) {
_push(`<span class="loading loading-spinner loading-xs"></span>`);
} else {
_push(`<!---->`);
}
_push(`确认撤销 </button></div></div><form method="dialog" class="modal-backdrop"><button>close</button></form></dialog></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/device.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export { _sfc_main as default };
//# sourceMappingURL=device-CfQFMgWh.mjs.map