Commit 39e0ad27 by linjinhong

feat:【生产软件】(新)生产软件新增烫画智能排版管理模块

parent 00050ef8
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
"bignumber.js": "^9.2.1", "bignumber.js": "^9.2.1",
"compressing": "^1.10.1", "compressing": "^1.10.1",
"core-js": "^3.6.4", "core-js": "^3.6.4",
"dayjs": "^1.11.21",
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
"electron-dialogs": "^1.4.0", "electron-dialogs": "^1.4.0",
"electron-icon-builder": "^2.0.1", "electron-icon-builder": "^2.0.1",
...@@ -75,6 +76,5 @@ ...@@ -75,6 +76,5 @@
"pug-plain-loader": "^1.0.0", "pug-plain-loader": "^1.0.0",
"vue-cli-plugin-electron-builder": "^1.4.6", "vue-cli-plugin-electron-builder": "^1.4.6",
"vue-template-compiler": "^2.6.11" "vue-template-compiler": "^2.6.11"
}, }
"__npminstall_done": false
} }
...@@ -14,7 +14,7 @@ const { setVersion, getHostApi, setApi } = require("@/server/utils/store"); ...@@ -14,7 +14,7 @@ const { setVersion, getHostApi, setApi } = require("@/server/utils/store");
Object.defineProperty(app, "isPackaged", { Object.defineProperty(app, "isPackaged", {
get() { get() {
return true; return true;
}, }
}); });
createServer(); createServer();
const isDevelopment = process.env.NODE_ENV !== "production"; const isDevelopment = process.env.NODE_ENV !== "production";
...@@ -22,7 +22,7 @@ const isDevelopment = process.env.NODE_ENV !== "production"; ...@@ -22,7 +22,7 @@ const isDevelopment = process.env.NODE_ENV !== "production";
let win; let win;
let newWindow; let newWindow;
protocol.registerSchemesAsPrivileged([ protocol.registerSchemesAsPrivileged([
{ scheme: "app", privileges: { secure: true, standard: true } }, { scheme: "app", privileges: { secure: true, standard: true } }
]); ]);
const winURL = const winURL =
process.env.NODE_ENV === "development" process.env.NODE_ENV === "development"
...@@ -39,9 +39,9 @@ async function createWindow() { ...@@ -39,9 +39,9 @@ async function createWindow() {
webSecurity: false, webSecurity: false,
nodeIntegration: true, nodeIntegration: true,
contextIsolation: false, // ^1.4.0 版本必须关闭 contextIsolation: false // ^1.4.0 版本必须关闭
}, },
show: false, show: false
}); });
win.once("ready-to-show", () => { win.once("ready-to-show", () => {
win.maximize(); win.maximize();
...@@ -49,62 +49,6 @@ async function createWindow() { ...@@ -49,62 +49,6 @@ async function createWindow() {
}); });
const template = [ const template = [
{ {
label: "文件",
submenu: [
{
label: "新建",
accelerator: "CmdOrCtrl+N",
click: () => {
console.log("新建文件");
// 这里可以添加创建新文件的逻辑
},
},
{
label: "打开",
accelerator: "CmdOrCtrl+O",
click: () => {
// 打开文件对话框
dialog
.showOpenDialog({
properties: ["openFile"],
})
.then((result) => {
if (!result.canceled) {
console.log("打开文件:", result.filePaths[0]);
}
});
},
},
{
label: "保存",
accelerator: "CmdOrCtrl+S",
click: () => {
console.log("保存文件");
},
},
{
label: "另存为",
accelerator: "CmdOrCtrl+Shift+S",
click: () => {
console.log("另存为");
},
},
{ type: "separator" },
{
label: "打印",
accelerator: "CmdOrCtrl+P",
click: () => {
const win = BrowserWindow.getFocusedWindow();
if (win) {
win.webContents.print();
}
},
},
{ type: "separator" },
],
},
{
label: "编辑", label: "编辑",
submenu: [ submenu: [
{ label: "撤销", role: "undo" }, { label: "撤销", role: "undo" },
...@@ -115,8 +59,8 @@ async function createWindow() { ...@@ -115,8 +59,8 @@ async function createWindow() {
{ label: "粘贴", role: "paste" }, { label: "粘贴", role: "paste" },
{ label: "删除", role: "delete" }, { label: "删除", role: "delete" },
{ type: "separator" }, { type: "separator" },
{ label: "全选", role: "selectAll" }, { label: "全选", role: "selectAll" }
], ]
}, },
{ {
...@@ -130,8 +74,8 @@ async function createWindow() { ...@@ -130,8 +74,8 @@ async function createWindow() {
{ label: "放大", role: "zoomin" }, { label: "放大", role: "zoomin" },
{ label: "缩小", role: "zoomout" }, { label: "缩小", role: "zoomout" },
{ type: "separator" }, { type: "separator" },
{ label: "全屏切换", role: "togglefullscreen" }, { label: "全屏切换", role: "togglefullscreen" }
], ]
}, },
{ {
...@@ -139,8 +83,8 @@ async function createWindow() { ...@@ -139,8 +83,8 @@ async function createWindow() {
submenu: [ submenu: [
{ label: "最小化", role: "minimize" }, { label: "最小化", role: "minimize" },
{ label: "缩放", role: "zoom" }, { label: "缩放", role: "zoom" },
{ label: "关闭", role: "close" }, { label: "关闭", role: "close" }
], ]
}, },
{ {
label: "设置", label: "设置",
...@@ -159,7 +103,7 @@ async function createWindow() { ...@@ -159,7 +103,7 @@ async function createWindow() {
type: "error", type: "error",
title: "错误", title: "错误",
message: "无可用窗口", message: "无可用窗口",
buttons: ["确定"], buttons: ["确定"]
}); });
return; return;
} }
...@@ -183,8 +127,8 @@ async function createWindow() { ...@@ -183,8 +127,8 @@ async function createWindow() {
contextIsolation: false, contextIsolation: false,
sandbox: false, sandbox: false,
enableRemoteModule: true, enableRemoteModule: true,
webSecurity: false, webSecurity: false
}, }
}); });
// 3. 打开开发者工具(排查用,上线后删除) // 3. 打开开发者工具(排查用,上线后删除)
...@@ -194,7 +138,7 @@ async function createWindow() { ...@@ -194,7 +138,7 @@ async function createWindow() {
if (process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
exePath = path.join( exePath = path.join(
__dirname, __dirname,
"../html/domain-prompt.html", "../html/domain-prompt.html"
); );
} else { } else {
const newpath = path const newpath = path
...@@ -251,11 +195,11 @@ async function createWindow() { ...@@ -251,11 +195,11 @@ async function createWindow() {
// console.log("修改后的数据:", newData); // console.log("修改后的数据:", newData);
// 4. 写回文件 // 4. 写回文件
fs.writeFile(configPath, newData, "utf-8", (writeErr) => { fs.writeFile(configPath, newData, "utf-8", writeErr => {
if (writeErr) { if (writeErr) {
console.error("写入配置文件失败:", writeErr); console.error("写入配置文件失败:", writeErr);
this.$message.error( this.$message.error(
`写入配置文件失败: ${writeErr.message}`, `写入配置文件失败: ${writeErr.message}`
); );
return; return;
} }
...@@ -267,7 +211,7 @@ async function createWindow() { ...@@ -267,7 +211,7 @@ async function createWindow() {
} catch (parseError) { } catch (parseError) {
console.error("解析 JSON 失败:", parseError); console.error("解析 JSON 失败:", parseError);
this.$message.error( this.$message.error(
`配置文件格式错误: ${parseError.message}`, `配置文件格式错误: ${parseError.message}`
); );
} }
}); });
...@@ -278,7 +222,7 @@ async function createWindow() { ...@@ -278,7 +222,7 @@ async function createWindow() {
console.error("自定义弹窗出错:", error); console.error("自定义弹窗出错:", error);
} }
})(); })();
}, }
}, },
{ {
label: "清除缓存", label: "清除缓存",
...@@ -293,7 +237,7 @@ async function createWindow() { ...@@ -293,7 +237,7 @@ async function createWindow() {
type: "error", type: "error",
title: "错误", title: "错误",
message: "无可用窗口", message: "无可用窗口",
buttons: ["确定"], buttons: ["确定"]
}); });
return; return;
} }
...@@ -317,8 +261,8 @@ async function createWindow() { ...@@ -317,8 +261,8 @@ async function createWindow() {
contextIsolation: false, contextIsolation: false,
sandbox: false, sandbox: false,
enableRemoteModule: true, enableRemoteModule: true,
webSecurity: false, webSecurity: false
}, }
}); });
// 3. 打开开发者工具(排查用,上线后删除) // 3. 打开开发者工具(排查用,上线后删除)
...@@ -372,34 +316,34 @@ async function createWindow() { ...@@ -372,34 +316,34 @@ async function createWindow() {
console.error("自定义弹窗出错:", error); console.error("自定义弹窗出错:", error);
} }
})(); })();
}, }
}, }
], ]
}, }
{
label: "帮助",
submenu: [
{
label: "帮助文档",
click: async () => {
await shell.openExternal("");
},
},
{
label: "检查更新",
click: () => {
console.log("检查更新");
},
},
{ type: "separator" },
{ // {
label: "关于", // label: "帮助",
click: () => {}, // submenu: [
}, // {
], // label: "帮助文档",
}, // click: async () => {
// await shell.openExternal("");
// },
// },
// {
// label: "检查更新",
// click: () => {
// console.log("检查更新");
// },
// },
// { type: "separator" },
// {
// label: "关于",
// click: () => {},
// },
// ],
// },
]; ];
// 构建菜单 // 构建菜单
const menu = Menu.buildFromTemplate(template); const menu = Menu.buildFromTemplate(template);
...@@ -415,20 +359,20 @@ async function createWindow() { ...@@ -415,20 +359,20 @@ async function createWindow() {
if (newWindow) newWindow.webContents.send("getProductionNoInfo", v); if (newWindow) newWindow.webContents.send("getProductionNoInfo", v);
}); });
ipcMain.on("request-select-folder", (event) => { ipcMain.on("request-select-folder", event => {
// 打开文件夹选择对话框(Electron 6.x 回调写法,更稳定) // 打开文件夹选择对话框(Electron 6.x 回调写法,更稳定)
dialog.showOpenDialog( dialog.showOpenDialog(
{ {
properties: ["openDirectory"], // 仅允许选择文件夹 properties: ["openDirectory"], // 仅允许选择文件夹
title: "选择下载保存位置", title: "选择下载保存位置"
}, },
(result) => { result => {
// 处理结果并返回给渲染进程 // 处理结果并返回给渲染进程
console.log(438, result); console.log(438, result);
if (result.length) { if (result.length) {
event.reply("select-folder-result", result[0]); event.reply("select-folder-result", result[0]);
} }
}, }
); );
}); });
...@@ -465,22 +409,22 @@ async function createWindow() { ...@@ -465,22 +409,22 @@ async function createWindow() {
// 自动更新逻辑开始 // 自动更新逻辑开始
autoUpdater.autoDownload = false; autoUpdater.autoDownload = false;
autoUpdater.autoInstallOnAppQuit = false; // 应用退出后自动安装 autoUpdater.autoInstallOnAppQuit = false; // 应用退出后自动安装
autoUpdater.on("download-progress", (progress) => { autoUpdater.on("download-progress", progress => {
// 下载进度监听 // 下载进度监听
if (win.isDestroyed()) return; if (win.isDestroyed()) return;
win.webContents.send("update", { win.webContents.send("update", {
speed: Math.ceil(progress.bytesPerSecond / 1000), // 网速 speed: Math.ceil(progress.bytesPerSecond / 1000), // 网速
percent: Math.ceil(progress.percent), // 百分比 percent: Math.ceil(progress.percent) // 百分比
}); });
}); });
autoUpdater.on("error", (err) => { autoUpdater.on("error", err => {
// 下载失败监听 // 下载失败监听
if (win.isDestroyed()) return; if (win.isDestroyed()) return;
win.webContents.send("update-error", err); win.webContents.send("update-error", err);
}); });
autoUpdater.on("update-downloaded", (info) => { autoUpdater.on("update-downloaded", info => {
// 下载完成监听 // 下载完成监听
if (win.isDestroyed()) return; if (win.isDestroyed()) return;
console.log(info, "info"); console.log(info, "info");
...@@ -497,9 +441,9 @@ async function createWindow() { ...@@ -497,9 +441,9 @@ async function createWindow() {
if (win.isDestroyed()) return; if (win.isDestroyed()) return;
autoUpdater.setFeedURL({ autoUpdater.setFeedURL({
provider: "generic", provider: "generic",
url: item.url, url: item.url
}); });
autoUpdater.checkForUpdates().then((res) => { autoUpdater.checkForUpdates().then(res => {
console.log(res); console.log(res);
autoUpdater.downloadUpdate(); autoUpdater.downloadUpdate();
}); });
...@@ -516,7 +460,7 @@ async function createWindow() { ...@@ -516,7 +460,7 @@ async function createWindow() {
path.dirname(app.getPath("exe")), path.dirname(app.getPath("exe")),
"resources", "resources",
"scripts", "scripts",
"script.ps1", "script.ps1"
); );
} }
...@@ -576,7 +520,7 @@ app.on("will-quit", () => { ...@@ -576,7 +520,7 @@ app.on("will-quit", () => {
if (isDevelopment) { if (isDevelopment) {
if (process.platform === "win32") { if (process.platform === "win32") {
process.on("message", (data) => { process.on("message", data => {
if (data === "graceful-exit") { if (data === "graceful-exit") {
app.quit(); app.quit();
} }
......
<template>
<div class="commodity-card" :class="{ active: active }">
<div class="commodity-card-image">
<div class="before" :style="{ paddingTop: paddingTop }"></div>
<div class="image">
<img :src="mainImageSrc" />
</div>
<!-- 左上角 -->
<div class="img_top_left">
<span v-if="showSelectIcon" class="select-icon"></span>
<slot name="top_left"></slot>
</div>
<!-- 右上角 -->
<div class="img_top_right">
<slot name="top_right"></slot>
</div>
<!-- 左下角 -->
<div class="img_bottom_left">
<slot name="bottom_left"></slot>
</div>
<!-- 右下角 -->
<div class="img_bottom_right">
<slot name="operations"></slot>
</div>
</div>
<div class="commodity-card-info">
<!-- 颜色图片列表 -->
<div v-if="hasImageList" class="color-image flex flex-gap-10">
<div
v-for="(img, index) in imageList"
:key="index"
class="color-image-item"
>
<img :src="getItemImagePath(img)" />
</div>
</div>
<!-- 时间信息插槽 -->
<slot name="time"></slot>
<!-- 名称和价格 -->
<div
v-if="cardItem?.productName"
class="commodity-card-name-price flex flex-justify-space-between"
>
<slot name="productName">
<span>{{ cardItem?.productName }}</span>
</slot>
<slot name="price"></slot>
</div>
<!-- SKU信息 -->
<div
v-if="cardItem?.sku"
class="commodity-card-sku"
@click.stop="copy(String(cardItem?.sku))"
>
<!-- <img src="../assets/images/id.png" height="20" /> -->
<span>{{ cardItem?.sku }}</span>
</div>
<slot name="images"></slot>
<!-- 自定义信息 -->
<slot name="info"></slot>
</div>
</div>
</template>
<script>
/**
* 通用卡片封装 BaseCard
* 基于ElementUI el-card二次封装,配置驱动 + 多插槽拓展
* @prop {Object} cardConfig 卡片核心配置对象
* @prop {String} bodyPadding 卡片body内边距,默认 0px
*/
export default {
name: "BaseCard",
props: {
cardItem: {
type: Object,
default: () => ({})
},
active: {
type: Boolean,
default: false
},
showSelectIcon: {
type: Boolean,
default: true
},
showSku: {
type: Boolean,
default: false
},
showProductInfo: {
type: Boolean,
default: false
},
showImageList: {
type: Boolean,
default: false
},
imageField: {
type: String,
default: "variantImage"
},
imageListField: {
type: String,
default: "imageList"
},
imagePathField: {
type: String,
default: "imagePath"
},
paddingTop: {
type: String,
default: "120%"
}
},
data() {
return { imageList: [] };
},
computed: {
hasImageList() {
return true;
},
mainImageSrc() {
return "https://tcustom.jomalls.com/shengchengtu/xiaoguotu/20260603/1780453208357TTp79stDPWRzooRZ.jpg";
}
},
methods: {}
};
</script>
<style lang="less" scoped>
.commodity-card {
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.commodity-card-image {
position: relative;
border: 1px solid #eee;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
.img_top_left {
position: absolute;
top: 5px;
left: 5px;
display: flex;
align-items: center;
gap: 4px;
}
.img_top_right {
position: absolute;
top: 0px;
right: 0px;
}
.img_bottom_left {
position: absolute;
bottom: 5px;
left: 5px;
}
.img_bottom_right {
position: absolute;
bottom: 5px;
right: 5px;
display: flex;
align-items: center;
:deep(.svg-icon) {
width: 2em;
height: 2em;
}
}
}
.before {
height: 0;
}
.image {
position: absolute;
// position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
}
.color-image {
.color-image-item {
width: 50px;
height: 50px;
}
img {
width: 100%;
height: 100%;
}
}
.commodity-card-info {
flex: 1;
padding: 10px;
font-size: 14px;
background: linear-gradient(
90deg,
rgba(228, 228, 228, 0.4) 0%,
rgba(255, 255, 255, 1) 100%
);
}
.commodity-card-name-price {
height: 30px;
line-height: 30px;
}
.commodity-card-sku {
display: flex;
align-items: center;
gap: 5px;
background-color: #fff;
cursor: pointer;
}
.select-icon {
position: relative;
display: block;
width: 16px;
height: 16px;
border: 1px solid #cccccc;
box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.4) inset;
border-radius: 8px;
background: #fff;
}
.commodity-card.active .select-icon {
background: #4168ff;
position: relative;
border-color: #4168ff;
box-shadow: none;
font-size: 18px;
top: -1px;
left: -1px;
}
.commodity-card.active .select-icon::after {
position: absolute;
content: "";
top: 0px;
left: 4px;
width: 4px;
height: 8px;
border-width: 2px;
border-style: solid;
border-color: transparent #fff #fff transparent;
transform: rotate(45deg) scale(0.8);
}
</style>
<template>
<div class="base-table-wrap">
<!-- ElementUI 原生表格,所有属性透传 -->
<el-table
ref="tableRef"
:data="tableData"
v-bind="$attrs"
v-on="$listeners"
@selection-change="handleSelectionChange"
>
<!-- 多选框列 -->
<el-table-column
v-if="hasSelection"
type="selection"
width="50"
align="center"
/>
<!-- 序号列 -->
<el-table-column
v-if="hasIndex"
type="index"
label="序号"
width="50"
align="center"
/>
<!-- 动态循环渲染列配置 -->
<el-table-column
v-for="col in tableConfig"
:key="col.prop"
:prop="col.prop"
:label="col.label"
:width="col.width"
:min-width="col.minWidth"
:fixed="col.fixed"
:align="col.align || 'center'"
:header-align="col.headerAlign || col.align || 'center'"
:sortable="col.sortable"
:show-overflow-tooltip="col.showOverflowTooltip ?? true"
>
<template slot-scope="scope">
<!-- 1. 自定义render -->
<span
v-if="col.render"
v-html="col.render(scope.row, scope.column, scope.$index)"
></span>
<!-- 2. tag标签 -->
<el-tag
v-else-if="col.type === 'tag'"
:type="col.getTagType ? col.getTagType(scope.row) : 'primary'"
:effect="col.tagEffect || 'light'"
size="mini"
>
{{
col.getTagText ? col.getTagText(scope.row) : scope.row[col.prop]
}}
</el-tag>
<!-- 3. 图片 -->
<el-image
v-else-if="col.type === 'image'"
:src="scope.row[col.prop]"
style="width: 40px; height: 40px"
fit="cover"
:preview-src-list="[scope.row[col.prop]]"
/>
<!-- 4. 开关 -->
<el-switch
v-else-if="col.type === 'switch'"
v-model="scope.row[col.prop]"
@change="col.onSwitchChange && col.onSwitchChange(scope.row)"
active-text="开启"
inactive-text="关闭"
/>
<!-- 5. 操作按钮 -->
<div v-else-if="col.type === 'button'" class="table-btn-group">
<el-button
v-for="btn in col.btns"
:key="btn.key"
size="mini"
:type="btn.type || 'primary'"
:icon="btn.icon"
:disabled="btn.disabled ? btn.disabled(scope.row) : false"
@click="btn.click(scope.row, scope.$index)"
>
{{ btn.label }}
</el-button>
</div>
<!-- 6. 外部自定义插槽 -->
<slot v-else-if="col.slotName" :name="col.slotName" v-bind="scope" />
<!-- 7. 普通文本兜底(现在一定能拿到scope) -->
<span v-else>{{ scope.row[col.prop] ?? "" }}</span>
</template>
<!-- 7. 默认文本展示 -->
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
small
v-if="showPagination"
class="table-pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageInfo.pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
/>
</div>
</template>
<script>
export default {
name: "BaseTable",
props: {
/**
* 表格数据源
*/
tableData: {
type: Array,
default: () => []
},
/**
* 列配置数组【核心】
* @type Array<Object>
* 字段说明:
* prop: 绑定字段名
* label: 表头文字
* width/minWidth: 列宽
* fixed: 固定列 left/right
* align/headerAlign: 对齐方式
* sortable: 是否可排序
* showOverflowTooltip: 文字溢出悬浮提示
* type: tag/image/switch/button 特殊类型渲染
* render: 自定义渲染函数(row, column, index) => html字符串
* slotName: 自定义插槽名称
* btns: 操作按钮数组(type=button时生效)
*/
tableConfig: {
type: Array,
required: true
},
/**
* 是否显示多选框
*/
hasSelection: {
type: Boolean,
default: false
},
/**
* 是否显示序号列
*/
hasIndex: {
type: Boolean,
default: false
},
/**
* 是否展示分页
*/
showPagination: {
type: Boolean,
default: true
},
/**
* 分页信息
* { pageNum: 1, pageSize: 10, total: 0 }
*/
pageInfo: {
type: Object,
default: () => ({
pageNum: 1,
pageSize: 10,
total: 0
})
}
},
data() {
return {
// 选中行存储
selectedRows: []
};
},
methods: {
/**
* 多选框选中回调
*/
handleSelectionChange(val) {
this.selectedRows = val;
this.$emit("selection", val);
},
/**
* 获取当前选中的所有行数据
*/
getSelectedRows() {
return this.selectedRows;
},
/**
* 清空多选框选中状态
*/
clearSelection() {
this.$refs.tableRef.clearSelection();
this.selectedRows = [];
},
/**
* 每页条数改变
*/
handleSizeChange(size) {
this.$emit("page-size-change", size);
},
/**
* 页码改变
*/
handleCurrentChange(page) {
this.$emit("page-current-change", page);
}
},
mounted() {
console.log("tableConfig", this.tableConfig);
console.log("tableData", this.tableData);
}
};
</script>
<style scoped>
.el-table {
max-height: calc(100% - 75px);
}
.base-table-wrap {
width: 100%;
height: 100%;
/* overflow-y: scroll; */
}
.table-pagination {
margin-top: 10px;
text-align: center;
}
.table-btn-group {
display: flex;
gap: 4px;
flex-wrap: wrap;
justify-content: center;
}
</style>
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
:draggable="true" :draggable="true"
:resizable="true" :resizable="true"
:rotatable="true" :rotatable="true"
@dragstop="(a) => dragStop(a, item)" @dragstop="a => dragStop(a, item)"
@resizestop="(a) => resizeStop(a, item)" @resizestop="a => resizeStop(a, item)"
@rotatestop="(a) => rotating(a, item)" @rotatestop="a => rotating(a, item)"
:angle="item.r" :angle="item.r"
> >
<div <div
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
:class="{ 'no-border-grid': systemSetting.gridShow !== 1 }" :class="{ 'no-border-grid': systemSetting.gridShow !== 1 }"
:style="{ :style="{
width: gridWH.w + 'px', width: gridWH.w + 'px',
height: gridWH.h + 'px', height: gridWH.h + 'px'
}" }"
class="grid" class="grid"
> >
...@@ -89,9 +89,9 @@ export default { ...@@ -89,9 +89,9 @@ export default {
// console.log(data); // console.log(data);
this.$set(item, "r", data.angle); this.$set(item, "r", data.angle);
this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList))); this.imgHistoryList.push(JSON.parse(JSON.stringify(this.imgList)));
}, }
}, },
mounted() {}, mounted() {}
}; };
</script> </script>
<style lang="less"> <style lang="less">
...@@ -105,7 +105,7 @@ export default { ...@@ -105,7 +105,7 @@ export default {
#line { #line {
position: absolute; position: absolute;
left: 5%; left: 5%;
top: 50%; top: 46%;
transform: translate(0, -50%); transform: translate(0, -50%);
background-color: #f0f2f6; background-color: #f0f2f6;
} }
......
...@@ -8,38 +8,62 @@ const routes = [ ...@@ -8,38 +8,62 @@ const routes = [
path: "/", path: "/",
name: "login", name: "login",
meta: { meta: {
title: "登录", title: "登录"
}, },
component: (resolve) => require(["../views/login/index.vue"], resolve), component: resolve => require(["../views/login/index.vue"], resolve)
}, },
{ {
path: "/design", path: "/design",
name: "design", name: "design",
meta: { meta: {
title: "设计页面", title: "设计页面"
}, },
component: (resolve) => require(["../views/design/index.vue"], resolve), component: resolve => require(["../views/design/index.vue"], resolve)
}, },
// {
// path: "/design-detail",
// name: "design",
// meta: {
// title: "设计详情页面"
// },
// component: resolve => require(["../views/design/detail/index.vue"], resolve)
// },
{ {
path: "/design-detail", path: "/dtf-setting",
name: "design", name: "dtfSetting",
meta: { meta: {
title: "设计详情页面", title: "DTF排版设置"
}, },
component: (resolve) => component: resolve => require(["@/views/dtf-setting/index.vue"], resolve)
require(["../views/design/detail/index.vue"], resolve),
}, },
{ {
path: "*", path: "/dtf-batch-detail",
redirect: "/", name: "dtfBatchDetail",
meta: {
title: "DTF批次详情"
},
component: resolve =>
require(["@/views/dtf-batch-detail/detail.vue"], resolve)
},
{
path: "/dtf-file",
name: "dtfFileDownLoad",
meta: {
title: "DTF下载文件详情"
},
component: resolve => require(["@/views/dtf-file/index.vue"], resolve)
}, },
{
path: "*",
redirect: "/"
}
]; ];
const router = new VueRouter({ const router = new VueRouter({
mode: "hash", mode: "hash",
base: process.env.BASE_URL, base: process.env.BASE_URL,
routes, routes
}); });
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
let user = Vue.prototype.$dataStore.get("user"); let user = Vue.prototype.$dataStore.get("user");
...@@ -57,6 +81,8 @@ router.beforeEach((to, from, next) => { ...@@ -57,6 +81,8 @@ router.beforeEach((to, from, next) => {
if (user) { if (user) {
return next(); return next();
} else { } else {
console.log("router", user);
return next("/"); return next("/");
} }
} }
......
...@@ -202,6 +202,12 @@ module.exports = { ...@@ -202,6 +202,12 @@ module.exports = {
}, },
getIsOver: () => store.get("isOver") || false, getIsOver: () => store.get("isOver") || false,
//本地储存 DTG、DTF生产
setProductType: value => {
store.set("productType", value);
},
getProductType: () => store.get("productType") || "DTG",
setLocation: (version, locationKey) => { setLocation: (version, locationKey) => {
if (!locationKey) return; if (!locationKey) return;
store.set(locationKey, version); store.set(locationKey, version);
......
...@@ -1144,7 +1144,7 @@ export default { ...@@ -1144,7 +1144,7 @@ export default {
z-index: 4; z-index: 4;
bottom: 0; bottom: 0;
height: calc(100% - 50px); height: calc(100% - 75px);
.print-content { .print-content {
background: #fff; background: #fff;
......
<script> <script>
import PHead from "./head/index.vue"; import PHead from "./head/index.vue";
import PMain from "./main/index.vue"; import PMain from "./main/index.vue";
import DTFproduct from "@/views/dtf-list/index.vue";
import UpdateDialog from "@/views/design/updateDialog.vue"; import UpdateDialog from "@/views/design/updateDialog.vue";
const { getProductType, setProductType } = require("@/server/utils/store");
export default { export default {
components: { PHead, PMain, UpdateDialog }, components: { PHead, PMain, UpdateDialog, DTFproduct },
data() { data() {
return { return {
user: {}, user: {},
factoryType: "CN", factoryType: "CN",
activeName: getProductType()
}; };
}, },
mounted() { mounted() {
console.log(18, getProductType());
this.user = this.$dataStore.get("user"); this.user = this.$dataStore.get("user");
if (this.user.factory && this.user.factory.countryCode) { if (this.user.factory && this.user.factory.countryCode) {
this.factoryType = this.user.factory.countryCode; this.factoryType = this.user.factory.countryCode;
} }
// console.log(17, this.user); // console.log(17, this.user);
this.$refs.updateDialog.checkUpdate().then((data) => { this.$refs.updateDialog.checkUpdate().then(data => {
// console.log(17, data); // console.log(17, data);
if (data) { if (data) {
...@@ -27,22 +31,75 @@ export default { ...@@ -27,22 +31,75 @@ export default {
} }
}); });
}, },
methods: {
tabClick(tab) {
console.log(34, tab);
setProductType(tab.name);
}
}
}; };
</script> </script>
<template> <template>
<div class="page"> <div class="page">
<p-head :user="user" :factoryType="factoryType" /> <el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
<p-main :factoryType="factoryType" /> <el-tab-pane label="DTG生产" name="DTG">
<update-dialog ref="updateDialog" /> <p-head :user="user" :factoryType="factoryType"/>
<p-main :factoryType="factoryType"/>
<update-dialog ref="updateDialog"
/></el-tab-pane>
<el-tab-pane label="DTF生产" name="DTF">
<DTFproduct :user="user" :factoryType="factoryType"></DTFproduct>
</el-tab-pane>
</el-tabs>
</div> </div>
</template> </template>
<style scoped> <style scoped lang="less">
.page { .page {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
// border-top: 1px solid #dcdfe6;
}
::v-deep {
.el-tabs {
height: 100%;
border-bottom: none;
}
.el-tabs__header {
margin: 0;
background-color: #c6c6c6;
// height: 20px;
}
.el-tabs__header .el-tabs__item {
font-size: 12px;
line-height: 25px;
height: 25px;
// border-bottom: none;
}
.el-tabs--border-card > .el-tabs__content {
padding: 0;
height: 100%;
}
.el-tab-pane {
height: 100%;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
border: none;
background-color: #243151;
color: #fff;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
border: none;
}
.el-tabs--border-card
> .el-tabs__header
.el-tabs__item:not(.is-disabled):hover {
color: #fff;
// background-color: #5b647c;
}
} }
</style> </style>
...@@ -18,33 +18,33 @@ export default { ...@@ -18,33 +18,33 @@ export default {
y: 0, y: 0,
w: 0, w: 0,
h: 0, h: 0,
r: 0, r: 0
}, }
}; };
}, },
computed: { computed: {
...mapState(["isPreView"]), ...mapState(["isPreView"])
}, },
props: { props: {
visible: { visible: {
type: Boolean, type: Boolean,
default: false, default: false
}, },
item: { item: {
type: Object, type: Object,
default: () => {}, default: () => {}
}, },
newDesktopDevice: { newDesktopDevice: {
type: [String, Number], type: [String, Number],
default: "1", default: "1"
}, }
}, },
watch: { watch: {
visible: { visible: {
handler() { handler() {
this.drawerShow = this.visible; this.drawerShow = this.visible;
}, },
immediate: true, immediate: true
}, },
item: { item: {
handler(val) { handler(val) {
...@@ -67,14 +67,14 @@ export default { ...@@ -67,14 +67,14 @@ export default {
y: 0, y: 0,
w: 0, w: 0,
h: 0, h: 0,
r: 0, r: 0
}; };
} }
// console.log("item", this.item); // console.log("item", this.item);
}, },
immediate: true, immediate: true,
deep: true, deep: true
}, }
}, },
methods: { methods: {
pxToUnit, pxToUnit,
...@@ -87,7 +87,7 @@ export default { ...@@ -87,7 +87,7 @@ export default {
this.item.x = item.x - item.w / 2; this.item.x = item.x - item.w / 2;
this.$dataStore.set( this.$dataStore.set(
"position_before_px", "position_before_px",
JSON.parse(JSON.stringify(this.item)), JSON.parse(JSON.stringify(this.item))
); );
console.log("this.item", this.item); console.log("this.item", this.item);
...@@ -107,7 +107,7 @@ export default { ...@@ -107,7 +107,7 @@ export default {
this.form.r = this.item.r; this.form.r = this.item.r;
this.$dataStore.set( this.$dataStore.set(
`position_after_px`, `position_after_px`,
JSON.parse(JSON.stringify(this.form)), JSON.parse(JSON.stringify(this.form))
); );
}, },
formChange(t) { formChange(t) {
...@@ -169,8 +169,8 @@ export default { ...@@ -169,8 +169,8 @@ export default {
if (this.form[f] < 0) this.$set(this.form, f, 0); if (this.form[f] < 0) this.$set(this.form, f, 0);
} }
this.formChange(); this.formChange();
}, }
}, }
}; };
</script> </script>
...@@ -370,14 +370,14 @@ export default { ...@@ -370,14 +370,14 @@ export default {
width: 500px; width: 500px;
// bottom: 0; // bottom: 0;
// top: 50px; // top: 50px;
padding: 10px; // padding: 10px;
// z-index: 99; // z-index: 99;
background: white; background: white;
// box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2), // box-shadow: 0 8px 10px -5px rgba(0, 0, 0, 0.2),
// 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12); // 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12);
// left: 0; // left: 0;
// position: fixed; // position: fixed;
border-right: 1px solid #ececec; // border-right: 1px solid #ececec;
// height: calc(100vh - 50px); // height: calc(100vh - 50px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
......
...@@ -1593,7 +1593,7 @@ export default { ...@@ -1593,7 +1593,7 @@ export default {
<div class="item-label">工厂:</div> <div class="item-label">工厂:</div>
<div class="item-value">{{ detail.factoryCode }}</div> <div class="item-value">{{ detail.factoryCode }}</div>
</div> </div>
<div :title="detail.shopNumber" class="div-item" style="flex: 50%;"> <div :title="detail.shopNumber" class="div-item">
<div> <div>
店铺单号: 店铺单号:
</div> </div>
...@@ -1601,11 +1601,7 @@ export default { ...@@ -1601,11 +1601,7 @@ export default {
{{ detail.shopNumber }} {{ detail.shopNumber }}
</div> </div>
</div> </div>
<div <div :title="detail.endProductId" class="div-item">
:title="detail.endProductId"
class="div-item"
style="flex: 50%;"
>
<div> <div>
客户保存记录ID: 客户保存记录ID:
</div> </div>
...@@ -1613,19 +1609,11 @@ export default { ...@@ -1613,19 +1609,11 @@ export default {
{{ detail.endProductId || "" }} {{ detail.endProductId || "" }}
</div> </div>
</div> </div>
<div <div :title="detail.createTime" class="div-item">
:title="detail.createTime"
class="div-item"
style="flex: 100%;"
>
<div>创建时间:</div> <div>创建时间:</div>
<div>{{ detail.createTime }}</div> <div>{{ detail.createTime }}</div>
</div> </div>
<div <div :title="detail.startStockingTime" class="div-item">
:title="detail.startStockingTime"
class="div-item"
style="flex: 100%;"
>
<div> <div>
生产确认时间: 生产确认时间:
</div> </div>
...@@ -2033,6 +2021,7 @@ export default { ...@@ -2033,6 +2021,7 @@ export default {
flex-shrink: 0; flex-shrink: 0;
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
height: 100%;
} }
.main-bg { .main-bg {
...@@ -2049,7 +2038,7 @@ export default { ...@@ -2049,7 +2038,7 @@ export default {
// z-index: 2; // z-index: 2;
left: 5%; left: 5%;
top: 50%; top: 46%;
transform: translate(0, -50%); transform: translate(0, -50%);
background-color: #f0f2f6; background-color: #f0f2f6;
} }
......
<script>
import { mapState } from "vuex";
const { getDesktopDevice } = require("@/server/utils/store");
export default {
props: {
user: {
default: () => ({
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" }
},
data() {
return {};
},
computed: {
...mapState([
"defaultProportion",
"countryList",
"orderType",
"grid",
"imgList"
])
},
mounted() {
this.$nextTick(() => {
this.$refs.searchRef?.focus();
if (this.desktopDevice !== 3) {
this.selectGridIndex = 0;
this.setting.gridValue = 0;
} else {
this.selectGridIndex = 5;
this.setting.gridValue = 5;
}
});
this.$store.commit("changeDesktopDevice", getDesktopDevice());
},
created() {
localStorage.setItem("desktoVersion", "print");
if (this.$dataStore.get("setting")) {
this.setting = this.$dataStore.get("setting");
} else {
this.$dataStore.set("setting", this.setting);
}
},
methods: {
dropdownCommand(v) {
switch (v) {
case "logout":
this.$confirm("是否退出登录?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$dataStore.delete("user");
this.$router.push("/");
})
.catch(() => {});
break;
case "cache":
this.checkList = [];
this.cacheVisible = true;
break;
}
},
getCountryName(code) {
if (code) {
const item = this.countryList?.find(el => el.countryCode == code);
if (item) {
return `(${item.nameCn})`;
}
}
return "";
},
goBack() {
// Vue路由返回
this.$router.back();
// 如果需要关闭当前弹窗/子窗口,搭配:
// ipcRenderer.send("close-current-win");
},
goSetting() {
this.$router.push({
path: "/DTFsetting",
query: { id: 123 }
});
},
getDataInfo() {},
productionCompleted() {
this.$confirm("确认完成生产?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {})
.catch(() => {});
}
}
};
</script>
<template>
<div>
<div class="page-header">
<el-form style="display: flex;flex-wrap: nowrap;" inline>
<el-form-item>
<el-button
icon="el-icon-arrow-left"
@click="goBack"
style="margin-right:12px;"
type="text"
>返回</el-button
></el-form-item
>
<el-form-item> <el-input></el-input></el-form-item>
<el-form-item label="操作单状态"> <el-input></el-input></el-form-item>
<el-form-item>
<el-button @click="getDataInfo" type="primary"
>查询
</el-button></el-form-item
>
<el-form-item>
<el-button @click="productionCompleted" type="success"
>生产完成
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting" type="success"
>下载素材
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting" type="success"
>排版
</el-button></el-form-item
>
<el-form-item>
<el-button @click="() => {}" type="success"
>查看排版文件
</el-button></el-form-item
>
</el-form>
<div class="right-user">
<div
v-if="user && user.factory"
style="font-weight: 700;margin-left: 8px;"
>
{{
user.factory.countryCode
? `${user.factory.countryCode}${getCountryName(
user.factory.countryCode
)}`
: "CN(中国)"
}}
</div>
<p v-if="user && user.factory">{{ user.factory.title }}</p>
<el-dropdown @command="dropdownCommand">
<div style="margin-right: 20px">
<b style="cursor:pointer;">{{ user.account }}</b>
<i class="el-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.right-user {
display: flex;
align-items: center;
b {
margin: 0 3px;
display: inline-block;
color: black;
font-size: 15px;
font-weight: bold;
}
p {
margin: 0 10px;
font-weight: bold;
display: inline-block;
font-size: 15px;
color: #e6a23c;
}
}
.page-header {
display: flex;
justify-content: space-between;
background-color: #ececec;
padding: 5px;
.el-form-item {
margin-bottom: 0;
}
}
</style>
<script>
import BaseCard from "../../components/BaseCard.vue";
import DTFhead from "./components/detailHead.vue";
const { getProductType, setProductType } = require("@/server/utils/store");
const { remote } = require("electron");
const { Menu } = remote;
import dayjs from "dayjs";
export default {
name: "dtfBatchDetail",
components: { BaseCard, DTFhead },
props: {
user: {
default: () => ({
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" },
cardConfig: {
imageSrc: "./src/assets/template-bg-1.jpg",
title: "title",
time: "time"
}
},
data() {
return {
pageInfo: {
pageNum: 1,
pageSize: 10,
total: 2
},
detailRow: {
name: { label: "批次号", value: 111 },
name1: { label: "操作单数量", value: 111 },
name2: { label: "素材数量", value: 111 },
name3: { label: "工艺类型", value: 111 },
name6: { label: "规范素材", value: 111 },
name4: { label: "创建时间", value: 111 },
name5: { label: "排版状态", value: 111 },
name7: { label: "操作单状态", value: 111 }
},
item: {},
activeName: getProductType()
};
},
mounted() {
console.log(this.tableList);
},
methods: {
tabClick(tab) {
if (tab.name == "DTG")
this.$router.push({
name: "design"
});
setProductType(tab.name);
},
loadData() {
// 请求列表接口
},
handleSelect(rows) {
console.log("选中行", rows);
},
handleSizeChange(size) {
this.pageInfo.pageSize = size;
this.pageInfo.pageNum = 1;
this.loadData();
},
handleCurrentChange(page) {
this.pageInfo.pageNum = page;
this.loadData();
},
copyText(text) {
navigator.clipboard.writeText(text);
// ElMessage.success("复制成功");
},
getOrderDelayText(createTime) {
if (!createTime) return "--";
const createAt = dayjs(createTime);
if (!createAt.isValid()) return "--";
const diffMinutes = Math.max(0, dayjs().diff(createAt, "minute"));
const baseHours = Math.floor(diffMinutes / 60);
const remainMinutes = diffMinutes % 60;
const hours = baseHours + (remainMinutes > 30 ? 1 : 0);
return `${hours}h`;
},
openMenu(e) {
e.preventDefault();
const template = [
{ label: "全部选择", click: () => console.log("全部选择") },
{ label: "取消选择", click: () => console.log("取消选择") }
];
const menu = Menu.buildFromTemplate(template);
menu.popup({ x: e.clientX, y: e.clientY });
},
getItemTags(tagsId) {},
handleViewDetail(tagsId) {},
setProductMark(tagsId) {},
parseImageAry(tagsId) {},
openLogDialog(tagsId) {}
}
};
</script>
<template>
<div style="height:100%" @contextmenu.prevent="openMenu">
<el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
<el-tab-pane label="DTG生产" name="DTG"> /></el-tab-pane>
<el-tab-pane label="DTF生产" name="DTF">
<div class="page">
<DTFhead :user="user" :factoryType="factoryType"></DTFhead>
<div class="rowBox">
<div
class="rowItem"
v-for="(item, index) in detailRow"
:key="index"
>
<div
style="display: flex;
flex-direction: column; align-items: center;"
>
<div>{{ item.label }}</div>
<div>{{ item.value }}</div>
</div>
</div>
</div>
<div class="card-content">
<div class="card-grid">
<div class="card-grid-item" v-for="value in 20" :key="value">
<BaseCard
style="cursor: pointer;"
:card-item="item"
:active="true"
:show-sku="false"
:show-product-info="false"
:image-field="'variantImage'"
:padding-top="'100%'"
>
<template #bottom_left>
<span
class="operation-number"
:title="`操作单号:${item.operationNo}`"
@click.stop="() => {}"
>
{{ item.operationNo }}
</span>
</template>
<template #top_left>
<el-tooltip
v-if="item.outOfStock"
effect="light"
content="缺货"
placement="bottom"
>
<div
style="
background-color: #f56c6c;
color: #fff;
padding: 2px 4px;
border-radius: 4px;
font-size: 12px;
"
>
</div>
</el-tooltip>
<span v-if="item.tagsId" class="flex-row flex-row-gap6">
<el-tag
v-for="tag in getItemTags(item.tagsId)"
:key="tag.id"
>
{{ tag.name }}
</el-tag>
</span>
</template>
<template #images>
<div class="flex-between">
<div class="images-position">
<div class="images-container">
<div
v-for="(img, index) in parseImageAry(item.imageAry)"
:key="index"
:title="img.title"
class="item-image"
>
<el-image
:src="img.url"
height="50"
:preview-src-list="
parseImageAry(item.imageAry).map(i => i.url)
"
:initial-index="index"
/>
</div>
</div>
</div>
<div class="flex-row flex-row-gap15">
<el-tooltip
class="item"
effect="dark"
:content="'用户编码: ' + item?.userMark"
placement="bottom"
>
<span
style="
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
display: inline-block;
"
@click.stop="copyText(String(item?.userMark || ''))"
>
{{ item?.userMark || "AAAF" }}
</span>
</el-tooltip>
<img
v-if="item.platform"
:src="''"
style="width: 30px; height: 30px"
/>
</div>
</div>
</template>
<template #operations>
<div class="flex-row flex-row-gap6">
<div
v-if="
item?.productMark === 'custom_normal' ||
item?.productMark === 'normal'
"
class="product-mark-badge"
:title="`类型:${setProductMark(item?.productMark)}类`"
>
{{ setProductMark(item?.productMark) }}
</div>
<div
v-if="item.customizedQuantity"
class="quantity-badge"
:class="
item.customizedQuantity === 1
? 'single-quantity-badge-color'
: 'multiple-quantity-badge-color'
"
:title="
`类型:${
item.customizedQuantity === 1 ? '单面' : '双面'
}`
"
>
{{ item.customizedQuantity === 1 ? "单" : "多" }}
</div>
<el-icon
name="caozuorizhi"
style="width: 28px; height: 28px"
@click.stop="openLogDialog(item)"
>
<template #title>
<title>操作日志</title>
</template>
</el-icon>
<el-icon
name="chakanxiangqing"
@click.stop="handleViewDetail(item)"
>
<template #title>
<title>查看详情</title>
</template>
</el-icon>
</div>
</template>
<template #info>
<div class="card-info-grid">
<div class="card-info-row full">
<span
class="info-value ellipsis"
:title="item.productName || ''"
>
{{ item.productName }}
</span>
</div>
<div class="card-info-row">
<span
class="info-value clickable ellipsis"
:title="`变体SKU:${item.variantSku || ''}`"
@click.stop="copyText(item.variantSku || '')"
>
{{ item.variantSku }}
</span>
</div>
<div class="card-info-row">
<span class="info-label">工艺:</span>
<span class="info-value">{{ item.craftName }}</span>
</div>
<div class="card-info-row">
<span
class="info-value clickable ellipsis"
:title="`库存SKU:${item.thirdSkuCode || ''}`"
@click.stop="copyText(item.thirdSkuCode || '')"
>
{{ item.thirdSkuCode }}
</span>
</div>
<div class="card-info-row">
<span class="info-label">店铺单号:</span>
<span
class="info-value clickable ellipsis"
:title="`店铺单号:${item.shopNumber || ''}`"
@click.stop="copyText(item.shopNumber || '')"
>{{ item.shopNumber }}</span
>
</div>
<div class="card-info-row">
<span class="info-label">款号:</span>
<span
class="info-value clickable ellipsis"
:title="`款号:${item.supplierProductNo || ''}`"
@click.stop="copyText(item.supplierProductNo || '')"
>{{ item.supplierProductNo }}</span
>
</div>
<div class="card-info-row">
<span class="info-label">客户单号:</span>
<span
class="info-value clickable ellipsis"
:title="`客户单号:${item.thirdOrderNumber || ''}`"
@click.stop="copyText(item.thirdOrderNumber || '')"
>{{ item.thirdOrderNumber }}</span
>
</div>
<div class="card-info-row">
<span class="info-label">批次号:</span>
<span
class="info-value clickable ellipsis"
:title="`批次号:${item.batchArrangeNumber || ''}`"
@click.stop="copyText(item.batchArrangeNumber || '')"
>{{ item.batchArrangeNumber }}</span
>
</div>
<div class="card-info-row" style="color: red">
<span class="info-label">状态:</span>
<span class="info-value">{{ item.statusName }}</span>
</div>
<div class="card-info-row full delay-time-row">
<span
class="delay-time-value"
:title="
`订单延期:${getOrderDelayText(
item.orderCreateTime
)}`
"
>
{{ getOrderDelayText(item.orderCreateTime) }}
</span>
</div>
</div>
</template>
</BaseCard>
</div>
</div>
</div>
<div class="table-pagination">
<el-pagination
small
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageInfo.pageNum"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<style scoped lang="less">
.page {
display: flex;
flex-direction: column;
height: calc(100% - 25px);
}
.table-pagination {
margin: 10px 0;
text-align: center;
}
::v-deep {
.el-tabs {
height: 100%;
border-bottom: none;
}
.el-tabs__header {
margin: 0;
background-color: #c6c6c6;
// height: 20px;
}
.el-tabs__header .el-tabs__item {
font-size: 12px;
line-height: 25px;
height: 25px;
// border-bottom: none;
}
.el-tabs--border-card > .el-tabs__content {
padding: 0;
height: 100%;
}
.el-tab-pane {
height: 100%;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
border: none;
background-color: #243151;
color: #fff;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
border: none;
}
.el-tabs--border-card
> .el-tabs__header
.el-tabs__item:not(.is-disabled):hover {
color: #fff;
// background-color: #5b647c;
}
}
.rowBox {
display: grid;
grid-template-columns: repeat(8, 1fr);
justify-items: center;
align-items: center;
background-color: #f3f3f3;
padding: 10px 0;
.rowItem {
width: 100%;
border-right: 1px solid #c6c6c6;
:nth-last-child {
border: none;
}
}
}
.card-content {
height: 100%;
flex: 1;
overflow-y: auto;
}
.card-pagination {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.card-selected-info {
font-size: 14px;
color: #606266;
.highlight {
color: red;
font-weight: bold;
}
}
.card-grid {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
grid-template-rows: max-content;
gap: 10px;
padding: 5px;
}
.operation-number {
font-size: 12px;
cursor: pointer;
background: rgba(255, 255, 255, 0.75);
padding: 2px 6px;
border-radius: 4px;
max-width: 100%;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.quantity-badge {
background-color: #f56c6c;
color: #fff;
padding: 5px 8px;
border-radius: 4px;
font-size: 12px;
}
.multiple-quantity-badge-color {
background-color: #e6a23c;
}
.product-mark-badge {
border: 2px solid #f56c6c;
color: #f56c6c;
font-weight: 700;
height: 28px;
width: 28px;
text-align: center;
border-radius: 6px;
font-size: 16px;
}
.card-info-grid {
display: grid;
grid-template-columns: 1fr 150px;
gap: 4px;
font-size: 12px;
margin-top: 6px;
.full {
grid-column: 1 / -1;
}
}
.card-info-row {
display: flex;
overflow: hidden;
}
.delay-time-row {
justify-content: flex-end;
margin-top: 2px;
}
.delay-time-value {
color: red;
font-weight: 600;
}
.info-label {
flex-shrink: 0;
color: #909399;
}
.info-value {
flex: 1;
min-width: 0;
&.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.clickable {
cursor: pointer;
color: #409eff;
&:hover {
text-decoration: underline;
}
}
}
.flex-between {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
overflow: hidden;
gap: 6px;
.images-position {
flex: 1;
overflow: auto hidden;
.images-container {
width: 100%;
display: flex;
gap: 6px;
}
.item-image {
width: 50px;
min-width: 50px;
height: 50px;
border: 1px solid #eee;
cursor: pointer;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
b {
margin-right: 5px;
font-size: 15px;
}
}
.flex-row {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.flex-row-gap15 {
gap: 15px;
}
.flex-row-gap6 {
gap: 6px;
}
@media (max-width: 1920px) {
.card-grid {
grid-template-columns: repeat(7, minmax(0, 1fr));
}
}
@media (max-width: 1750px) {
.card-grid {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
.card-info-grid {
grid-template-columns: 1fr 180px;
}
}
@media (max-width: 1550px) {
.card-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.card-info-grid {
grid-template-columns: 1fr 200px;
}
}
</style>
<template>
<div style="height:100%">
<el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
<el-tab-pane label="DTG生产" name="DTG"> /></el-tab-pane>
<el-tab-pane label="DTF生产" name="DTF">
<div class="dtf-file-page">
<!-- 返回按钮 -->
<div class="page-top">
<el-button icon="el-icon-arrow-left" text @click="goBack">
返回
</el-button>
</div>
<el-card class="file-card">
<template #header>
<div class="card-header">
<span>下载文件夹</span>
</div>
</template>
<div class="file-breadcrumb">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item
><a style="vertical-align: middle;"
><img src="../../assets/computer.png" alt="" width="18"/></a
></el-breadcrumb-item>
<el-breadcrumb-item><a>活动管理</a></el-breadcrumb-item>
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="file-content">
<div v-for="value in 100" :key="value" class="imgBox">
<img
src="../../assets/file.png"
alt=""
width="80"
height="80"
/>
<div>test</div>
</div>
</div>
</el-card>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
const { ipcRenderer } = require("electron");
const { getProductType, setProductType } = require("@/server/utils/store");
export default {
name: "dtfFileDownLoad",
data() {
return {
// 表单配置,可从本地配置文件读取初始化
form: {
// 素材超宽处理:autoScale / skip / biggerSize
overWidthMode: "autoScale",
// 最大素材数模式:batch / custom
maxPicMode: "batch",
// 自定义素材数量
customPicNum: 30,
// 自动排版规格 40+2 / 60 / none
autoLayoutType: "none",
// 默认下载目录
downloadDir: "C:\\Users\\95487\\Desktop\\Test_JMGZ_260530021.png"
},
activeName: getProductType()
};
},
mounted() {
// 页面加载读取本地配置回填表单
this.loadLocalConfig();
},
methods: {
// 返回上一页
goBack() {
this.$router.push({
name: "design"
});
},
// 读取本地配置
async loadLocalConfig() {
ipcRenderer.send("read-layout-config");
ipcRenderer.once("layout-config-data", (_, cfg) => {
if (cfg) {
this.form = Object.assign({}, this.form, cfg);
}
});
},
// 选择文件夹弹窗
selectFolder() {
ipcRenderer.send("request-select-folder");
ipcRenderer.once("select-folder-result", (_, path) => {
if (path) this.form.downloadDir = path;
});
},
// 保存配置到本地文件
saveConfig() {
ipcRenderer.send("save-layout-config", this.form);
this.$message.success("排版设置保存成功!");
},
tabClick(tab) {
if (tab.name == "DTG") this.goBack();
setProductType(tab.name);
}
}
};
</script>
<style lang="less" scoped>
.dtf-file-page {
padding: 16px;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.page-top {
margin-bottom: 12px;
}
::v-deep.file-card {
width: 100%;
height: calc(100% - 90px);
.file-breadcrumb {
padding: 10px 20px;
background-color: #f3f3f3;
}
.el-card__body {
padding: 0;
height: 100%;
}
}
.card-header {
display: flex;
align-items: center;
gap: 8px;
font-size: 20px;
font-weight: 700;
}
.file-group {
margin-bottom: 24px;
}
.group-title {
font-size: 20px;
color: #303133;
margin-bottom: 10px;
}
.el-radio-group {
display: flex;
flex-direction: column;
gap: 10px;
padding: 12px 16px;
border: 1px solid #e4e7ed;
border-radius: 4px;
}
.custom-num-row {
display: flex;
align-items: center;
}
.dir-input-row {
display: flex;
align-items: center;
gap: 8px;
}
.btn-wrap {
margin-top: 30px;
text-align: left;
}
.el-radio-group {
.el-radio {
padding: 10px 0;
font-size: 18px;
}
}
::v-deep {
.el-tabs {
height: 100%;
border-bottom: none;
}
.el-tabs__header {
margin: 0;
background-color: #c6c6c6;
// height: 20px;
}
.el-tabs__header .el-tabs__item {
font-size: 12px;
line-height: 25px;
height: 25px;
// border-bottom: none;
}
.el-tabs--border-card > .el-tabs__content {
padding: 0;
height: 100%;
}
.el-tab-pane {
height: 100%;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
border: none;
background-color: #243151;
color: #fff;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
border: none;
}
.el-tabs--border-card
> .el-tabs__header
.el-tabs__item:not(.is-disabled):hover {
color: #fff;
// background-color: #5b647c;
}
}
.file-content {
display: grid;
grid-template-columns: repeat(10, minmax(0, 1fr));
grid-template-rows: max-content;
gap: 10px;
padding: 20px;
overflow-y: auto;
height: calc(100% - 150px);
.imgBox {
text-align: center;
}
}
.el-breadcrumb {
font-size: 18px;
}
</style>
<script>
import { mapState } from "vuex";
const { getDesktopDevice } = require("@/server/utils/store");
export default {
props: {
user: {
default: () => ({
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" }
},
data() {
return {};
},
computed: {
...mapState([
"defaultProportion",
"countryList",
"orderType",
"grid",
"imgList"
])
},
mounted() {
this.$nextTick(() => {
this.$refs.searchRef?.focus();
if (this.desktopDevice !== 3) {
this.selectGridIndex = 0;
this.setting.gridValue = 0;
} else {
this.selectGridIndex = 5;
this.setting.gridValue = 5;
}
});
this.$store.commit("changeDesktopDevice", getDesktopDevice());
},
created() {
localStorage.setItem("desktoVersion", "print");
if (this.$dataStore.get("setting")) {
this.setting = this.$dataStore.get("setting");
} else {
this.$dataStore.set("setting", this.setting);
}
},
methods: {
dropdownCommand(v) {
switch (v) {
case "logout":
this.$confirm("是否退出登录?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$dataStore.delete("user");
this.$router.push("/");
})
.catch(() => {});
break;
case "cache":
this.checkList = [];
this.cacheVisible = true;
break;
}
},
getCountryName(code) {
if (code) {
const item = this.countryList?.find(el => el.countryCode == code);
if (item) {
return `(${item.nameCn})`;
}
}
return "";
},
goBack() {
// Vue路由返回
this.$router.push({
name: "design"
});
// 如果需要关闭当前弹窗/子窗口,搭配:
// ipcRenderer.send("close-current-win");
},
goSetting() {
this.$router.push({
name: "dtfSetting"
});
},
goSetting1() {
this.$router.push({
name: "dtfBatchDetail"
});
},
getDataInfo() {}
}
};
</script>
<template>
<div>
<div class="page-header">
<el-form style="display: flex;flex-wrap: nowrap;" inline>
<el-form-item label="批次号"> <el-input></el-input></el-form-item>
<el-form-item label="排版状态"> <el-input></el-input></el-form-item>
<el-form-item label="创建时间"> <el-input></el-input></el-form-item>
<el-form-item>
<el-button @click="getDataInfo" type="primary"
>查询
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting" type="success"
>DTF排版设置
</el-button></el-form-item
>
<el-form-item>
<el-button @click="goSetting1" type="success"
>详情页
</el-button></el-form-item
>
</el-form>
<div class="right-user">
<div
v-if="user && user.factory"
style="font-weight: 700;margin-left: 8px;"
>
{{
user.factory.countryCode
? `${user.factory.countryCode}${getCountryName(
user.factory.countryCode
)}`
: "CN(中国)"
}}
</div>
<p v-if="user && user.factory">{{ user.factory.title }}</p>
<el-dropdown @command="dropdownCommand">
<div style="margin-right: 20px">
<b style="cursor:pointer;">{{ user.account }}</b>
<i class="el-icon-arrow-down"></i>
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.right-user {
display: flex;
align-items: center;
b {
margin: 0 3px;
display: inline-block;
color: black;
font-size: 15px;
font-weight: bold;
}
p {
margin: 0 10px;
font-weight: bold;
display: inline-block;
font-size: 15px;
color: #e6a23c;
}
}
.page-header {
display: flex;
justify-content: space-between;
background-color: #ececec;
padding: 5px;
.el-form-item {
margin-bottom: 0;
}
}
</style>
<script>
import BaseTable from "../../components/BaseTable.vue";
import DTFhead from "./components/head.vue";
export default {
name: "DtfFile",
components: { BaseTable, DTFhead },
props: {
user: {
default: () => ({
avatar: "",
factory: {}
}),
type: Object
},
factoryType: { type: String, default: "CN" }
},
data() {
return {
pageInfo: {
pageNum: 1,
pageSize: 10,
total: 2
},
tableList: Array.from({ length: 50 }, (_, index) => {
const isDtg = index % 2 === 0;
return {
id: index + 1,
name: index + 1,
status: index % 3 === 0 ? 0 : 1,
img: isDtg ? "/static/dtg.jpg" : "/static/dtf.jpg",
open: index % 4 !== 0,
price: isDtg ? 120 + index * 2 : 86 + index,
remark: ""
};
}),
tableConfig: [
{
prop: "name",
label: "批次号",
width: 100
},
{
prop: "price",
label: "操作单数量",
width: 100,
// 自定义渲染函数
render: row => ${row.price}.00`
},
{
prop: "status",
label: "素材数量",
width: 100,
type: "tag",
// 动态标签文字
getTagText: row => (row.status === 1 ? "启用" : "停用"),
// 动态标签颜色
getTagType: row => (row.status === 1 ? "success" : "danger")
},
{
prop: "img",
label: "工艺类型",
width: 100,
type: "image"
},
{
prop: "open",
label: "规范素材",
width: 100,
type: "switch",
onSwitchChange: row => {
console.log("切换上架状态", row);
}
},
{
label: "创建时间",
slotName: "remark" // 绑定外部自定义插槽
},
{
label: "排版状态",
width: 140,
slotName: "remark" // 绑定外部自定义插槽
},
{
label: "失败原因",
width: 300,
slotName: "remark" // 绑定外部自定义插槽
},
{
label: "排版参数",
width: 300,
slotName: "remark" // 绑定外部自定义插槽
},
{
label: "操作",
width: 260,
slotName: "operation"
}
]
};
},
mounted() {
console.log(this.tableList);
},
methods: {
loadData() {
// 请求列表接口
},
handleSelect(rows) {
console.log("选中行", rows);
},
handleSizeChange(size) {
this.pageInfo.pageSize = size;
this.pageInfo.pageNum = 1;
this.loadData();
},
handleCurrentChange(page) {
this.pageInfo.pageNum = page;
this.loadData();
},
goFliePage() {
this.$router.push({
name: "dtfFileDownLoad"
});
}
}
};
</script>
<template>
<div class="page">
<DTFhead :user="user" :factoryType="factoryType"></DTFhead>
<BaseTable
:table-data="tableList"
:table-config="tableConfig"
:has-selection="true"
:has-index="true"
:page-info="pageInfo"
@page-size-change="handleSizeChange"
@page-current-change="handleCurrentChange"
@selection="handleSelect"
border
stripe
height="100%"
size="mini"
>
<!-- 自定义插槽示例 -->
<template #remark="scope">
<el-input v-model="scope.row.remark" size="mini" />
</template>
<template #operation>
<div class="flex" style="justify-content: space-between;">
<el-button type="text" class="btn flex btnBox">
<img src="../../assets/download.png" width="30" height="30" />
<div>下载素材</div></el-button
>
<el-button type="text" class="btn flex btnBox"
><img src="../../assets/typesetting.png" width="30" height="30" />
<div>排版</div>
</el-button>
<el-button type="text" class="btn flex btnBox" @click="goFliePage">
<img src="../../assets/file.png" width="30" height="30" />
<div>查看排版文件</div>
</el-button>
</div>
</template>
</BaseTable>
<!-- <BaseCard></BaseCard> -->
</div>
</template>
<style scoped lang="less">
.page {
height: "100%";
}
.flex {
display: flex;
}
.btnBox {
flex-direction: column;
align-items: center;
}
.btn {
padding: 0;
}
</style>
<template>
<div style="height:100%">
<el-tabs type="border-card" v-model="activeName" @tab-click="tabClick">
<el-tab-pane label="DTG生产" name="DTG"> /></el-tab-pane>
<el-tab-pane label="DTF生产" name="DTF">
<div class="dtf-setting-page">
<!-- 返回按钮 -->
<div class="page-top">
<el-button icon="el-icon-arrow-left" text @click="goBack">
返回
</el-button>
</div>
<el-card class="setting-card">
<template #header>
<div class="card-header">
<i
class="el-icon-setting"
style="color: #568cf9;font-size: 24px;margin-right: 8px;"
></i>
<span>DTF排版设置</span>
</div>
</template>
<div class="setting-group">
<div class="group-title">素材超排版宽度时:</div>
<el-radio-group v-model="form.overWidthMode">
<el-radio label="autoScale"
>自动缩小素材,适配烫画模宽度</el-radio
>
<el-radio label="skip">超出排版宽度不排版</el-radio>
<el-radio label="biggerSize"
>超出排版宽度,使用更大规格排版</el-radio
>
</el-radio-group>
</div>
<div class="setting-group">
<div class="group-title">单张排版最大素材数:</div>
<el-radio-group v-model="form.maxPicMode">
<el-radio label="batch">批次素材数</el-radio>
<div class="custom-num-row">
<el-radio label="custom">自定义素材数(建议数量30):</el-radio>
<el-input
v-model.number="form.customPicNum"
placeholder="请输入素材数"
style="width: 180px; margin-left: 8px"
:disabled="form.maxPicMode !== 'custom'"
/>
</div>
</el-radio-group>
</div>
<div class="setting-group">
<div class="group-title">自动排版设置</div>
<el-radio-group v-model="form.autoLayoutType">
<el-radio label="40+2">40+2</el-radio>
<el-radio label="60">60</el-radio>
<el-radio label="none">不执行自动排版</el-radio>
</el-radio-group>
</div>
<div class="setting-group">
<div class="group-title">下载文件目录</div>
<div class="dir-input-row">
<el-input v-model="form.downloadDir" readonly style="flex: 1">
<template slot="prepend">素材默认下载位置:</template>
</el-input>
<el-button
icon="el-icon-folder-opened"
@click="selectFolder"
></el-button>
</div>
</div>
<div class="btn-wrap">
<el-button type="primary" @click="saveConfig">保存设置</el-button>
</div>
</el-card>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
const { ipcRenderer } = require("electron");
const { getProductType, setProductType } = require("@/server/utils/store");
export default {
name: "dtfSetting",
data() {
return {
// 表单配置,可从本地配置文件读取初始化
form: {
// 素材超宽处理:autoScale / skip / biggerSize
overWidthMode: "autoScale",
// 最大素材数模式:batch / custom
maxPicMode: "batch",
// 自定义素材数量
customPicNum: 30,
// 自动排版规格 40+2 / 60 / none
autoLayoutType: "none",
// 默认下载目录
downloadDir: "C:\\Users\\95487\\Desktop\\Test_JMGZ_260530021.png"
},
activeName: getProductType()
};
},
mounted() {
// 页面加载读取本地配置回填表单
this.loadLocalConfig();
},
methods: {
// 返回上一页
goBack() {
this.$router.push({
name: "design"
});
},
// 读取本地配置
async loadLocalConfig() {
ipcRenderer.send("read-layout-config");
ipcRenderer.once("layout-config-data", (_, cfg) => {
if (cfg) {
this.form = Object.assign({}, this.form, cfg);
}
});
},
// 选择文件夹弹窗
selectFolder() {
ipcRenderer.send("request-select-folder");
ipcRenderer.once("select-folder-result", (_, path) => {
if (path) this.form.downloadDir = path;
});
},
// 保存配置到本地文件
saveConfig() {
ipcRenderer.send("save-layout-config", this.form);
this.$message.success("排版设置保存成功!");
},
tabClick(tab) {
if (tab.name == "DTG") this.goBack();
setProductType(tab.name);
}
}
};
</script>
<style lang="less" scoped>
.dtf-setting-page {
padding: 16px;
width: 100%;
height: 100%;
box-sizing: border-box;
}
.page-top {
margin-bottom: 12px;
}
.setting-card {
width: 100%;
}
.card-header {
display: flex;
align-items: center;
gap: 8px;
font-size: 20px;
font-weight: 700;
}
.setting-group {
margin-bottom: 24px;
}
.group-title {
font-size: 20px;
color: #303133;
margin-bottom: 10px;
}
.el-radio-group {
display: flex;
flex-direction: column;
gap: 10px;
padding: 12px 16px;
border: 1px solid #e4e7ed;
border-radius: 4px;
}
.custom-num-row {
display: flex;
align-items: center;
}
.dir-input-row {
display: flex;
align-items: center;
gap: 8px;
}
.btn-wrap {
margin-top: 30px;
text-align: left;
}
.setting-card {
::v-deep {
.el-card__header {
border-bottom: none;
}
.el-card__body {
padding: 10px 200px;
}
}
}
.el-radio-group {
.el-radio {
padding: 10px 0;
font-size: 18px;
}
}
::v-deep {
.el-tabs {
height: 100%;
border-bottom: none;
}
.el-tabs__header {
margin: 0;
background-color: #c6c6c6;
// height: 20px;
}
.el-tabs__header .el-tabs__item {
font-size: 12px;
line-height: 25px;
height: 25px;
// border-bottom: none;
}
.el-tabs--border-card > .el-tabs__content {
padding: 0;
height: 100%;
}
.el-tab-pane {
height: 100%;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
border: none;
background-color: #243151;
color: #fff;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item {
border: none;
}
.el-tabs--border-card
> .el-tabs__header
.el-tabs__item:not(.is-disabled):hover {
color: #fff;
// background-color: #5b647c;
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment