Compare commits
24 Commits
2f2a152b46
...
test
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b1e9cc8a9 | |||
| 598609e050 | |||
| 13bd39fbed | |||
| ea5a4c14e9 | |||
| ffad9432c5 | |||
| 6d09813aa4 | |||
| e2338b3888 | |||
| c7f22e193a | |||
| 50139a5e57 | |||
| 209be704e1 | |||
| 6a20930a7d | |||
| 506dcbb804 | |||
| 75e46ec6dd | |||
| c87c999d42 | |||
| f648a7ea5e | |||
| 0ab8852656 | |||
| 03883e1b26 | |||
| b9308c1f21 | |||
| be12089ffe | |||
| e5cdf0a3dc | |||
| 51812fb0cc | |||
| 6e39a94f01 | |||
| d6a33aea3b | |||
| 397f4b2bcf |
@@ -65,9 +65,10 @@
|
|||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.13",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
|
"vue-draggable-plus": "^0.6.1",
|
||||||
"vue-i18n": "^11.1.0",
|
"vue-i18n": "^11.1.0",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"ysk-utils": "^1.0.85"
|
"ysk-utils": "^1.0.91"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^19.7.1",
|
"@commitlint/cli": "^19.7.1",
|
||||||
|
|||||||
12
src/App.vue
@@ -3,7 +3,17 @@
|
|||||||
<!-- 开启水印 -->
|
<!-- 开启水印 -->
|
||||||
<el-watermark :font="{ color: fontColor }" :content="watermarkEnabled ? defaultSettings.watermarkContent : ''"
|
<el-watermark :font="{ color: fontColor }" :content="watermarkEnabled ? defaultSettings.watermarkContent : ''"
|
||||||
:z-index="9999" class="wh-full">
|
:z-index="9999" class="wh-full">
|
||||||
<router-view />
|
<!-- 🔴 修改开始:使用 v-slot 处理路由组件 -->
|
||||||
|
<router-view v-slot="{ Component, route }">
|
||||||
|
<!--
|
||||||
|
1. 使用 <transition> 包裹,防止渲染冲突
|
||||||
|
2. 加上 :key="route.path" 强制 Vue 在路由变化时重新渲染,避免复用导致的空白
|
||||||
|
-->
|
||||||
|
<transition name="fade" mode="out-in">
|
||||||
|
<component :is="Component" :key="route.path" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
|
<!-- 🟢 修改结束 -->
|
||||||
</el-watermark>
|
</el-watermark>
|
||||||
</el-config-provider>
|
</el-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -27,11 +27,34 @@ const Api = {
|
|||||||
method: "post",
|
method: "post",
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
// 排序
|
||||||
|
sort(params: sortRequest) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}/sort`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Api;
|
export default Api;
|
||||||
|
export interface sortRequest {
|
||||||
|
/**
|
||||||
|
* 拖动的支付类型ID
|
||||||
|
*/
|
||||||
|
id: number;
|
||||||
|
/**
|
||||||
|
* 店铺ID
|
||||||
|
*/
|
||||||
|
shopId: number;
|
||||||
|
/**
|
||||||
|
* 目标位置排序号
|
||||||
|
*/
|
||||||
|
targetSort: number;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
interface getRequset {
|
interface getRequset {
|
||||||
id?: string
|
id?: string
|
||||||
|
|||||||
@@ -59,6 +59,22 @@ const ShopApi = {
|
|||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 重置密码
|
||||||
|
putPassword(data: any) {
|
||||||
|
return request({
|
||||||
|
url: `/account/admin/sysUser/pwd`,
|
||||||
|
method: "put",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 续期记录
|
||||||
|
registerRecord(params: any) {
|
||||||
|
return request({
|
||||||
|
url: `${baseURL}/registerRecord`,
|
||||||
|
method: "get",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ShopApi;
|
export default ShopApi;
|
||||||
|
|||||||
@@ -45,14 +45,13 @@ const API = {
|
|||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 重置密码
|
||||||
pwd(data: any) {
|
pwd(data: any) {
|
||||||
return request({
|
return request({
|
||||||
url: `${baseURL}/pwd`,
|
url: `${baseURL}/pwd`,
|
||||||
method: "put",
|
method: "put",
|
||||||
data
|
data
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
,
|
|
||||||
|
|
||||||
}
|
}
|
||||||
export default API;
|
export default API;
|
||||||
|
|||||||
@@ -12,6 +12,19 @@ export const getRegion = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有短信签名
|
||||||
|
* @param params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const getSms = ({ type }: { type: string }) => {
|
||||||
|
return request<any, any[]>({
|
||||||
|
url: `/account/admin/common/sms`,
|
||||||
|
method: "get",
|
||||||
|
params: { type }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有银行
|
* 获取所有银行
|
||||||
* @param params
|
* @param params
|
||||||
|
|||||||
26
src/api/order/fince.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import request from "@/utils/request";
|
||||||
|
import { Order_BaseUrl } from "@/api/config";
|
||||||
|
const baseURL = Order_BaseUrl + "/admin";
|
||||||
|
const FinanceApi = {
|
||||||
|
financeBase(params: Request) {
|
||||||
|
return request<any, any>({
|
||||||
|
url: `${baseURL}/finance/base`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface Request {
|
||||||
|
/**
|
||||||
|
* 日期yyyy-MM-dd
|
||||||
|
*/
|
||||||
|
date: string;
|
||||||
|
shopId: number;
|
||||||
|
type: string;
|
||||||
|
[property: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default FinanceApi;
|
||||||
@@ -89,6 +89,22 @@ const OrderApi = {
|
|||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 打印经营日报
|
||||||
|
printDayReport(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${Order_BaseUrl}/admin/finance/printDayReport`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 打印日结单
|
||||||
|
printDaySettle(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${Order_BaseUrl}/admin/finance/printDaySettle`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default OrderApi;
|
export default OrderApi;
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ const Api = {
|
|||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 商品报表打印
|
||||||
|
print(params: any) {
|
||||||
|
return request<any>({
|
||||||
|
url: `${baseURL}/print`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Api;
|
export default Api;
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ const AuthAPI = {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 商品-标记自动售罄
|
||||||
|
markIsAutoSoldOut(data: Object) {
|
||||||
|
return request<any, Responseres>({
|
||||||
|
url: `${baseURL}/markIsAutoSoldOut`,
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
},
|
||||||
// 删除
|
// 删除
|
||||||
deleteByIds(id: number | String) {
|
deleteByIds(id: number | String) {
|
||||||
return request<any, Responseres>({
|
return request<any, Responseres>({
|
||||||
@@ -72,7 +80,7 @@ const AuthAPI = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 耗材列表
|
// 耗材列表分页
|
||||||
productcons(params: any) {
|
productcons(params: any) {
|
||||||
return request<any, Responseres>({
|
return request<any, Responseres>({
|
||||||
url: `/product/admin/product/cons/page`,
|
url: `/product/admin/product/cons/page`,
|
||||||
@@ -80,7 +88,22 @@ const AuthAPI = {
|
|||||||
params
|
params
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
// 耗材列表
|
||||||
|
productconsList(params: any) {
|
||||||
|
return request<any, Responseres>({
|
||||||
|
url: `/product/admin/product/cons/list`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 耗材列表
|
||||||
|
consStock(params: any) {
|
||||||
|
return request<any, Responseres>({
|
||||||
|
url: `/product/admin/product/cons/consStock`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
|
},
|
||||||
// 上下架
|
// 上下架
|
||||||
onOff(data: any) {
|
onOff(data: any) {
|
||||||
return request<any, Responseres>({
|
return request<any, Responseres>({
|
||||||
@@ -190,6 +213,14 @@ const AuthAPI = {
|
|||||||
params,
|
params,
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
// 商品-批量操作
|
||||||
|
batchOperate(params: any) {
|
||||||
|
return request<any, Responseres>({
|
||||||
|
url: `${baseURL}/batchOperate`,
|
||||||
|
method: "get",
|
||||||
|
params
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
BIN
src/assets/index_bg.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/index_quick1.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
src/assets/index_quick2.png
Normal file
|
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/index_quick3.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
src/assets/index_quick4.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
src/assets/index_quick5.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
BIN
src/assets/index_quick6.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
@@ -3,43 +3,64 @@
|
|||||||
<!-- 表格工具栏 -->
|
<!-- 表格工具栏 -->
|
||||||
<div class="flex-x-between mb-[10px]">
|
<div class="flex-x-between mb-[10px]">
|
||||||
<!-- 左侧工具栏 -->
|
<!-- 左侧工具栏 -->
|
||||||
<div style="display: flex;">
|
<div style="display: flex">
|
||||||
<template v-for="item in toolbar" :key="item">
|
<template v-for="item in toolbar" :key="item">
|
||||||
<template v-if="typeof item === 'string'">
|
<template v-if="typeof item === 'string'">
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<template v-if="item === 'add'">
|
<template v-if="item === 'add'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item}`]" type="primary" icon="plus"
|
<el-button
|
||||||
@click="handleToolbar(item)">
|
v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
||||||
|
type="primary"
|
||||||
|
icon="plus"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<!-- 删除 -->
|
<!-- 删除 -->
|
||||||
<template v-else-if="item === 'delete'">
|
<template v-else-if="item === 'delete'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item}`]" type="danger" icon="delete"
|
<el-button
|
||||||
:disabled="removeIds.length === 0" @click="handleToolbar(item)">
|
v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
||||||
|
type="danger"
|
||||||
|
icon="delete"
|
||||||
|
:disabled="removeIds.length === 0"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<!-- 导入 -->
|
<!-- 导入 -->
|
||||||
<template v-else-if="item === 'import'">
|
<template v-else-if="item === 'import'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item}`]" type="default" icon="upload"
|
<el-button
|
||||||
@click="handleToolbar(item)">
|
v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
||||||
|
type="default"
|
||||||
|
icon="upload"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
>
|
||||||
导入
|
导入
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<!-- 导出 -->
|
<!-- 导出 -->
|
||||||
<template v-else-if="item === 'export'">
|
<template v-else-if="item === 'export'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item}`]" type="default" icon="download"
|
<el-button
|
||||||
@click="handleToolbar(item)">
|
v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
||||||
|
type="default"
|
||||||
|
icon="download"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
>
|
||||||
导出
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<template v-else-if="typeof item === 'object'">
|
<template v-else-if="typeof item === 'object'">
|
||||||
<el-button v-if="item.hidden === undefined || item.hidden === false"
|
<el-button
|
||||||
v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]" :icon="item.icon" :type="item.type ?? 'default'"
|
v-if="item.hidden === undefined || item.hidden === false"
|
||||||
@click="handleToolbar(item.name)">
|
v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
|
||||||
|
:icon="item.icon"
|
||||||
|
:type="item.type ?? 'default'"
|
||||||
|
@click="handleToolbar(item.name)"
|
||||||
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -70,36 +91,68 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- 导出 -->
|
<!-- 导出 -->
|
||||||
<template v-else-if="item === 'exports'">
|
<template v-else-if="item === 'exports'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:export`]" icon="download" circle title="导出"
|
<el-button
|
||||||
@click="handleToolbar(item)" />
|
v-hasPerm="[`${contentConfig.pageName}:export`]"
|
||||||
|
icon="download"
|
||||||
|
circle
|
||||||
|
title="导出"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<!-- 导入 -->
|
<!-- 导入 -->
|
||||||
<template v-else-if="item === 'imports'">
|
<template v-else-if="item === 'imports'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:import`]" icon="upload" circle title="导入"
|
<el-button
|
||||||
@click="handleToolbar(item)" />
|
v-hasPerm="[`${contentConfig.pageName}:import`]"
|
||||||
|
icon="upload"
|
||||||
|
circle
|
||||||
|
title="导入"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<template v-else-if="item === 'search'">
|
<template v-else-if="item === 'search'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:query`]" icon="search" circle title="搜索"
|
<el-button
|
||||||
@click="handleToolbar(item)" />
|
v-hasPerm="[`${contentConfig.pageName}:query`]"
|
||||||
|
icon="search"
|
||||||
|
circle
|
||||||
|
title="搜索"
|
||||||
|
@click="handleToolbar(item)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<template v-else-if="typeof item === 'object'">
|
<template v-else-if="typeof item === 'object'">
|
||||||
<template v-if="item.auth">
|
<template v-if="item.auth">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]" :icon="item.icon" circle
|
<el-button
|
||||||
:title="item.title" @click="handleToolbar(item.name)" />
|
v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
|
||||||
|
:icon="item.icon"
|
||||||
|
circle
|
||||||
|
:title="item.title"
|
||||||
|
@click="handleToolbar(item.name)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-button :icon="item.icon" circle :title="item.title" @click="handleToolbar(item.name)" />
|
<el-button
|
||||||
|
:icon="item.icon"
|
||||||
|
circle
|
||||||
|
:title="item.title"
|
||||||
|
@click="handleToolbar(item.name)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<el-table ref="tableRef" v-loading="loading" v-bind="contentConfig.table" :data="pageData" :row-key="pk"
|
<el-table
|
||||||
@selection-change="handleSelectionChange" @filter-change="handleFilterChange">
|
ref="tableRef"
|
||||||
|
v-loading="loading"
|
||||||
|
v-bind="contentConfig.table"
|
||||||
|
:data="pageData"
|
||||||
|
:row-key="pk"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
@filter-change="handleFilterChange"
|
||||||
|
>
|
||||||
<template v-for="col in cols" :key="col">
|
<template v-for="col in cols" :key="col">
|
||||||
<el-table-column v-if="col.show" v-bind="col">
|
<el-table-column v-if="col.show" v-bind="col">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -108,15 +161,24 @@
|
|||||||
<template v-if="col.prop">
|
<template v-if="col.prop">
|
||||||
<template v-if="Array.isArray(scope.row[col.prop])">
|
<template v-if="Array.isArray(scope.row[col.prop])">
|
||||||
<template v-for="(item, index) in scope.row[col.prop]" :key="item">
|
<template v-for="(item, index) in scope.row[col.prop]" :key="item">
|
||||||
<el-image :src="item" :preview-src-list="scope.row[col.prop]" :initial-index="index"
|
<el-image
|
||||||
:preview-teleported="true" :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40
|
:src="item"
|
||||||
}px`" />
|
:preview-src-list="scope.row[col.prop]"
|
||||||
|
:initial-index="index"
|
||||||
|
:preview-teleported="true"
|
||||||
|
:style="`width: ${col.imageWidth ?? 40}px; height: ${
|
||||||
|
col.imageHeight ?? 40
|
||||||
|
}px`"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-image :src="scope.row[col.prop]" :preview-src-list="[scope.row[col.prop]]"
|
<el-image
|
||||||
|
:src="scope.row[col.prop]"
|
||||||
|
:preview-src-list="[scope.row[col.prop]]"
|
||||||
:preview-teleported="true"
|
:preview-teleported="true"
|
||||||
:style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`" />
|
:style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
@@ -138,20 +200,30 @@
|
|||||||
<template v-else-if="col.templet === 'switch'">
|
<template v-else-if="col.templet === 'switch'">
|
||||||
<template v-if="col.prop">
|
<template v-if="col.prop">
|
||||||
<!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 -->
|
<!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 -->
|
||||||
<el-switch v-model="scope.row[col.prop]" :active-value="col.activeValue ?? 1"
|
<el-switch
|
||||||
:inactive-value="col.inactiveValue ?? 0" :inline-prompt="true" :active-text="col.activeText ?? ''"
|
v-model="scope.row[col.prop]"
|
||||||
:inactive-text="col.inactiveText ?? ''" :validate-event="false"
|
:active-value="col.activeValue ?? 1"
|
||||||
:disabled="!hasAuth(`${contentConfig.pageName}:modify`)" @change="
|
:inactive-value="col.inactiveValue ?? 0"
|
||||||
|
:inline-prompt="true"
|
||||||
|
:active-text="col.activeText ?? ''"
|
||||||
|
:inactive-text="col.inactiveText ?? ''"
|
||||||
|
:validate-event="false"
|
||||||
|
:disabled="!hasAuth(`${contentConfig.pageName}:modify`)"
|
||||||
|
@change="
|
||||||
pageData.length > 0 && handleModify(col.prop, scope.row[col.prop], scope.row)
|
pageData.length > 0 && handleModify(col.prop, scope.row[col.prop], scope.row)
|
||||||
" />
|
"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<!-- 生成输入框组件 -->
|
<!-- 生成输入框组件 -->
|
||||||
<template v-else-if="col.templet === 'input'">
|
<template v-else-if="col.templet === 'input'">
|
||||||
<template v-if="col.prop">
|
<template v-if="col.prop">
|
||||||
<el-input v-model="scope.row[col.prop]" :type="col.inputType ?? 'text'"
|
<el-input
|
||||||
|
v-model="scope.row[col.prop]"
|
||||||
|
:type="col.inputType ?? 'text'"
|
||||||
:disabled="!hasAuth(`${contentConfig.pageName}:modify`)"
|
:disabled="!hasAuth(`${contentConfig.pageName}:modify`)"
|
||||||
@blur="handleModify(col.prop, scope.row[col.prop], scope.row)" />
|
@blur="handleModify(col.prop, scope.row[col.prop], scope.row)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<!-- 格式化为价格 -->
|
<!-- 格式化为价格 -->
|
||||||
@@ -183,7 +255,7 @@
|
|||||||
{{
|
{{
|
||||||
scope.row[col.prop]
|
scope.row[col.prop]
|
||||||
? useDateFormat(scope.row[col.prop], col.dateFormat ?? "YYYY-MM-DD HH:mm:ss")
|
? useDateFormat(scope.row[col.prop], col.dateFormat ?? "YYYY-MM-DD HH:mm:ss")
|
||||||
.value
|
.value
|
||||||
: ""
|
: ""
|
||||||
}}
|
}}
|
||||||
</template>
|
</template>
|
||||||
@@ -194,15 +266,21 @@
|
|||||||
<template v-if="typeof item === 'string'">
|
<template v-if="typeof item === 'string'">
|
||||||
<!-- 编辑/删除 -->
|
<!-- 编辑/删除 -->
|
||||||
<template v-if="item === 'edit' || item === 'delete'">
|
<template v-if="item === 'edit' || item === 'delete'">
|
||||||
<el-button v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
<el-button
|
||||||
:type="item === 'edit' ? 'primary' : 'danger'" :icon="item" size="small" link @click="
|
v-hasPerm="[`${contentConfig.pageName}:${item}`]"
|
||||||
|
:type="item === 'edit' ? 'primary' : 'danger'"
|
||||||
|
:icon="item"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="
|
||||||
handleOperat({
|
handleOperat({
|
||||||
name: item,
|
name: item,
|
||||||
row: scope.row,
|
row: scope.row,
|
||||||
column: scope.column,
|
column: scope.column,
|
||||||
$index: scope.$index,
|
$index: scope.$index,
|
||||||
})
|
})
|
||||||
">
|
"
|
||||||
|
>
|
||||||
{{ item === "edit" ? "编辑" : "删除" }}
|
{{ item === "edit" ? "编辑" : "删除" }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -210,43 +288,63 @@
|
|||||||
<!-- 其他 -->
|
<!-- 其他 -->
|
||||||
<template v-else-if="typeof item === 'object'">
|
<template v-else-if="typeof item === 'object'">
|
||||||
<template v-if="item.hidden === undefined || item.hidden === false">
|
<template v-if="item.hidden === undefined || item.hidden === false">
|
||||||
<el-button v-if="item.isBtn" v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
|
<el-button
|
||||||
:icon="item.icon" :type="item.type ?? 'primary'" size="small" link @click="
|
v-if="item.isBtn"
|
||||||
|
v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
|
||||||
|
:icon="item.icon"
|
||||||
|
:type="item.type ?? 'primary'"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="
|
||||||
handleOperat({
|
handleOperat({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
row: scope.row,
|
row: scope.row,
|
||||||
column: scope.column,
|
column: scope.column,
|
||||||
$index: scope.$index,
|
$index: scope.$index,
|
||||||
})
|
})
|
||||||
">
|
"
|
||||||
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
<el-dropdown style="margin-top: 4px" v-else>
|
<el-dropdown style="margin-top: 4px" v-else>
|
||||||
<el-button v-if="item.render === undefined || item.render(scope.row)" v-bind="item.auth
|
<el-button
|
||||||
? { 'v-hasPerm': [`${contentConfig.pageName}:${item.auth}`] }
|
v-if="item.render === undefined || item.render(scope.row)"
|
||||||
: {}
|
v-bind="
|
||||||
" :icon="item.icon" :type="item.type ?? 'primary'" size="small" link @click="
|
item.auth
|
||||||
|
? { 'v-hasPerm': [`${contentConfig.pageName}:${item.auth}`] }
|
||||||
|
: {}
|
||||||
|
"
|
||||||
|
:icon="item.icon"
|
||||||
|
:type="item.type ?? 'primary'"
|
||||||
|
size="small"
|
||||||
|
link
|
||||||
|
@click="
|
||||||
handleOperat({
|
handleOperat({
|
||||||
name: item.name,
|
name: item.name,
|
||||||
row: scope.row,
|
row: scope.row,
|
||||||
column: scope.column,
|
column: scope.column,
|
||||||
$index: scope.$index,
|
$index: scope.$index,
|
||||||
})
|
})
|
||||||
">
|
"
|
||||||
|
>
|
||||||
{{ item.text }}
|
{{ item.text }}
|
||||||
</el-button>
|
</el-button>
|
||||||
<template #dropdown v-if="item.options && item.options.length > 0">
|
<template #dropdown v-if="item.options && item.options.length > 0">
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item @click="
|
<el-dropdown-item
|
||||||
handleOperat({
|
@click="
|
||||||
name: item.name,
|
handleOperat({
|
||||||
row: scope.row,
|
name: item.name,
|
||||||
column: scope.column,
|
row: scope.row,
|
||||||
$index: scope.$index,
|
column: scope.column,
|
||||||
command: opt.command ? opt.command : '',
|
$index: scope.$index,
|
||||||
})
|
command: opt.command ? opt.command : '',
|
||||||
" v-for="opt in item.options" :key="opt.value">
|
})
|
||||||
|
"
|
||||||
|
v-for="opt in item.options"
|
||||||
|
:key="opt.value"
|
||||||
|
>
|
||||||
{{ opt.label }}
|
{{ opt.label }}
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@@ -268,18 +366,33 @@
|
|||||||
<template v-if="showPagination">
|
<template v-if="showPagination">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<div class="mt-[12px]">
|
<div class="mt-[12px]">
|
||||||
<el-pagination v-bind="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
<el-pagination
|
||||||
|
v-bind="pagination"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
<!-- 导出弹窗 -->
|
<!-- 导出弹窗 -->
|
||||||
<el-dialog v-model="exportsModalVisible" :align-center="true" title="导出数据" width="600px" style="padding-right: 0"
|
<el-dialog
|
||||||
@close="handleCloseExportsModal">
|
v-model="exportsModalVisible"
|
||||||
|
:align-center="true"
|
||||||
|
title="导出数据"
|
||||||
|
width="600px"
|
||||||
|
style="padding-right: 0"
|
||||||
|
@close="handleCloseExportsModal"
|
||||||
|
>
|
||||||
<!-- 滚动 -->
|
<!-- 滚动 -->
|
||||||
<el-scrollbar max-height="60vh">
|
<el-scrollbar max-height="60vh">
|
||||||
<!-- 表单 -->
|
<!-- 表单 -->
|
||||||
<el-form ref="exportsFormRef" label-width="auto" style="padding-right: var(--el-dialog-padding-primary)"
|
<el-form
|
||||||
:model="exportsFormData" :rules="exportsFormRules">
|
ref="exportsFormRef"
|
||||||
|
label-width="auto"
|
||||||
|
style="padding-right: var(--el-dialog-padding-primary)"
|
||||||
|
:model="exportsFormData"
|
||||||
|
:rules="exportsFormRules"
|
||||||
|
>
|
||||||
<el-form-item label="文件名" prop="filename">
|
<el-form-item label="文件名" prop="filename">
|
||||||
<el-input v-model="exportsFormData.filename" clearable />
|
<el-input v-model="exportsFormData.filename" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -289,10 +402,16 @@
|
|||||||
<el-form-item label="数据源" prop="origin">
|
<el-form-item label="数据源" prop="origin">
|
||||||
<el-select v-model="exportsFormData.origin">
|
<el-select v-model="exportsFormData.origin">
|
||||||
<el-option label="当前数据 (当前页的数据)" :value="ExportsOriginEnum.CURRENT" />
|
<el-option label="当前数据 (当前页的数据)" :value="ExportsOriginEnum.CURRENT" />
|
||||||
<el-option label="选中数据 (所有选中的数据)" :value="ExportsOriginEnum.SELECTED"
|
<el-option
|
||||||
:disabled="selectionData.length <= 0" />
|
label="选中数据 (所有选中的数据)"
|
||||||
<el-option label="全量数据 (所有分页的数据)" :value="ExportsOriginEnum.REMOTE"
|
:value="ExportsOriginEnum.SELECTED"
|
||||||
:disabled="contentConfig.exportsAction === undefined" />
|
:disabled="selectionData.length <= 0"
|
||||||
|
/>
|
||||||
|
<el-option
|
||||||
|
label="全量数据 (所有分页的数据)"
|
||||||
|
:value="ExportsOriginEnum.REMOTE"
|
||||||
|
:disabled="contentConfig.exportsAction === undefined"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字段" prop="fields">
|
<el-form-item label="字段" prop="fields">
|
||||||
@@ -313,17 +432,35 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 导入弹窗 -->
|
<!-- 导入弹窗 -->
|
||||||
<el-dialog v-model="importModalVisible" :align-center="true" title="导入数据" width="600px" style="padding-right: 0"
|
<el-dialog
|
||||||
@close="handleCloseImportModal">
|
v-model="importModalVisible"
|
||||||
|
:align-center="true"
|
||||||
|
title="导入数据"
|
||||||
|
width="600px"
|
||||||
|
style="padding-right: 0"
|
||||||
|
@close="handleCloseImportModal"
|
||||||
|
>
|
||||||
<!-- 滚动 -->
|
<!-- 滚动 -->
|
||||||
<el-scrollbar max-height="60vh">
|
<el-scrollbar max-height="60vh">
|
||||||
<!-- 表单 -->
|
<!-- 表单 -->
|
||||||
<el-form ref="importFormRef" label-width="auto" style="padding-right: var(--el-dialog-padding-primary)"
|
<el-form
|
||||||
:model="importFormData" :rules="importFormRules">
|
ref="importFormRef"
|
||||||
|
label-width="auto"
|
||||||
|
style="padding-right: var(--el-dialog-padding-primary)"
|
||||||
|
:model="importFormData"
|
||||||
|
:rules="importFormRules"
|
||||||
|
>
|
||||||
<el-form-item label="文件名" prop="files">
|
<el-form-item label="文件名" prop="files">
|
||||||
<el-upload ref="uploadRef" v-model:file-list="importFormData.files" class="w-full"
|
<el-upload
|
||||||
|
ref="uploadRef"
|
||||||
|
v-model:file-list="importFormData.files"
|
||||||
|
class="w-full"
|
||||||
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
|
||||||
:drag="true" :limit="1" :auto-upload="false" :on-exceed="handleFileExceed">
|
:drag="true"
|
||||||
|
:limit="1"
|
||||||
|
:auto-upload="false"
|
||||||
|
:on-exceed="handleFileExceed"
|
||||||
|
>
|
||||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||||
<div class="el-upload__text">
|
<div class="el-upload__text">
|
||||||
<span>将文件拖到此处,或</span>
|
<span>将文件拖到此处,或</span>
|
||||||
@@ -332,8 +469,13 @@
|
|||||||
<template #tip>
|
<template #tip>
|
||||||
<div class="el-upload__tip">
|
<div class="el-upload__tip">
|
||||||
*.xlsx / *.xls
|
*.xlsx / *.xls
|
||||||
<el-link v-if="contentConfig.importTemplate" type="primary" icon="download" :underline="false"
|
<el-link
|
||||||
@click="handleDownloadTemplate">
|
v-if="contentConfig.importTemplate"
|
||||||
|
type="primary"
|
||||||
|
icon="download"
|
||||||
|
:underline="false"
|
||||||
|
@click="handleDownloadTemplate"
|
||||||
|
>
|
||||||
下载模板
|
下载模板
|
||||||
</el-link>
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -345,7 +487,11 @@
|
|||||||
<!-- 弹窗底部操作按钮 -->
|
<!-- 弹窗底部操作按钮 -->
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div style="padding-right: var(--el-dialog-padding-primary)">
|
<div style="padding-right: var(--el-dialog-padding-primary)">
|
||||||
<el-button type="primary" :disabled="importFormData.files.length === 0" @click="handleImportSubmit">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:disabled="importFormData.files.length === 0"
|
||||||
|
@click="handleImportSubmit"
|
||||||
|
>
|
||||||
确 定
|
确 定
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="handleCloseImportModal">取 消</el-button>
|
<el-button @click="handleCloseImportModal">取 消</el-button>
|
||||||
@@ -386,6 +532,7 @@ const emit = defineEmits<{
|
|||||||
editClick: [row: IObject];
|
editClick: [row: IObject];
|
||||||
operatClick: [data: IOperatData];
|
operatClick: [data: IOperatData];
|
||||||
filterChange: [data: IObject];
|
filterChange: [data: IObject];
|
||||||
|
selectChange: []
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
// 主键
|
// 主键
|
||||||
@@ -490,6 +637,7 @@ function handleSelectionChange(selection: any[]) {
|
|||||||
console.log("defaultSelData.value", defaultSelData.value);
|
console.log("defaultSelData.value", defaultSelData.value);
|
||||||
selectionData.value = selection;
|
selectionData.value = selection;
|
||||||
removeIds.value = selection.map((item) => item[pk]);
|
removeIds.value = selection.map((item) => item[pk]);
|
||||||
|
emit('selectChange', getselectTable())
|
||||||
}
|
}
|
||||||
// 获取选中的表格数据
|
// 获取选中的表格数据
|
||||||
function getselectTable() {
|
function getselectTable() {
|
||||||
@@ -861,10 +1009,10 @@ function fetchPageData(formData: IObject = {}, isRestart = false) {
|
|||||||
.indexAction(
|
.indexAction(
|
||||||
showPagination
|
showPagination
|
||||||
? {
|
? {
|
||||||
[request.pageName]: pagination.currentPage,
|
[request.pageName]: pagination.currentPage,
|
||||||
[request.limitName]: pagination.pageSize,
|
[request.limitName]: pagination.pageSize,
|
||||||
...formData,
|
...formData,
|
||||||
}
|
}
|
||||||
: formData
|
: formData
|
||||||
)
|
)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
@@ -929,7 +1077,7 @@ function saveXlsx(fileData: BlobPart, fileName: string) {
|
|||||||
document.body.removeChild(downloadLink);
|
document.body.removeChild(downloadLink);
|
||||||
window.URL.revokeObjectURL(downloadUrl);
|
window.URL.revokeObjectURL(downloadUrl);
|
||||||
}
|
}
|
||||||
function test(rows: any[]) { }
|
function test(rows: any[]) {}
|
||||||
|
|
||||||
const defaultSelData = ref<IObject[]>([]);
|
const defaultSelData = ref<IObject[]>([]);
|
||||||
// 设置默认选择
|
// 设置默认选择
|
||||||
@@ -964,6 +1112,7 @@ defineExpose({
|
|||||||
pagination,
|
pagination,
|
||||||
test,
|
test,
|
||||||
setSelectTable,
|
setSelectTable,
|
||||||
|
pageData,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ const formItems = reactive(props.searchConfig.formItems);
|
|||||||
// 是否可展开/收缩
|
// 是否可展开/收缩
|
||||||
const isExpandable = ref(props.searchConfig.isExpandable ?? true);
|
const isExpandable = ref(props.searchConfig.isExpandable ?? true);
|
||||||
// 是否已展开
|
// 是否已展开
|
||||||
const isExpand = ref(false);
|
const isExpand = ref(props.searchConfig.isExpand ?? false);
|
||||||
// 表单项展示数量,若可展开,超出展示数量的表单项隐藏
|
// 表单项展示数量,若可展开,超出展示数量的表单项隐藏
|
||||||
const showNumber = computed(() => {
|
const showNumber = computed(() => {
|
||||||
if (isExpandable.value === true) {
|
if (isExpandable.value === true) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export interface ISearchConfig {
|
|||||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||||
pageName: string;
|
pageName: string;
|
||||||
inline?: Boolean;
|
inline?: Boolean;
|
||||||
|
isExpand?: boolean;
|
||||||
// 表单项
|
// 表单项
|
||||||
formItems: Array<{
|
formItems: Array<{
|
||||||
// 组件类型(如input,select等)
|
// 组件类型(如input,select等)
|
||||||
@@ -58,6 +59,7 @@ export interface ISearchConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IContentConfig<T = any> {
|
export interface IContentConfig<T = any> {
|
||||||
|
rowDraggable?: boolean;
|
||||||
resultListKey?: string;
|
resultListKey?: string;
|
||||||
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
// 页面名称(参与组成权限标识,如sys:user:xxx)
|
||||||
pageName: string;
|
pageName: string;
|
||||||
@@ -189,6 +191,7 @@ export interface IContentConfig<T = any> {
|
|||||||
| "icon"
|
| "icon"
|
||||||
| "date"
|
| "date"
|
||||||
| "tool"
|
| "tool"
|
||||||
|
| "drag-handle"
|
||||||
| "custom";
|
| "custom";
|
||||||
// image模板相关参数
|
// image模板相关参数
|
||||||
imageWidth?: number;
|
imageWidth?: number;
|
||||||
|
|||||||
@@ -5,18 +5,8 @@
|
|||||||
<el-input v-model="searhForm.name" placeholder="商品名称"></el-input>
|
<el-input v-model="searhForm.name" placeholder="商品名称"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-select
|
<el-select style="width: 200px" v-model="searhForm.category" placeholder="商品分类" :disabled="disableCategory">
|
||||||
style="width: 200px"
|
<el-option :label="item.name" :value="item.id" v-for="item in categoryList" :key="item.id"></el-option>
|
||||||
v-model="searhForm.category"
|
|
||||||
placeholder="商品分类"
|
|
||||||
:disabled="disableCategory"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.id"
|
|
||||||
v-for="item in categoryList"
|
|
||||||
:key="item.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -25,7 +15,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-table ref="table" :data="tableData.list" height="500" v-loading="tableData.loading">
|
<el-table ref="table" :data="tableData.list" height="500" border stripe v-loading="tableData.loading">
|
||||||
<el-table-column type="selection" width="55" align="center" v-if="!radio"></el-table-column>
|
<el-table-column type="selection" width="55" align="center" v-if="!radio"></el-table-column>
|
||||||
<el-table-column label="商品信息">
|
<el-table-column label="商品信息">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
@@ -72,14 +62,9 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<el-pagination
|
<el-pagination :total="tableData.total" :current-page="tableData.page" :page-size="tableData.size"
|
||||||
:total="tableData.total"
|
@current-change="paginationChange" @size-change="sizeChange"
|
||||||
:current-page="tableData.page"
|
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||||
:page-size="tableData.size"
|
|
||||||
@current-change="paginationChange"
|
|
||||||
@size-change="sizeChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
></el-pagination>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer" v-if="!radio">
|
<span class="dialog-footer" v-if="!radio">
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
@@ -132,7 +117,7 @@ export default {
|
|||||||
},
|
},
|
||||||
// 确定选商品
|
// 确定选商品
|
||||||
confirmHandle() {
|
confirmHandle() {
|
||||||
let res = this.$refs.table.selection;
|
let res = this.$refs.table.getSelectionRows();
|
||||||
console.log(res);
|
console.log(res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return ElMessage.error("请选择商品");
|
return ElMessage.error("请选择商品");
|
||||||
@@ -148,6 +133,7 @@ export default {
|
|||||||
this.tableData.page = 1;
|
this.tableData.page = 1;
|
||||||
this.tableData.size = 10;
|
this.tableData.size = 10;
|
||||||
this.tableData.list = [];
|
this.tableData.list = [];
|
||||||
|
this.getTableData();
|
||||||
},
|
},
|
||||||
// 分页大小改变
|
// 分页大小改变
|
||||||
sizeChange(e) {
|
sizeChange(e) {
|
||||||
|
|||||||
305
src/components/importData/index copy.vue
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
<!-- 批量导入数据dialog -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="btn_row">
|
||||||
|
<el-button type="success" icon="RefreshRight" @click="updateData">数据更新</el-button>
|
||||||
|
|
||||||
|
<el-button type="primary" icon="Upload" @click="show">批量导入</el-button>
|
||||||
|
<el-button icon="Download" @click="downloadTemplateAjax">下载银收客模板</el-button>
|
||||||
|
</div>
|
||||||
|
<el-dialog
|
||||||
|
title="批量导入"
|
||||||
|
width="800px"
|
||||||
|
v-model="visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
@close="dialogClose"
|
||||||
|
>
|
||||||
|
<div class="row">
|
||||||
|
<tabHeader v-model="tabActive" :list="tabs" />
|
||||||
|
</div>
|
||||||
|
<div class="row mt14">
|
||||||
|
<div class="import_container" v-if="tabActive == 0">
|
||||||
|
<div class="header_title">第一步:选择模板</div>
|
||||||
|
<div class="row mt14 pb50">
|
||||||
|
<div class="list">
|
||||||
|
<div
|
||||||
|
class="item"
|
||||||
|
:class="{ active: platformActive == index }"
|
||||||
|
v-for="(item, index) in platformList"
|
||||||
|
:key="item.id"
|
||||||
|
@click="selectPlatform(item)"
|
||||||
|
>
|
||||||
|
<img class="img" :src="item.img" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header_title">
|
||||||
|
第二步:上传文件
|
||||||
|
<span>单次仅可上传一个文件</span>
|
||||||
|
</div>
|
||||||
|
<div class="row mt14">
|
||||||
|
<GfileUpload
|
||||||
|
v-model="form.files"
|
||||||
|
:accept="platformList[platformActive]?.file_type || ''"
|
||||||
|
:limit="1"
|
||||||
|
@file-selected="fileSelected"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="row mt14">
|
||||||
|
<div class="footer_wrap">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:disabled="!form.files.length"
|
||||||
|
:loading="loading"
|
||||||
|
@click="startImportHandle"
|
||||||
|
>
|
||||||
|
<template v-if="!form.files.length">请选择文件</template>
|
||||||
|
<template v-else>开始导入</template>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-table :data="tableData" border stripe v-if="tabActive == 1" height="419px">
|
||||||
|
<el-table-column prop="file_name" label="文件名称" width="300" />
|
||||||
|
<el-table-column prop="created_time" label="导入时间" width="200" />
|
||||||
|
<el-table-column prop="status_text" label="导入状态" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag v-if="scope.row.status == 0" type="info" disable-transitions>
|
||||||
|
待处理...
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.status == 1" type="warning" disable-transitions>
|
||||||
|
处理中...
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.status == 2" type="success" disable-transitions>
|
||||||
|
处理完成
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.status == -1" type="danger" disable-transitions>
|
||||||
|
导入失败
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="importResult" label="导入结果">
|
||||||
|
<template #default="scope">
|
||||||
|
<template v-if="scope.row.status == 2">
|
||||||
|
<div class="column">
|
||||||
|
<div>
|
||||||
|
<el-text type="success">成功:{{ scope.row.success_num }} 条</el-text>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-text type="danger">失败:{{ scope.row.fail_num }} 条</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import { getplatlist, uploadFile, importlist, downloadTemp } from "@/importDataApi/index.js";
|
||||||
|
import GfileUpload from "../Upload/GfileUpload.vue";
|
||||||
|
import tabHeader from "@/views/marketing_center/components/tabHeader.vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
type: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 3, // 3商品 4台桌区域 5台桌 6会员 7菜品销售统计 8台桌销售统计 9订单销售统计
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const platformList = ref([]);
|
||||||
|
const platformActive = ref(0);
|
||||||
|
function selectPlatform(item) {
|
||||||
|
form.value.files = [];
|
||||||
|
platformActive.value = platformList.value.findIndex((i) => i.id === item.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tabs = ref([
|
||||||
|
{ label: "导入数据", name: "importData" },
|
||||||
|
{ label: "导入记录", name: "importRecord" },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const tabActive = ref(0);
|
||||||
|
|
||||||
|
watch(tabActive, (newVal) => {
|
||||||
|
if (newVal === 1) {
|
||||||
|
getImportRecord();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const form = ref({
|
||||||
|
files: [],
|
||||||
|
platform: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
function fileSelected(file) {
|
||||||
|
console.log("fileSelected", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始导入
|
||||||
|
async function startImportHandle() {
|
||||||
|
try {
|
||||||
|
form.value.platform = platformList.value[platformActive.value]?.id;
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", form.value.files[0].raw);
|
||||||
|
formData.append("shop_id", localStorage.getItem("shopId"));
|
||||||
|
formData.append("type", props.type);
|
||||||
|
formData.append("platform", form.value.platform);
|
||||||
|
loading.value = true;
|
||||||
|
await uploadFile(formData);
|
||||||
|
ElMessage.success("文件上传成功,正在导入数据,请在导入记录中查看导入结果");
|
||||||
|
form.value.files = [];
|
||||||
|
tabActive.value = 1;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取平台列表
|
||||||
|
async function getPlatformList() {
|
||||||
|
try {
|
||||||
|
const res = await getplatlist({ plat_type: props.type });
|
||||||
|
platformList.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入记录
|
||||||
|
const tableData = ref([]);
|
||||||
|
async function getImportRecord() {
|
||||||
|
try {
|
||||||
|
const res = await importlist({ shop_id: localStorage.getItem("shopId") });
|
||||||
|
tableData.value = res;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载模板
|
||||||
|
async function downloadTemplateAjax() {
|
||||||
|
try {
|
||||||
|
const res = await downloadTemp({ plat_type: props.type });
|
||||||
|
window.open(res, "_blank");
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const emits = defineEmits(["close", "update"]);
|
||||||
|
|
||||||
|
function updateData() {
|
||||||
|
// 把 ElMessage 改成 ElMessageBox 就好了
|
||||||
|
ElMessageBox.confirm("确认需要更新经营数据吗?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
emits("update");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
// 取消操作,空着就行
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dialogClose() {
|
||||||
|
emits("close");
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getPlatformList();
|
||||||
|
});
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
visible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.btn_row {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
margin-left: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header_title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999999;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
&.mt14 {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.pb50 {
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.import_container {
|
||||||
|
.list {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 122px;
|
||||||
|
height: 42px;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer_wrap {
|
||||||
|
display: flex;
|
||||||
|
gap: 14px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,11 +2,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="btn_row">
|
<div class="btn_row">
|
||||||
|
<el-button type="success" icon="RefreshRight" @click="updateData">数据更新</el-button>
|
||||||
|
|
||||||
<el-button type="primary" icon="Upload" @click="show">批量导入</el-button>
|
<el-button type="primary" icon="Upload" @click="show">批量导入</el-button>
|
||||||
<el-button icon="Download" @click="downloadTemplateAjax">下载银收客模板</el-button>
|
<el-button icon="Download" @click="downloadTemplateAjax">下载银收客模板</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog title="批量导入" width="800px" v-model="visible" :close-on-click-modal="false" :close-on-press-escape="false"
|
<el-dialog
|
||||||
@close="dialogClose">
|
title="批量导入"
|
||||||
|
width="800px"
|
||||||
|
v-model="visible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:close-on-press-escape="false"
|
||||||
|
@close="dialogClose"
|
||||||
|
>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<tabHeader v-model="tabActive" :list="tabs" />
|
<tabHeader v-model="tabActive" :list="tabs" />
|
||||||
</div>
|
</div>
|
||||||
@@ -15,23 +23,38 @@
|
|||||||
<div class="header_title">第一步:选择模板</div>
|
<div class="header_title">第一步:选择模板</div>
|
||||||
<div class="row mt14 pb50">
|
<div class="row mt14 pb50">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="item" :class="{ active: platformActive == index }" v-for="(item, index) in platformList"
|
<div
|
||||||
:key="item.id" @click="selectPlatform(item)">
|
class="item"
|
||||||
<img class="img" :src="item.img" alt="">
|
:class="{ active: platformActive == index }"
|
||||||
|
v-for="(item, index) in platformList"
|
||||||
|
:key="item.id"
|
||||||
|
@click="selectPlatform(item)"
|
||||||
|
>
|
||||||
|
<img class="img" :src="item.img" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header_title">第二步:上传文件
|
<div class="header_title">
|
||||||
|
第二步:上传文件
|
||||||
<span>单次仅可上传一个文件</span>
|
<span>单次仅可上传一个文件</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt14">
|
<div class="row mt14">
|
||||||
<GfileUpload v-model="form.files" :accept="platformList[platformActive]?.file_type || ''" :limit="1"
|
<GfileUpload
|
||||||
@file-selected="fileSelected" />
|
v-model="form.files"
|
||||||
|
:accept="platformList[platformActive]?.file_type || ''"
|
||||||
|
:limit="1"
|
||||||
|
@file-selected="fileSelected"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt14">
|
<div class="row mt14">
|
||||||
<div class="footer_wrap">
|
<div class="footer_wrap">
|
||||||
<el-button @click="visible = false">取 消</el-button>
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
<el-button type="primary" :disabled="!form.files.length" :loading="loading" @click="startImportHandle">
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:disabled="!form.files.length"
|
||||||
|
:loading="loading"
|
||||||
|
@click="startImportHandle"
|
||||||
|
>
|
||||||
<template v-if="!form.files.length">请选择文件</template>
|
<template v-if="!form.files.length">请选择文件</template>
|
||||||
<template v-else>开始导入</template>
|
<template v-else>开始导入</template>
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -43,10 +66,18 @@
|
|||||||
<el-table-column prop="created_time" label="导入时间" width="200" />
|
<el-table-column prop="created_time" label="导入时间" width="200" />
|
||||||
<el-table-column prop="status_text" label="导入状态" width="150">
|
<el-table-column prop="status_text" label="导入状态" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.status == 0" type="info" disable-transitions>待处理...</el-tag>
|
<el-tag v-if="scope.row.status == 0" type="info" disable-transitions>
|
||||||
<el-tag v-else-if="scope.row.status == 1" type="warning" disable-transitions>处理中...</el-tag>
|
待处理...
|
||||||
<el-tag v-else-if="scope.row.status == 2" type="success" disable-transitions>处理完成</el-tag>
|
</el-tag>
|
||||||
<el-tag v-else-if="scope.row.status == -1" type="danger" disable-transitions>导入失败</el-tag>
|
<el-tag v-else-if="scope.row.status == 1" type="warning" disable-transitions>
|
||||||
|
处理中...
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.status == 2" type="success" disable-transitions>
|
||||||
|
处理完成
|
||||||
|
</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.status == -1" type="danger" disable-transitions>
|
||||||
|
导入失败
|
||||||
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="importResult" label="导入结果">
|
<el-table-column prop="importResult" label="导入结果">
|
||||||
@@ -66,19 +97,45 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 日期选择弹窗 -->
|
||||||
|
<el-dialog
|
||||||
|
v-model="dateDialogVisible"
|
||||||
|
title="选择更新日期"
|
||||||
|
width="500px"
|
||||||
|
@close="dateDialogVisible = false"
|
||||||
|
>
|
||||||
|
<div style="padding: 20px 0">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="selectDate"
|
||||||
|
type="date"
|
||||||
|
label="选择日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dateDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmUpdateDate">确认更新</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, watch } from 'vue';
|
import { ref, onMounted, watch } from "vue";
|
||||||
import { getplatlist, uploadFile, importlist, downloadTemp } from '@/importDataApi/index.js';
|
import { getplatlist, uploadFile, importlist, downloadTemp } from "@/importDataApi/index.js";
|
||||||
import GfileUpload from '../Upload/GfileUpload.vue';
|
import GfileUpload from "../Upload/GfileUpload.vue";
|
||||||
import tabHeader from '@/views/marketing_center/components/tabHeader.vue';
|
import tabHeader from "@/views/marketing_center/components/tabHeader.vue";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: 3, // 3商品 4台桌区域 5台桌 6会员 7菜品销售统计 8台桌销售统计 9订单销售统计
|
default: 3,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -86,15 +143,15 @@ const platformList = ref([]);
|
|||||||
const platformActive = ref(0);
|
const platformActive = ref(0);
|
||||||
function selectPlatform(item) {
|
function selectPlatform(item) {
|
||||||
form.value.files = [];
|
form.value.files = [];
|
||||||
platformActive.value = platformList.value.findIndex(i => i.id === item.id);
|
platformActive.value = platformList.value.findIndex((i) => i.id === item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tabs = ref([
|
const tabs = ref([
|
||||||
{ label: '导入数据', name: 'importData' },
|
{ label: "导入数据", name: "importData" },
|
||||||
{ label: '导入记录', name: 'importRecord' },
|
{ label: "导入记录", name: "importRecord" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tabActive = ref(0)
|
const tabActive = ref(0);
|
||||||
|
|
||||||
watch(tabActive, (newVal) => {
|
watch(tabActive, (newVal) => {
|
||||||
if (newVal === 1) {
|
if (newVal === 1) {
|
||||||
@@ -106,11 +163,16 @@ const visible = ref(false);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const form = ref({
|
const form = ref({
|
||||||
files: [],
|
files: [],
|
||||||
platform: ''
|
platform: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// 日期选择弹窗
|
||||||
|
const dateDialogVisible = ref(false);
|
||||||
|
const today = new Date().toISOString().split("T")[0];
|
||||||
|
const selectDate = ref(today); // 默认当天
|
||||||
|
|
||||||
function fileSelected(file) {
|
function fileSelected(file) {
|
||||||
console.log('fileSelected', file);
|
console.log("fileSelected", file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 开始导入
|
// 开始导入
|
||||||
@@ -118,15 +180,15 @@ async function startImportHandle() {
|
|||||||
try {
|
try {
|
||||||
form.value.platform = platformList.value[platformActive.value]?.id;
|
form.value.platform = platformList.value[platformActive.value]?.id;
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', form.value.files[0].raw);
|
formData.append("file", form.value.files[0].raw);
|
||||||
formData.append('shop_id', localStorage.getItem('shopId'));
|
formData.append("shop_id", localStorage.getItem("shopId"));
|
||||||
formData.append('type', props.type);
|
formData.append("type", props.type);
|
||||||
formData.append('platform', form.value.platform);
|
formData.append("platform", form.value.platform);
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await uploadFile(formData);
|
await uploadFile(formData);
|
||||||
ElMessage.success('文件上传成功,正在导入数据,请在导入记录中查看导入结果');
|
ElMessage.success("文件上传成功,正在导入数据,请在导入记录中查看导入结果");
|
||||||
form.value.files = []
|
form.value.files = [];
|
||||||
tabActive.value = 1
|
tabActive.value = 1;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -149,7 +211,7 @@ async function getPlatformList() {
|
|||||||
const tableData = ref([]);
|
const tableData = ref([]);
|
||||||
async function getImportRecord() {
|
async function getImportRecord() {
|
||||||
try {
|
try {
|
||||||
const res = await importlist({ shop_id: localStorage.getItem('shopId') });
|
const res = await importlist({ shop_id: localStorage.getItem("shopId") });
|
||||||
tableData.value = res;
|
tableData.value = res;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -160,20 +222,38 @@ async function getImportRecord() {
|
|||||||
async function downloadTemplateAjax() {
|
async function downloadTemplateAjax() {
|
||||||
try {
|
try {
|
||||||
const res = await downloadTemp({ plat_type: props.type });
|
const res = await downloadTemp({ plat_type: props.type });
|
||||||
window.open(res, '_blank');
|
window.open(res, "_blank");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const emits = defineEmits(['close'])
|
const emits = defineEmits(["close", "update"]);
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
// 数据更新(打开日期选择框)
|
||||||
|
// ==================================
|
||||||
|
function updateData() {
|
||||||
|
dateDialogVisible.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认选择日期并更新
|
||||||
|
function confirmUpdateDate() {
|
||||||
|
if (!selectDate.value) {
|
||||||
|
ElMessage.warning("请选择日期");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dateDialogVisible.value = false;
|
||||||
|
emits("update", selectDate.value); // 把选中的日期传给父组件
|
||||||
|
// ElMessage.success("已选择日期:" + selectDate.value);
|
||||||
|
}
|
||||||
|
|
||||||
function dialogClose() {
|
function dialogClose() {
|
||||||
emits('close')
|
emits("close");
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPlatformList()
|
getPlatformList();
|
||||||
});
|
});
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
@@ -255,4 +335,4 @@ defineExpose({
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
120
src/components/printBusinessDialog.vue
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="打印确认" width="400px" v-model="showDayBusiness">
|
||||||
|
<div class="business_wrap">
|
||||||
|
<div class="title">
|
||||||
|
<el-text>请选择要打印的日期:</el-text> <el-text type="danger">周期最长为7天</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<el-date-picker v-model="printDayBusinessParams.date" type="daterange" start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" :disabled-date="disabledDate"
|
||||||
|
@change="handleDateChange" clearable />
|
||||||
|
</div>
|
||||||
|
<div class="business_tips">
|
||||||
|
<el-text type="info">若数据过多,打印时间会比较长,请耐心等待</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="showDayBusiness = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmHandle" :loading="printDayBusinessLoading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '经营日报'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const showDayBusiness = ref(false)
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
|
||||||
|
// 打印参数
|
||||||
|
const printDayBusinessParams = ref({
|
||||||
|
date: [],
|
||||||
|
})
|
||||||
|
const printDayBusinessLoading = ref(false)
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const confirmHandle = () => {
|
||||||
|
// 校验日期
|
||||||
|
if (!printDayBusinessParams.value.date || printDayBusinessParams.value.date.length !== 2) {
|
||||||
|
ElMessage.warning('请选择日期范围')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
showDayBusiness.value = false
|
||||||
|
emits('success', { date: printDayBusinessParams.value.date })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期禁用规则:只能选昨天及更早,不能选未来
|
||||||
|
const disabledDate = (time) => {
|
||||||
|
const yesterday = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
|
||||||
|
return dayjs(time).isAfter(yesterday)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日期选择后校验:区间长度不能超过7天
|
||||||
|
const handleDateChange = (val) => {
|
||||||
|
if (!val || val.length !== 2) return
|
||||||
|
const [start, end] = val
|
||||||
|
const days = dayjs(end).diff(start, 'day') + 1 // 包含起止日
|
||||||
|
if (days > 7) {
|
||||||
|
ElMessage.warning('日期范围最多只能选择7天')
|
||||||
|
printDayBusinessParams.value.date = [] // 清空选择
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断当前时间 是否在 00:00 ~ 05:20 之间
|
||||||
|
const time = ref(['00:00', '05:20'])
|
||||||
|
const isInTimeRange = () => {
|
||||||
|
const now = dayjs()
|
||||||
|
const startTime = dayjs(time.value[0], 'HH:mm')
|
||||||
|
const endTime = dayjs(time.value[1], 'HH:mm')
|
||||||
|
return now.isAfter(startTime) && now.isBefore(endTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const show = () => {
|
||||||
|
if (isInTimeRange()) {
|
||||||
|
ElMessage.warning(`当前时间不能打印${props.title},打印时间:${time.value[0]}点至${time.value[1]}点`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
showDayBusiness.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({ show })
|
||||||
|
|
||||||
|
// 初始化默认选中昨天
|
||||||
|
onMounted(() => {
|
||||||
|
const yesterday = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
|
||||||
|
printDayBusinessParams.value.date = [yesterday, yesterday]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.business_wrap {
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
padding-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.business_tips {
|
||||||
|
padding-top: 6px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
83
src/components/refundConsModal.vue
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="提示" width="450px" v-model="visible">
|
||||||
|
<div class="refund_content">
|
||||||
|
<div class="title_wrap">请确认当前菜品是否已上菜</div>
|
||||||
|
<div class="list_wrap">
|
||||||
|
<div class="item" v-for="(item, index) in list" :key="index">
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
<span>x{{ item.num }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dialog_footer">
|
||||||
|
<div class="btn">
|
||||||
|
<el-button @click="handleCancel" style="width: 100%;">未上菜(退还库存)</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="btn">
|
||||||
|
<el-button type="primary" @click="handleOk" style="width: 100%;">已上菜(不退库存)</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
|
||||||
|
// 未上菜 1退菜图库存
|
||||||
|
function handleCancel() {
|
||||||
|
visible.value = false
|
||||||
|
emits('success', 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 已上菜 2仅退菜不退库存
|
||||||
|
function handleOk() {
|
||||||
|
visible.value = false
|
||||||
|
emits('success', 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.refund_content {
|
||||||
|
.title_wrap {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list_wrap {
|
||||||
|
padding-top: 14px;
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog_footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
padding-top: 20px;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
123
src/components/resetPassword/CaptchaBtn.vue
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 验证码按钮 - 纯功能高度定制版 -->
|
||||||
|
<el-button :type="buttonType" :size="buttonSize" :disabled="disabled || isCountingDown" :loading="isLoading"
|
||||||
|
class="captcha-btn" @click="handleGetCaptcha">
|
||||||
|
<!-- 倒计时状态展示 -->
|
||||||
|
<span v-if="isCountingDown">{{ countDown }} 秒后重新获取</span>
|
||||||
|
<!-- 正常状态展示 -->
|
||||||
|
<span v-else>{{ buttonText }}</span>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { getSms } from "@/api/common";
|
||||||
|
|
||||||
|
// 接收父组件传递的自定义参数
|
||||||
|
const props = defineProps({
|
||||||
|
// 验证码类型
|
||||||
|
// editShopInfoOpePwd 店铺操作密码
|
||||||
|
// wxMiniPwd 微信小程序用户登录密码
|
||||||
|
// shopPwd 店铺登录密码
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'editShopInfoOpePwd'
|
||||||
|
},
|
||||||
|
// 按钮类型(primary/success/warning/danger/info/default)
|
||||||
|
buttonType: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary'
|
||||||
|
},
|
||||||
|
// 按钮尺寸(large/default/small)
|
||||||
|
buttonSize: {
|
||||||
|
type: String,
|
||||||
|
default: 'default'
|
||||||
|
},
|
||||||
|
// 正常状态按钮文字
|
||||||
|
buttonText: {
|
||||||
|
type: String,
|
||||||
|
default: '获取验证码'
|
||||||
|
},
|
||||||
|
// 倒计时总秒数
|
||||||
|
countDownNum: {
|
||||||
|
type: Number,
|
||||||
|
default: 60
|
||||||
|
},
|
||||||
|
// 手动控制按钮禁用状态
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 发射事件给父组件
|
||||||
|
const emit = defineEmits(['get-captcha'])
|
||||||
|
|
||||||
|
// 加载状态(请求验证码时)
|
||||||
|
const isLoading = ref(false)
|
||||||
|
// 是否正在倒计时
|
||||||
|
const isCountingDown = ref(false)
|
||||||
|
// 倒计时秒数
|
||||||
|
const countDown = ref(0)
|
||||||
|
// 倒计时定时器
|
||||||
|
let timer = null
|
||||||
|
|
||||||
|
// 获取验证码点击事件
|
||||||
|
const handleGetCaptcha = async () => {
|
||||||
|
// 倒计时中 / 加载中 / 禁用状态 禁止点击
|
||||||
|
if (isCountingDown.value || isLoading.value || props.disabled) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 开启加载状态
|
||||||
|
isLoading.value = true
|
||||||
|
// 触发父组件的请求方法(真正的接口请求写在父组件)
|
||||||
|
await getSms({ type: props.type });
|
||||||
|
ElNotification.success({
|
||||||
|
title: '成功',
|
||||||
|
message: '验证码已发送,请注意查收',
|
||||||
|
});
|
||||||
|
// ======================
|
||||||
|
// 请求成功 → 开始倒计时
|
||||||
|
// ======================
|
||||||
|
startCountDown()
|
||||||
|
} catch (error) {
|
||||||
|
// 请求失败 → 不触发倒计时,控制台提示
|
||||||
|
console.error('', error)
|
||||||
|
} finally {
|
||||||
|
// 关闭加载状态
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
}, 500) // 适当延迟,避免闪烁
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 倒计时核心逻辑
|
||||||
|
const startCountDown = () => {
|
||||||
|
// 初始化倒计时时间
|
||||||
|
countDown.value = props.countDownNum
|
||||||
|
isCountingDown.value = true
|
||||||
|
|
||||||
|
// 开启定时器
|
||||||
|
timer = setInterval(() => {
|
||||||
|
countDown.value--
|
||||||
|
// 倒计时结束
|
||||||
|
if (countDown.value <= 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
timer = null
|
||||||
|
isCountingDown.value = false
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面销毁时清除定时器(防止内存泄漏)
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (timer) clearInterval(timer)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 你可以在这里自定义按钮默认样式,也可以在父组件覆盖 */
|
||||||
|
.captcha-btn {
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
180
src/components/resetPassword/index.vue
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="修改密码" modal-append-to-body append-to-body v-model="dialogVisible" @close="reset" width="400px">
|
||||||
|
<el-form ref="refForm" :model="form" :rules="rules" label-width="100px">
|
||||||
|
<el-form-item label="手机号">
|
||||||
|
<el-input :value="maskPhone(shopInfo.phone)" disabled></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="旧密码" prop="originalPassword">
|
||||||
|
<el-input type="password" show-password v-model="form.originalPassword" placeholder="请输入旧密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新密码" prop="password">
|
||||||
|
<el-input type="password" show-password v-model="form.password" placeholder="请输入新密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="margin-top: -10px;"><el-text :type="isPws ? 'danger' : 'info'" size="small"
|
||||||
|
style="line-height: 16px;">注意:新密码必须至少包含字母、数字、特殊符号中的两种,且长度6-18位</el-text></el-form-item>
|
||||||
|
<el-form-item label="确认新密码" prop="checkPassword">
|
||||||
|
<el-input type="password" show-password v-model="form.checkPassword" placeholder="请再次输入新密码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="验证码" prop="code">
|
||||||
|
<div class="center">
|
||||||
|
<el-input v-model="form.code" placeholder="请输入验证码"></el-input>
|
||||||
|
<captcha-btn type="shopPwd" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="formLoading" @click="submitHandle">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import sysUser from "@/api/account/sysUser";
|
||||||
|
import { ElNotification } from "element-plus";
|
||||||
|
import { maskPhone } from "@/utils";
|
||||||
|
import CaptchaBtn from "./CaptchaBtn.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
// 修改成功后的跳转类型 1- 跳转到登录页 2- 留在当前页
|
||||||
|
type: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const shopInfo = ref({
|
||||||
|
phone: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const formLoading = ref(false);
|
||||||
|
|
||||||
|
const isPws = ref(false);
|
||||||
|
|
||||||
|
const form = reactive({
|
||||||
|
id: '',
|
||||||
|
originalPassword: "", // 原密码
|
||||||
|
code: '', // 验证码
|
||||||
|
checkPassword: "", // 确认新密码
|
||||||
|
password: "", // 新密码
|
||||||
|
});
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
form.originalPassword = "";
|
||||||
|
form.checkPassword = "";
|
||||||
|
form.password = "";
|
||||||
|
form.code = "";
|
||||||
|
refForm.value.resetFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
const reg = /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,}$/;
|
||||||
|
const validateNewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
||||||
|
if (!form.password) {
|
||||||
|
callback(new Error(" "));
|
||||||
|
} else if (form.password === form.originalPassword) {
|
||||||
|
callback(new Error("请输入与旧密码不同的新密码"));
|
||||||
|
} else if (form.password.length < 6 || form.password.length > 18) {
|
||||||
|
// 密码长度6 - 18位
|
||||||
|
callback(new Error("密码长度应为6-18位"));
|
||||||
|
} else if (!reg.test(form.password)) {
|
||||||
|
// 新密码长度不能小于6 需包含字母、数字、特殊符号中至少两种
|
||||||
|
isPws.value = true;
|
||||||
|
callback(new Error(""));
|
||||||
|
} else {
|
||||||
|
isPws.value = false;
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const validateRnewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
||||||
|
if (!form.checkPassword) {
|
||||||
|
callback(new Error(" "));
|
||||||
|
} else if (form.checkPassword !== form.password) {
|
||||||
|
callback(new Error("两次密码输入不一致"));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
originalPassword: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: validateNewPass,
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
checkPassword: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
validator: validateRnewPass,
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
code: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: " ",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
|
||||||
|
const refForm = ref();
|
||||||
|
// 提交修改密码
|
||||||
|
function submitHandle() {
|
||||||
|
refForm.value.validate(async (vaild: boolean) => {
|
||||||
|
if (vaild) {
|
||||||
|
try {
|
||||||
|
formLoading.value = true;
|
||||||
|
await sysUser.pwd(form);
|
||||||
|
if (props.type == 1) {
|
||||||
|
ElNotification.success("密码修改成功,请重新登录");
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push("/login");
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
ElNotification.success("密码修改成功");
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
emit('success')
|
||||||
|
} catch (error) {
|
||||||
|
formLoading.value = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(e: object) {
|
||||||
|
console.log(e);
|
||||||
|
shopInfo.value = e
|
||||||
|
form.id = e.id
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -10,41 +10,25 @@
|
|||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item @click="handleOpenUserProfile">店铺配置</el-dropdown-item>
|
<el-dropdown-item @click="handleOpenUserProfile">店铺配置</el-dropdown-item>
|
||||||
<el-dropdown-item divided @click="dialogVisible = true">修改密码</el-dropdown-item>
|
<el-dropdown-item divided @click="refResetPasswordRef.show(shopInfo)">修改密码</el-dropdown-item>
|
||||||
<el-dropdown-item divided @click="logout">退出登录</el-dropdown-item>
|
<el-dropdown-item divided @click="logout">退出登录</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<el-dialog title="修改密码" modal-append-to-body append-to-body v-model="dialogVisible" @close="reset" width="400px">
|
<resetPassword ref="refResetPasswordRef" />
|
||||||
<el-form ref="refForm" :model="form" :rules="rules">
|
|
||||||
<el-form-item label="旧密码" prop="oldPass">
|
|
||||||
<el-input type="password" show-password v-model="form.oldPass" placeholder="请输入旧密码"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="新密码" prop="newPass">
|
|
||||||
<el-input type="password" show-password v-model="form.newPass" placeholder="请输入新密码"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="确认新密码" prop="rnewPass">
|
|
||||||
<el-input type="password" show-password v-model="form.rnewPass" placeholder="请再次输入新密码"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" :loading="formLoading" @click="submitHandle">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import sysUser from "@/api/account/sysUser";
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: "UserProfile",
|
name: "UserProfile",
|
||||||
});
|
});
|
||||||
import { ElNotification } from "element-plus";
|
|
||||||
import { useTagsViewStore, useUserStore } from "@/store";
|
import { useTagsViewStore, useUserStore } from "@/store";
|
||||||
import { useCartsStore } from '@/store/modules/carts'
|
import { useCartsStore } from '@/store/modules/carts'
|
||||||
|
import resetPassword from "@/components/resetPassword/index.vue";
|
||||||
|
|
||||||
|
const shopInfo = JSON.parse(localStorage.getItem("userInfo") || "{}");
|
||||||
|
|
||||||
|
const refResetPasswordRef = ref(null);
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
@@ -53,91 +37,6 @@ const cartStore = useCartsStore()
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const dialogVisible = ref(false);
|
|
||||||
const formLoading = ref(false);
|
|
||||||
|
|
||||||
const form = reactive({
|
|
||||||
oldPass: "",
|
|
||||||
newPass: "",
|
|
||||||
rnewPass: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
form.oldPass = "";
|
|
||||||
form.newPass = "";
|
|
||||||
form.rnewPass = "";
|
|
||||||
refForm.value.resetFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
const validateNewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
|
||||||
if (!form.newPass) {
|
|
||||||
callback(new Error(" "));
|
|
||||||
} else if (form.newPass === form.oldPass) {
|
|
||||||
callback(new Error("请输入与旧密码不同的新密码"));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const validateRnewPass = (rule: any, value: string, callback: (error?: Error) => void) => {
|
|
||||||
if (!form.rnewPass) {
|
|
||||||
callback(new Error(" "));
|
|
||||||
} else if (form.rnewPass !== form.newPass) {
|
|
||||||
callback(new Error("两次密码输入不一致"));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const rules = {
|
|
||||||
oldPass: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: " ",
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
newPass: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
validator: validateNewPass,
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
rnewPass: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
validator: validateRnewPass,
|
|
||||||
trigger: "blur",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const refForm = ref();
|
|
||||||
// 提交修改密码
|
|
||||||
function submitHandle() {
|
|
||||||
refForm.value.validate(async (vaild: boolean) => {
|
|
||||||
if (vaild) {
|
|
||||||
try {
|
|
||||||
formLoading.value = true;
|
|
||||||
const res = await sysUser.pwd({
|
|
||||||
originalPassword: form.oldPass,
|
|
||||||
checkPassword: form.newPass,
|
|
||||||
password: form.newPass,
|
|
||||||
});
|
|
||||||
ElNotification.success("修改成功,请重新登陆");
|
|
||||||
userStore
|
|
||||||
.logout()
|
|
||||||
.then(() => {
|
|
||||||
tagsViewStore.delAllViews();
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
router.push(`/login?redirect=${route.fullPath}`);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
formLoading.value = false;
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 打开个人中心页面
|
* 打开个人中心页面
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import {
|
|||||||
OrderCostSummary,
|
OrderCostSummary,
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
|
import { getCompatibleFieldValue } from "./utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回商品单价
|
* 返回商品单价
|
||||||
* @param goods 商品
|
* @param goods 商品
|
||||||
@@ -46,7 +48,13 @@ export function returnGoodsPrice(
|
|||||||
// 限时折扣
|
// 限时折扣
|
||||||
if (limitTimeDiscount && limitTimeDiscount.id) {
|
if (limitTimeDiscount && limitTimeDiscount.id) {
|
||||||
//优先使用
|
//优先使用
|
||||||
if (goods.isTimeDiscount || goods.is_time_discount) {
|
// 兼容 isTimeDiscount/is_time_discount(这里顺便处理该字段的命名兼容)
|
||||||
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
|
goods,
|
||||||
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (isTimeDiscount) {
|
||||||
return new BigNumber(goods.salePrice)
|
return new BigNumber(goods.salePrice)
|
||||||
.times(limitTimeDiscount.discountRate / 100)
|
.times(limitTimeDiscount.discountRate / 100)
|
||||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||||
@@ -169,7 +177,15 @@ export function returnCanDikouGoodsArr(args: CanDikouGoodsArrArgs) {
|
|||||||
})
|
})
|
||||||
.filter((v) => {
|
.filter((v) => {
|
||||||
const canUseNum = (v.num ?? 0) - (v.returnNum || 0);
|
const canUseNum = (v.num ?? 0) - (v.returnNum || 0);
|
||||||
if (canUseNum <= 0 || v.is_temporary || v.is_gift) {
|
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
|
||||||
|
if (canUseNum <= 0 || isTemporary || isGift) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,7 +204,13 @@ function returnGoodsIsUseVipPrice(
|
|||||||
user: ShopUserInfo,
|
user: ShopUserInfo,
|
||||||
goods: BaseCartItem
|
goods: BaseCartItem
|
||||||
) {
|
) {
|
||||||
if (goods.is_time_discount) {
|
// 兼容 isTimeDiscount/is_time_discount
|
||||||
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
|
goods,
|
||||||
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (isTimeDiscount) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (shopInfo.isMemberPrice != 1 || user.isVip != 1) {
|
if (shopInfo.isMemberPrice != 1 || user.isVip != 1) {
|
||||||
@@ -214,12 +236,16 @@ function returnCanCalcGoodsList(
|
|||||||
user: ShopUserInfo
|
user: ShopUserInfo
|
||||||
) {
|
) {
|
||||||
return canCalcGoodsArr.filter((goods) => {
|
return canCalcGoodsArr.filter((goods) => {
|
||||||
if (
|
// 兼容 isTimeDiscount/is_time_discount
|
||||||
!coupon.discountShare &&
|
const isTimeDiscount = getCompatibleFieldValue(
|
||||||
(goods.is_time_discount || goods.isTimeDiscount)
|
goods,
|
||||||
) {
|
"isTimeDiscount",
|
||||||
|
"is_time_discount"
|
||||||
|
);
|
||||||
|
if (!coupon.discountShare && isTimeDiscount) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!coupon.vipPriceShare &&
|
!coupon.vipPriceShare &&
|
||||||
returnGoodsIsUseVipPrice(shopInfo, user, goods)
|
returnGoodsIsUseVipPrice(shopInfo, user, goods)
|
||||||
@@ -288,12 +314,14 @@ export function returnCouponCanUse(args: couponCalcParams) {
|
|||||||
return coupon.thresholdFoods.find((food) => food.id == v.productId);
|
return coupon.thresholdFoods.find((food) => food.id == v.productId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
canCalcGoodsArr = returnCanCalcGoodsList(
|
canCalcGoodsArr = returnCanCalcGoodsList(
|
||||||
canCalcGoodsArr,
|
canCalcGoodsArr,
|
||||||
coupon,
|
coupon,
|
||||||
shopInfo,
|
shopInfo,
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
||||||
return (
|
return (
|
||||||
pre +
|
pre +
|
||||||
@@ -328,6 +356,7 @@ export function returnCouponCanUse(args: couponCalcParams) {
|
|||||||
reason: "当前选中的券不可与其他券同享",
|
reason: "当前选中的券不可与其他券同享",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 满减券和折扣券计算门槛金额是否满足
|
// 满减券和折扣券计算门槛金额是否满足
|
||||||
if ([1, 3].includes(coupon.type)) {
|
if ([1, 3].includes(coupon.type)) {
|
||||||
if (canCalcGoodsArr.length <= 0) {
|
if (canCalcGoodsArr.length <= 0) {
|
||||||
@@ -438,7 +467,7 @@ export function calcDiscountGoodsArrPrice(
|
|||||||
) {
|
) {
|
||||||
let hasCountNum = 0;
|
let hasCountNum = 0;
|
||||||
let discountPrice = 0;
|
let discountPrice = 0;
|
||||||
let hasDiscountGoodsArr = [];
|
let hasDiscountGoodsArr:BaseCartItem[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < discountGoodsArr.length; i++) {
|
for (let i = 0; i < discountGoodsArr.length; i++) {
|
||||||
if (hasCountNum >= discountNum) {
|
if (hasCountNum >= discountNum) {
|
||||||
@@ -457,10 +486,13 @@ export function calcDiscountGoodsArrPrice(
|
|||||||
discountPrice += realPrice * num;
|
discountPrice += realPrice * num;
|
||||||
|
|
||||||
hasCountNum += num;
|
hasCountNum += num;
|
||||||
hasDiscountGoodsArr.push({
|
if(goods){
|
||||||
...goods,
|
hasDiscountGoodsArr.push({
|
||||||
num,
|
...goods,
|
||||||
});
|
num,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -609,7 +641,7 @@ export function returnCouponProductDiscount(
|
|||||||
let { useFoods, discountNum, useRule } = coupon;
|
let { useFoods, discountNum, useRule } = coupon;
|
||||||
discountNum = discountNum || 0;
|
discountNum = discountNum || 0;
|
||||||
//抵扣商品数组
|
//抵扣商品数组
|
||||||
let discountGoodsArr = [];
|
let discountGoodsArr:BaseCartItem[] = [];
|
||||||
|
|
||||||
//抵扣全部商品
|
//抵扣全部商品
|
||||||
if (useFoods.length === 0) {
|
if (useFoods.length === 0) {
|
||||||
@@ -656,9 +688,17 @@ function returnCouponBuyOneGiveOneDiscount(
|
|||||||
) {
|
) {
|
||||||
const { useFoods, useRule } = coupon;
|
const { useFoods, useRule } = coupon;
|
||||||
//抵扣商品
|
//抵扣商品
|
||||||
let discountGoods = undefined;
|
let discountGoods:BaseCartItem | undefined = undefined;
|
||||||
//符合买一送一条件的商品
|
//符合买一送一条件的商品(数量>=2 + 非临时/非赠品)
|
||||||
const canUseGoods = canDikouGoodsArr.filter((v) => (v.num || 0) >= 2);
|
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||||
|
});
|
||||||
//抵扣全部商品
|
//抵扣全部商品
|
||||||
if (useFoods.length === 0) {
|
if (useFoods.length === 0) {
|
||||||
if (useRule == "price_asc") {
|
if (useRule == "price_asc") {
|
||||||
@@ -710,9 +750,17 @@ function returnSecoendDiscount(
|
|||||||
) {
|
) {
|
||||||
const { useFoods, useRule } = coupon;
|
const { useFoods, useRule } = coupon;
|
||||||
//抵扣商品
|
//抵扣商品
|
||||||
let discountGoods = undefined;
|
let discountGoods:BaseCartItem | undefined = undefined;
|
||||||
//符合条件的商品
|
//符合条件的商品(数量>=2 + 非临时/非赠品)
|
||||||
const canUseGoods = canDikouGoodsArr.filter((v) => (v.num || 0) >= 2);
|
const canUseGoods = canDikouGoodsArr.filter((v) => {
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return (v.num || 0) >= 2 && !isTemporary && !isGift;
|
||||||
|
});
|
||||||
//抵扣全部商品
|
//抵扣全部商品
|
||||||
if (useFoods.length === 0) {
|
if (useFoods.length === 0) {
|
||||||
if (useRule == "price_asc") {
|
if (useRule == "price_asc") {
|
||||||
@@ -767,7 +815,14 @@ export function returnCanDikouGoods(
|
|||||||
) {
|
) {
|
||||||
const result = arr
|
const result = arr
|
||||||
.filter((v) => {
|
.filter((v) => {
|
||||||
return !v.is_temporary && !v.is_gift;
|
// 兼容 is_temporary/isTemporary 和 is_gift/isGift
|
||||||
|
const isTemporary = getCompatibleFieldValue(
|
||||||
|
v,
|
||||||
|
"isTemporary",
|
||||||
|
"is_temporary"
|
||||||
|
);
|
||||||
|
const isGift = getCompatibleFieldValue(v, "isGift", "is_gift");
|
||||||
|
return !isTemporary && !isGift;
|
||||||
})
|
})
|
||||||
.filter((v) => {
|
.filter((v) => {
|
||||||
return (v.num || 0) > 0;
|
return (v.num || 0) > 0;
|
||||||
@@ -781,9 +836,6 @@ export function returnCanDikouGoods(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const utils = {
|
export const utils = {
|
||||||
returnGoodsPrice,
|
returnGoodsPrice,
|
||||||
returnGoodsGroupMap,
|
returnGoodsGroupMap,
|
||||||
|
|||||||
1946
src/lib/goods.ts
@@ -29,9 +29,7 @@ export function canUseLimitTimeDiscount(
|
|||||||
) {
|
) {
|
||||||
shopInfo = shopInfo || {};
|
shopInfo = shopInfo || {};
|
||||||
shopUserInfo = shopUserInfo || {};
|
shopUserInfo = shopUserInfo || {};
|
||||||
if(shopInfo.isMemberPrice){
|
|
||||||
shopUserInfo.isMemberPrice=1
|
|
||||||
}
|
|
||||||
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -88,6 +86,9 @@ export function returnPrice(args: returnPriceArgs) {
|
|||||||
shopId: 0,
|
shopId: 0,
|
||||||
useType: "",
|
useType: "",
|
||||||
};
|
};
|
||||||
|
if(!goods){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||||
const includesGoods =
|
const includesGoods =
|
||||||
limitTimeDiscountRes.foodType == 1 ||
|
limitTimeDiscountRes.foodType == 1 ||
|
||||||
@@ -96,8 +97,7 @@ export function returnPrice(args: returnPriceArgs) {
|
|||||||
shopUserInfo = shopUserInfo || {};
|
shopUserInfo = shopUserInfo || {};
|
||||||
if (
|
if (
|
||||||
shopUserInfo.isMemberPrice == 1 &&
|
shopUserInfo.isMemberPrice == 1 &&
|
||||||
shopUserInfo.isVip == 1 &&
|
shopUserInfo.isVip == 1
|
||||||
shopInfo.isMemberPrice == 1
|
|
||||||
) {
|
) {
|
||||||
const memberPrice = goods.memberPrice || goods.salePrice;
|
const memberPrice = goods.memberPrice || goods.salePrice;
|
||||||
|
|
||||||
|
|||||||
33
src/lib/utils.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* 通用字段兼容工具函数:处理驼峰/下划线命名的字段取值
|
||||||
|
* @param obj 目标对象(如商品信息 BaseCartItem)
|
||||||
|
* @param camelCaseKey 驼峰命名字段(如 'isTemporary')
|
||||||
|
* @param snakeCaseKey 下划线命名字段(如 'is_temporary')
|
||||||
|
* @param defaultValue 默认值(默认 false,适配布尔类型字段)
|
||||||
|
* @returns 字段值(优先取存在的字段,无则返回默认值)
|
||||||
|
*/
|
||||||
|
export function getCompatibleFieldValue(
|
||||||
|
obj: Record<string, any>,
|
||||||
|
camelCaseKey: string,
|
||||||
|
snakeCaseKey: string,
|
||||||
|
defaultValue: boolean = false
|
||||||
|
): boolean {
|
||||||
|
// 优先判断驼峰字段(如果存在且不是 undefined/null)
|
||||||
|
if (
|
||||||
|
obj.hasOwnProperty(camelCaseKey) &&
|
||||||
|
obj[camelCaseKey] !== undefined &&
|
||||||
|
obj[camelCaseKey] !== null
|
||||||
|
) {
|
||||||
|
return Boolean(obj[camelCaseKey]);
|
||||||
|
}
|
||||||
|
// 再判断下划线字段
|
||||||
|
if (
|
||||||
|
obj.hasOwnProperty(snakeCaseKey) &&
|
||||||
|
obj[snakeCaseKey] !== undefined &&
|
||||||
|
obj[snakeCaseKey] !== null
|
||||||
|
) {
|
||||||
|
return Boolean(obj[snakeCaseKey]);
|
||||||
|
}
|
||||||
|
// 都不存在时返回默认值(布尔类型字段默认 false)
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
@@ -24,61 +24,17 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
path: "/",
|
path: '/',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: "/index",
|
redirect: '/index',
|
||||||
meta: {
|
|
||||||
title: "数据中心",
|
|
||||||
icon: "数据统计",
|
|
||||||
alwaysShow: true,
|
|
||||||
},
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: "index",
|
path: 'index',
|
||||||
component: () => import("@/views/data/index.vue"),
|
component: () => import('@/views/index/index.vue'),
|
||||||
name: "",
|
name: 'index',
|
||||||
meta: {
|
meta: {
|
||||||
title: "经营数据",
|
title: '首页',
|
||||||
affix: false,
|
icon: 'homepage',
|
||||||
keepAlive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "sales",
|
|
||||||
name: "",
|
|
||||||
component: () => import("@/views/data/sales.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "销售统计",
|
|
||||||
affix: false,
|
|
||||||
keepAlive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "table",
|
|
||||||
name: "",
|
|
||||||
component: () => import("@/views/data/table.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "台桌统计",
|
|
||||||
affix: false,
|
|
||||||
keepAlive: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "finance",
|
|
||||||
name: "",
|
|
||||||
component: () => import("@/views/data/finance.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "财务报表"
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "work",
|
|
||||||
name: "workStatistics",
|
|
||||||
component: () => import("@/views/data/work.vue"),
|
|
||||||
meta: {
|
|
||||||
title: "收银交班记录",
|
|
||||||
affix: false,
|
|
||||||
keepAlive: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -91,9 +47,79 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||||||
component: () => import("@/views/error/404.vue"),
|
component: () => import("@/views/error/404.vue"),
|
||||||
meta: { hidden: true },
|
meta: { hidden: true },
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
|
// path: "/",
|
||||||
|
// component: Layout,
|
||||||
|
// redirect: "/index",
|
||||||
|
// meta: {
|
||||||
|
// title: "数据中心",
|
||||||
|
// icon: "数据统计",
|
||||||
|
// alwaysShow: true,
|
||||||
|
// },
|
||||||
|
// children: [
|
||||||
|
// {
|
||||||
|
// path: "index",
|
||||||
|
// component: () => import("@/views/data/index.vue"),
|
||||||
|
// name: "",
|
||||||
|
// meta: {
|
||||||
|
// title: "经营数据",
|
||||||
|
// affix: false,
|
||||||
|
// keepAlive: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "sales",
|
||||||
|
// name: "",
|
||||||
|
// component: () => import("@/views/data/sales.vue"),
|
||||||
|
// meta: {
|
||||||
|
// title: "销售统计",
|
||||||
|
// affix: false,
|
||||||
|
// keepAlive: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "table",
|
||||||
|
// name: "",
|
||||||
|
// component: () => import("@/views/data/table.vue"),
|
||||||
|
// meta: {
|
||||||
|
// title: "台桌统计",
|
||||||
|
// affix: false,
|
||||||
|
// keepAlive: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "finance",
|
||||||
|
// name: "",
|
||||||
|
// component: () => import("@/views/data/finance.vue"),
|
||||||
|
// meta: {
|
||||||
|
// title: "财务报表"
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "work",
|
||||||
|
// name: "workStatistics",
|
||||||
|
// component: () => import("@/views/data/work.vue"),
|
||||||
|
// meta: {
|
||||||
|
// title: "收银交班记录",
|
||||||
|
// affix: false,
|
||||||
|
// keepAlive: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "401",
|
||||||
|
// component: () => import("@/views/error/401.vue"),
|
||||||
|
// meta: { hidden: true },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// path: "404",
|
||||||
|
// component: () => import("@/views/error/404.vue"),
|
||||||
|
// meta: { hidden: true },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// {
|
||||||
// path: "/shop",
|
// path: "/shop",
|
||||||
// component: Layout,
|
// component: Layout,
|
||||||
// meta: {
|
// meta: {
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ import { store } from "@/store";
|
|||||||
import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
|
import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
|
||||||
import orderApi from "@/api/order/order";
|
import orderApi from "@/api/order/order";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
|
const shopUser = useUserStoreHook();
|
||||||
|
|
||||||
import { customTruncateToTwoDecimals } from '@/utils/tools'
|
import { customTruncateToTwoDecimals } from '@/utils/tools'
|
||||||
import productApi from "@/api/product/index";
|
import productApi from "@/api/product/index";
|
||||||
|
|
||||||
const shopUser = useUserStoreHook();
|
|
||||||
export interface CartsState {
|
export interface CartsState {
|
||||||
id: string | number;
|
id: string | number;
|
||||||
[property: string]: any;
|
[property: string]: any;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket";
|
|||||||
import orderApi from "@/api/order/order";
|
import orderApi from "@/api/order/order";
|
||||||
import { useUserStoreHook } from "@/store/modules/user";
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
import productApi from "@/api/product/index";
|
import productApi from "@/api/product/index";
|
||||||
|
import categoryApi from "@/api/product/productclassification";
|
||||||
import shopUserApi from '@/api/account/shopUser'
|
import shopUserApi from '@/api/account/shopUser'
|
||||||
import limitTimeDiscountApi from '@/api/market/limitTimeDiscount.js'
|
import limitTimeDiscountApi from '@/api/market/limitTimeDiscount.js'
|
||||||
import { BigNumber } from "bignumber.js";
|
import { BigNumber } from "bignumber.js";
|
||||||
@@ -82,8 +83,6 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
default: productType = GoodsType.NORMAL;
|
default: productType = GoodsType.NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
@@ -226,9 +225,27 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
const isLinkFinshed = ref(false);
|
const isLinkFinshed = ref(false);
|
||||||
|
|
||||||
// 当前购物车数据(现在 getAllGoodsList 能直接访问)
|
// 当前购物车数据(现在 getAllGoodsList 能直接访问)
|
||||||
const list = useStorage<any[]>("carts", []);
|
const list = useStorage<any[]>(
|
||||||
// 历史订单数据(现在 getAllGoodsList 能直接访问),不从本地缓存获取,改为从接口获取
|
"carts",
|
||||||
const oldOrder = ref<any>({
|
[],
|
||||||
|
localStorage,
|
||||||
|
{
|
||||||
|
serializer: {
|
||||||
|
read: (rawValue) => {
|
||||||
|
// 没有值时直接返回默认空数组
|
||||||
|
if (!rawValue) return []
|
||||||
|
try {
|
||||||
|
return JSON.parse(rawValue)
|
||||||
|
} catch {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
write: (value) => JSON.stringify(value),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// 历史订单数据(现在 getAllGoodsList 能直接访问)
|
||||||
|
const oldOrder = useStorage<any>("Instead_olold_order", {
|
||||||
detailMap: [],
|
detailMap: [],
|
||||||
originAmount: 0
|
originAmount: 0
|
||||||
});
|
});
|
||||||
@@ -332,11 +349,61 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const consList = await productApi.consStock({ shopId: localStorage.getItem("shopId") })
|
||||||
|
|
||||||
|
goods.value = addGoodsSoldOutStatus(goods.value, consList)
|
||||||
|
|
||||||
console.log('代客下单页面商品缓存.goods.value', goods.value);
|
console.log('代客下单页面商品缓存.goods.value', goods.value);
|
||||||
|
|
||||||
setGoodsMap(goods.value);
|
setGoodsMap(goods.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给商品列表批量添加 isSoldOut 售罄状态字段
|
||||||
|
* @param {Array} goodsList - 商品列表 [ { consList, isAutoSoldStock } ]
|
||||||
|
* @param {Array} consStockList - 真实耗材库存列表 [ { consId, stockNumber } ]
|
||||||
|
* @returns 带 isSoldOut 字段的新商品列表
|
||||||
|
*/
|
||||||
|
function addGoodsSoldOutStatus(goodsList, consStockList) {
|
||||||
|
// console.log('addGoodsSoldOutStatus.goodsList', goodsList);
|
||||||
|
// console.log('addGoodsSoldOutStatus.consStockList', consStockList);
|
||||||
|
|
||||||
|
// 耗材ID映射真实库存(保留)
|
||||||
|
const consMap = _.keyBy(consStockList, item => String(item.consId));
|
||||||
|
|
||||||
|
return _.map(goodsList, goods => {
|
||||||
|
let isSoldOut = false;
|
||||||
|
|
||||||
|
// 开启自动售罄才判断
|
||||||
|
if (goods.isAutoSoldStock === 1 || goods.isAutoSoldStock === true) {
|
||||||
|
const goodsConsList = goods.consList || [];
|
||||||
|
|
||||||
|
// 无耗材 → 不售罄
|
||||||
|
if (goodsConsList.length === 0) {
|
||||||
|
isSoldOut = false;
|
||||||
|
} else {
|
||||||
|
// 核心:只要有一个耗材 真实库存 < 商品需要量 → 售罄
|
||||||
|
isSoldOut = _.some(goodsConsList, consItem => {
|
||||||
|
// 商品绑定的耗材ID(对应真实库存ID)
|
||||||
|
const consId = String(consItem.consInfoId);
|
||||||
|
// 商品需要消耗的数量(你的需求量)
|
||||||
|
const needStock = consItem.surplusStock || 0;
|
||||||
|
// 起售数量
|
||||||
|
const suitNum = goods.type == 'single' ? goods.skuList[0].suitNum : 1;
|
||||||
|
// 真实库存
|
||||||
|
const realStock = _.get(consMap, [consId, 'stockNumber'], 0);
|
||||||
|
|
||||||
|
// 真实库存 < 需要量 * 起售数量 → 不足 → 售罄
|
||||||
|
return realStock < needStock * suitNum;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...goods, isSoldOut };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setGoodsMap(goods: any[]) {
|
function setGoodsMap(goods: any[]) {
|
||||||
for (let item of goods) {
|
for (let item of goods) {
|
||||||
goodsMap[item.id] = item;
|
goodsMap[item.id] = item;
|
||||||
@@ -642,7 +709,9 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
sendMessage('add', { ...basic_msg, ...data });
|
sendMessage('add', { ...basic_msg, ...data });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加购物车/编辑购物车
|
||||||
function add(data: any) {
|
function add(data: any) {
|
||||||
|
// console.log('添加购物车/编辑购物车===', data);
|
||||||
goods.value.map(item => {
|
goods.value.map(item => {
|
||||||
if (item.id == data.product_id) {
|
if (item.id == data.product_id) {
|
||||||
data.is_time_discount = item.is_time_discount ? 1 : 0
|
data.is_time_discount = item.is_time_discount ? 1 : 0
|
||||||
@@ -657,8 +726,29 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
console.log('carts.add===', data);
|
console.log('carts.add===', data);
|
||||||
|
|
||||||
if (hasCart) {
|
if (hasCart) {
|
||||||
|
// console.log('编辑', msg);
|
||||||
|
if (hasCart.number * 1 + msg.number * 1 == 2) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: '购物车已有该商品,请确认是否重复',
|
||||||
|
duration: 4000
|
||||||
|
})
|
||||||
|
}
|
||||||
update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 });
|
update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 });
|
||||||
} else {
|
} else {
|
||||||
|
// console.log('添加', msg);
|
||||||
|
let arr = _.flatten(_.values(oldOrder.value.detailMap))
|
||||||
|
// console.log('添加.arr===', arr);
|
||||||
|
const isExist = _.some(arr, item => Number(item.productId) === msg.product_id)
|
||||||
|
|
||||||
|
// console.log('添加.isExist===', isExist);
|
||||||
|
if (msg.number == 1 && isExist) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: '该商品已下单过,请确认是否重复',
|
||||||
|
duration: 4000
|
||||||
|
})
|
||||||
|
}
|
||||||
sendMessage('add', msg);
|
sendMessage('add', msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -888,7 +978,7 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
console.log("收到消息:", msg);
|
console.log("收到消息:", msg);
|
||||||
if (!msg.status) {
|
if (!msg.status) {
|
||||||
if (msg.hasOwnProperty('status') && msg.status !== 1 && msg.operate_type !== 'bulk_edit') {
|
if (msg.hasOwnProperty('status') && msg.status !== 1 && msg.operate_type !== 'bulk_edit') {
|
||||||
return ElMessage.error(msg.message || '操作失败');
|
return ElMessage.error(msg.msg || '操作失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (msg?.data) {
|
if (msg?.data) {
|
||||||
@@ -1050,8 +1140,6 @@ export const useCartsStore = defineStore("carts", () => {
|
|||||||
newUserDiscount.value = {}
|
newUserDiscount.value = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
disconnect,
|
disconnect,
|
||||||
dinnerType,
|
dinnerType,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { setToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/
|
|||||||
export const useUserStore = defineStore("user", () => {
|
export const useUserStore = defineStore("user", () => {
|
||||||
// const isShopAdmin = ref(false) // 0商户 1员工
|
// const isShopAdmin = ref(false) // 0商户 1员工
|
||||||
const isShopAdmin = useStorage("isShopAdmin", false) // 0商户 1员工
|
const isShopAdmin = useStorage("isShopAdmin", false) // 0商户 1员工
|
||||||
|
const isAdmin = useStorage("isAdmin", false) // 是否是管理员
|
||||||
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
|
const userInfo = useStorage<UserInfo>("userInfo", {} as UserInfo);
|
||||||
const promissionList = useStorage<string[]>("promissionList", [] as string[]);
|
const promissionList = useStorage<string[]>("promissionList", [] as string[]);
|
||||||
//美团抖音核销店铺信息
|
//美团抖音核销店铺信息
|
||||||
@@ -32,6 +33,7 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
AuthAPI.login(loginRequest)
|
AuthAPI.login(loginRequest)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
isShopAdmin.value = data.loginType == 0 ? true : false;
|
isShopAdmin.value = data.loginType == 0 ? true : false;
|
||||||
|
isAdmin.value = data.shopInfo.id == 1 ? true : false
|
||||||
Object.assign(userInfo.value, { ...data.shopInfo, shopId: data.shopInfo.id });
|
Object.assign(userInfo.value, { ...data.shopInfo, shopId: data.shopInfo.id });
|
||||||
promissionList.value = data.promissionList;
|
promissionList.value = data.promissionList;
|
||||||
const token = data.tokenInfo.tokenValue;
|
const token = data.tokenInfo.tokenValue;
|
||||||
@@ -39,7 +41,7 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
setRefreshToken(token);
|
setRefreshToken(token);
|
||||||
localStorage.setItem("shopId", "" + data.shopInfo.id);
|
localStorage.setItem("shopId", "" + data.shopInfo.id);
|
||||||
localStorage.setItem("branch_shopId", data.shopInfo.id)
|
localStorage.setItem("branch_shopId", data.shopInfo.id)
|
||||||
resolve();
|
resolve(data);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
@@ -120,6 +122,7 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
userInfo.value = {} as UserInfo
|
userInfo.value = {} as UserInfo
|
||||||
meituan_douyin_info.value = {}
|
meituan_douyin_info.value = {}
|
||||||
isShopAdmin.value = false
|
isShopAdmin.value = false
|
||||||
|
isAdmin.value = false
|
||||||
clearToken();
|
clearToken();
|
||||||
usePermissionStoreHook().resetRouter();
|
usePermissionStoreHook().resetRouter();
|
||||||
useDictStoreHook().clearDictionaryCache();
|
useDictStoreHook().clearDictionaryCache();
|
||||||
@@ -137,7 +140,7 @@ export const useUserStore = defineStore("user", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isShopAdmin,
|
isShopAdmin, isAdmin,
|
||||||
meituan_douyin_info,
|
meituan_douyin_info,
|
||||||
userInfo,
|
userInfo,
|
||||||
promissionList,
|
promissionList,
|
||||||
|
|||||||
@@ -322,3 +322,41 @@ export function isValidMobile(phone: string): boolean {
|
|||||||
const mobileRegex = /^1[3-9]\d{9}$/;
|
const mobileRegex = /^1[3-9]\d{9}$/;
|
||||||
return mobileRegex.test(s);
|
return mobileRegex.test(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机号脱敏:隐藏中间四位数字
|
||||||
|
* @param {string | number} phone - 原始手机号(支持数字/字符串)
|
||||||
|
* @returns {string} 脱敏后的手机号,如 138****1234
|
||||||
|
*/
|
||||||
|
export function maskPhone(phone) {
|
||||||
|
// 先转成字符串,避免传入数字类型报错
|
||||||
|
const phoneStr = String(phone).trim();
|
||||||
|
|
||||||
|
// 简单校验:必须是11位数字
|
||||||
|
if (!/^1\d{10}$/.test(phoneStr)) {
|
||||||
|
console.warn('手机号格式不正确');
|
||||||
|
return phoneStr; // 格式错误直接返回原值
|
||||||
|
}
|
||||||
|
|
||||||
|
// 核心:前3位 + **** + 后4位
|
||||||
|
return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 金额保留两位小数 不四舍五入
|
||||||
|
* @param {number} num 金额数字
|
||||||
|
* @param {boolean} hasSymbol 是否带¥符号,默认true
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function formatMoney(num, hasSymbol = true) {
|
||||||
|
// 防止非数字、空值报错
|
||||||
|
if (isNaN(Number(num))) num = 0;
|
||||||
|
// 不四舍五入截断两位小数
|
||||||
|
const value = Math.floor(Math.abs(num) * 100) / 100;
|
||||||
|
// 拼接两位小数
|
||||||
|
const fixedNum = value.toFixed(2);
|
||||||
|
// 负数处理
|
||||||
|
const result = num < 0 ? `-${fixedNum}` : fixedNum;
|
||||||
|
// 默认返回带¥
|
||||||
|
return hasSymbol ? `¥${result}` : result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,18 +19,7 @@ const modalConfig: IModalConfig = {
|
|||||||
console.log("提交之前处理", data);
|
console.log("提交之前处理", data);
|
||||||
},
|
},
|
||||||
formItems: [
|
formItems: [
|
||||||
{
|
|
||||||
label: "状态",
|
|
||||||
prop: "status",
|
|
||||||
type: 'switch',
|
|
||||||
attrs: {
|
|
||||||
activeText: '开启',
|
|
||||||
inactiveText: '关闭',
|
|
||||||
activeValue: 1,
|
|
||||||
inactiveValue: 0
|
|
||||||
},
|
|
||||||
initialValue: 1
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "挂账人",
|
label: "挂账人",
|
||||||
@@ -66,6 +55,56 @@ const modalConfig: IModalConfig = {
|
|||||||
},
|
},
|
||||||
initialValue: 0
|
initialValue: 0
|
||||||
},
|
},
|
||||||
|
// ===================== 新增 =====================
|
||||||
|
{
|
||||||
|
label: "还款提醒日",
|
||||||
|
prop: "expireRemindDay",
|
||||||
|
type: "input",
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (!value) return callback();
|
||||||
|
const num = Number(value);
|
||||||
|
if (!Number.isInteger(num) || num < 1 || num > 28) {
|
||||||
|
callback(new Error("请输入 1~28 之间的整数"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attrs: {
|
||||||
|
type: "number",
|
||||||
|
placeholder: "每月几号提醒(1-28)",
|
||||||
|
style: { width: "200px" },
|
||||||
|
oninput: "value=value.replace(/\\D|\\./g,'')" // 禁止输入小数点
|
||||||
|
},
|
||||||
|
initialValue: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "还款提醒",
|
||||||
|
prop: "expireRemind",
|
||||||
|
type: "input",
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (!value) return callback();
|
||||||
|
const num = Number(value);
|
||||||
|
if (!Number.isInteger(num) || num < 0) {
|
||||||
|
callback(new Error("请输入大于等于 0 的整数"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attrs: {
|
||||||
|
type: "number",
|
||||||
|
placeholder: "提醒多久以前的数据单位(月)",
|
||||||
|
style: { width: "240px" },
|
||||||
|
oninput: "value=value.replace(/\\D|\\./g,'')" // 禁止输入小数点
|
||||||
|
},
|
||||||
|
initialValue: "",
|
||||||
|
},
|
||||||
|
// ================================================
|
||||||
{
|
{
|
||||||
label: "还款方式",
|
label: "还款方式",
|
||||||
prop: "repaymentMethod",
|
prop: "repaymentMethod",
|
||||||
@@ -73,6 +112,18 @@ const modalConfig: IModalConfig = {
|
|||||||
options: returnOptions('repaymentMethod'),
|
options: returnOptions('repaymentMethod'),
|
||||||
initialValue: returnOptions('repaymentMethod')[0].value
|
initialValue: returnOptions('repaymentMethod')[0].value
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "状态",
|
||||||
|
prop: "status",
|
||||||
|
type: 'switch',
|
||||||
|
attrs: {
|
||||||
|
activeText: '开启',
|
||||||
|
inactiveText: '关闭',
|
||||||
|
activeValue: 1,
|
||||||
|
inactiveValue: 0
|
||||||
|
},
|
||||||
|
initialValue: 1
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -58,16 +58,36 @@ const contentConfig: IContentConfig = {
|
|||||||
label: "已挂账金额(元)",
|
label: "已挂账金额(元)",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "owedAmount",
|
prop: "owedAmount",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: 'owedAmount',
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// label: "剩余挂账额度(元)",
|
||||||
|
// align: "center",
|
||||||
|
// prop: "remainingAmount",
|
||||||
|
// templet: "custom",
|
||||||
|
// slotName: 'remainingAmount',
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
label: "剩余挂账额度(元)",
|
label: "账户余额(挂账额度+用户余额)",
|
||||||
align: "center",
|
|
||||||
prop: "remainingAmount",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "账户余额",
|
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "accountBalance",
|
prop: "accountBalance",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: 'accountBalance',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "还款提醒日",
|
||||||
|
align: "center",
|
||||||
|
prop: "expireRemindDay",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: 'expireRemindDay',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "还款提醒",
|
||||||
|
align: "center",
|
||||||
|
prop: "expireRemind",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: 'expireRemind',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "操作",
|
label: "操作",
|
||||||
|
|||||||
@@ -19,18 +19,7 @@ const modalConfig: IModalConfig = {
|
|||||||
console.log("提交之前处理", data);
|
console.log("提交之前处理", data);
|
||||||
},
|
},
|
||||||
formItems: [
|
formItems: [
|
||||||
{
|
|
||||||
label: "状态",
|
|
||||||
prop: "status",
|
|
||||||
type: 'switch',
|
|
||||||
attrs: {
|
|
||||||
activeText: '开启',
|
|
||||||
inactiveText: '关闭',
|
|
||||||
activeValue: 1,
|
|
||||||
inactiveValue: 0
|
|
||||||
},
|
|
||||||
initialValue: 1
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "挂账人",
|
label: "挂账人",
|
||||||
@@ -66,6 +55,56 @@ const modalConfig: IModalConfig = {
|
|||||||
},
|
},
|
||||||
initialValue: 0
|
initialValue: 0
|
||||||
},
|
},
|
||||||
|
// ===================== 新增 =====================
|
||||||
|
{
|
||||||
|
label: "还款提醒日",
|
||||||
|
prop: "expireRemindDay",
|
||||||
|
type: "input",
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (!value) return callback();
|
||||||
|
const num = Number(value);
|
||||||
|
if (!Number.isInteger(num) || num < 1 || num > 28) {
|
||||||
|
callback(new Error("请输入 1~28 之间的整数"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attrs: {
|
||||||
|
type: "number",
|
||||||
|
placeholder: "每月几号提醒(1-28)",
|
||||||
|
style: { width: "200px" },
|
||||||
|
oninput: "value=value.replace(/\\D|\\./g,'')" // 禁止输入小数点
|
||||||
|
},
|
||||||
|
initialValue: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "还款提醒",
|
||||||
|
prop: "expireRemind",
|
||||||
|
type: "input",
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
validator: (rule, value, callback) => {
|
||||||
|
if (!value) return callback();
|
||||||
|
const num = Number(value);
|
||||||
|
if (!Number.isInteger(num) || num < 0) {
|
||||||
|
callback(new Error("请输入大于等于 0 的整数"));
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attrs: {
|
||||||
|
type: "number",
|
||||||
|
placeholder: "提醒多久以前的数据单位(月)",
|
||||||
|
style: { width: "240px" },
|
||||||
|
oninput: "value=value.replace(/\\D|\\./g,'')" // 禁止输入小数点
|
||||||
|
},
|
||||||
|
initialValue: "",
|
||||||
|
},
|
||||||
|
// ================================================
|
||||||
{
|
{
|
||||||
label: "还款方式",
|
label: "还款方式",
|
||||||
prop: "repaymentMethod",
|
prop: "repaymentMethod",
|
||||||
@@ -73,6 +112,18 @@ const modalConfig: IModalConfig = {
|
|||||||
options: returnOptions('repaymentMethod'),
|
options: returnOptions('repaymentMethod'),
|
||||||
initialValue: returnOptions('repaymentMethod')[0].value
|
initialValue: returnOptions('repaymentMethod')[0].value
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "状态",
|
||||||
|
prop: "status",
|
||||||
|
type: 'switch',
|
||||||
|
attrs: {
|
||||||
|
activeText: '开启',
|
||||||
|
inactiveText: '关闭',
|
||||||
|
activeValue: 1,
|
||||||
|
inactiveValue: 0
|
||||||
|
},
|
||||||
|
initialValue: 1
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,49 @@ import type { ISearchConfig } from "@/components/CURD/types";
|
|||||||
|
|
||||||
const searchConfig: ISearchConfig = {
|
const searchConfig: ISearchConfig = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
|
isExpand: true,
|
||||||
formItems: [
|
formItems: [
|
||||||
{
|
{
|
||||||
type: "input",
|
type: "input",
|
||||||
label: "挂账人",
|
label: "挂账人",
|
||||||
prop: "keywords",
|
prop: "debtor",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入挂账人或手机号",
|
placeholder: "请输入挂账人名称",
|
||||||
clearable: true,
|
clearable: true,
|
||||||
style: {
|
style: {
|
||||||
width: "200px",
|
width: "200px",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: "input",
|
||||||
|
label: "手机号",
|
||||||
|
prop: "mobile",
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请输入手机号",
|
||||||
|
clearable: true,
|
||||||
|
style: {
|
||||||
|
width: "200px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "select",
|
||||||
|
label: "状态",
|
||||||
|
prop: "status",
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请选择状态",
|
||||||
|
clearable: true,
|
||||||
|
style: {
|
||||||
|
width: "200px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
initialValue: '',
|
||||||
|
options: [
|
||||||
|
{ label: "停用", value: '0' },
|
||||||
|
{ label: "启用", value: '1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: "select",
|
type: "select",
|
||||||
label: "还款状态",
|
label: "还款状态",
|
||||||
@@ -28,9 +58,8 @@ const searchConfig: ISearchConfig = {
|
|||||||
},
|
},
|
||||||
initialValue: '',
|
initialValue: '',
|
||||||
options: [
|
options: [
|
||||||
{ label: "未还款", value: 'unpaid' },
|
{ label: "有欠款", value: '0' },
|
||||||
{ label: "部分还款", value: 'partial' },
|
{ label: "无欠款", value: '1' },
|
||||||
{ label: "已还清", value: 'paid' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -28,6 +28,27 @@
|
|||||||
<template #options="scope">
|
<template #options="scope">
|
||||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
</template>
|
</template>
|
||||||
|
<template #accountBalance="scope">
|
||||||
|
{{ scope.row.accountBalance }}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #owedAmount="scope">
|
||||||
|
{{
|
||||||
|
scope.row.creditAmount - scope.row.accountBalance > 0
|
||||||
|
? scope.row.creditAmount - scope.row.accountBalance
|
||||||
|
: 0
|
||||||
|
}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #expireRemindDay="scope">
|
||||||
|
<el-text>{{ scope.row.expireRemindDay }}号</el-text>
|
||||||
|
</template>
|
||||||
|
<template #expireRemind="scope">
|
||||||
|
<el-text>{{ scope.row.expireRemind }}月前</el-text>
|
||||||
|
</template>
|
||||||
|
<template #remainingAmount="scope">
|
||||||
|
{{ scope.row.creditAmount - scope.row.accountBalance }}
|
||||||
|
</template>
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" :loading="loading" @click="handleQuery">查询</el-button>
|
<el-button type="primary" icon="Search" :loading="loading" @click="handleQuery">查询</el-button>
|
||||||
<el-button @click="handleReset" icon="Refresh" :loading="loading">重置</el-button>
|
<el-button @click="handleReset" icon="Refresh" :loading="loading">重置</el-button>
|
||||||
|
<el-button icon="Printer" @click="printBusinessDialogRef.show()">经营日报</el-button>
|
||||||
|
<el-button icon="Printer" @click="printBusinessDialogRef2.show()">日结单</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-form inline>
|
<el-form inline>
|
||||||
@@ -359,6 +361,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<printBusinessDialog ref="printBusinessDialogRef" @success="printHandle" />
|
||||||
|
<printBusinessDialog ref="printBusinessDialogRef2" @success="printHandle2" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -366,6 +370,46 @@ import dayjs from "dayjs";
|
|||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import OrderApi from "@/api/order/order";
|
import OrderApi from "@/api/order/order";
|
||||||
import { downloadFile, multiplyAndFormat } from '@/utils'
|
import { downloadFile, multiplyAndFormat } from '@/utils'
|
||||||
|
import printBusinessDialog from "@/components/printBusinessDialog.vue";
|
||||||
|
|
||||||
|
const printBusinessDialogRef = ref(null)
|
||||||
|
|
||||||
|
// 打印经营日报回调
|
||||||
|
async function printHandle(res) {
|
||||||
|
try {
|
||||||
|
const shopStaff = JSON.parse(localStorage.getItem('shopStaff')) || { name: '' }
|
||||||
|
const shopName = localStorage.getItem('shopName')
|
||||||
|
await OrderApi.printDayReport({
|
||||||
|
beginDate: res.date[0],
|
||||||
|
endDate: res.date[1],
|
||||||
|
rangeType: 'CUSTOM',
|
||||||
|
shopId: localStorage.getItem('shopId') || '',
|
||||||
|
operator: shopStaff.name || shopName
|
||||||
|
})
|
||||||
|
ElMessage.success('打印成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const printBusinessDialogRef2 = ref(null)
|
||||||
|
// 打印日结单回调
|
||||||
|
async function printHandle2(res) {
|
||||||
|
try {
|
||||||
|
const shopStaff = JSON.parse(localStorage.getItem('shopStaff')) || { name: '' }
|
||||||
|
const shopName = localStorage.getItem('shopName')
|
||||||
|
await OrderApi.printDaySettle({
|
||||||
|
beginDate: res.date[0],
|
||||||
|
endDate: res.date[1],
|
||||||
|
rangeType: 'CUSTOM',
|
||||||
|
shopId: localStorage.getItem('shopId') || '',
|
||||||
|
operator: shopStaff.name || shopName
|
||||||
|
})
|
||||||
|
ElMessage.success('打印成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const queryForm = ref({
|
const queryForm = ref({
|
||||||
queryDate: dayjs().format('YYYY-MM-DD'), // 查询日期 yyyy-MM-dd
|
queryDate: dayjs().format('YYYY-MM-DD'), // 查询日期 yyyy-MM-dd
|
||||||
|
|||||||
@@ -52,15 +52,35 @@
|
|||||||
<span>营业</span>
|
<span>营业</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="u-flex" style="flex-wrap: wrap">
|
<div class="u-flex" style="flex-wrap: wrap">
|
||||||
<importData :type="9" style="margin-right: 14px;" @close="importDataClose" />
|
<importData
|
||||||
<el-select v-if="isHeadShop == 1 && loginType == 0" v-model="shopId" placeholder="选择分店"
|
:type="9"
|
||||||
style="width: 200px; margin-right: 10px;" @change="shopChange">
|
style="margin-right: 14px"
|
||||||
<el-option v-for="item in branchList" :key="item.shopId" :label="item.shopName" :value="item.shopId" />
|
@close="importDataClose"
|
||||||
|
@update="updateData"
|
||||||
|
/>
|
||||||
|
<el-select
|
||||||
|
v-if="isHeadShop == 1 && loginType == 0"
|
||||||
|
v-model="shopId"
|
||||||
|
placeholder="选择分店"
|
||||||
|
style="width: 200px; margin-right: 10px"
|
||||||
|
@change="shopChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in branchList"
|
||||||
|
:key="item.shopId"
|
||||||
|
:label="item.shopName"
|
||||||
|
:value="item.shopId"
|
||||||
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<div class="time_wrap u-flex" style="flex-shrink: 0">
|
<div class="time_wrap u-flex" style="flex-shrink: 0">
|
||||||
<div class="date_list">
|
<div class="date_list">
|
||||||
<div class="item" :class="{ active: dataListActive == index }" v-for="(item, index) in dateList"
|
<div
|
||||||
:key="item.value" @click="timeChange(item.value, index)">
|
class="item"
|
||||||
|
:class="{ active: dataListActive == index }"
|
||||||
|
v-for="(item, index) in dateList"
|
||||||
|
:key="item.value"
|
||||||
|
@click="timeChange(item.value, index)"
|
||||||
|
>
|
||||||
<!-- 标签文本 -->
|
<!-- 标签文本 -->
|
||||||
<span class="date-tab-item">{{ item.label }}</span>
|
<span class="date-tab-item">{{ item.label }}</span>
|
||||||
<!-- 分隔符:非最后一项才显示 -->
|
<!-- 分隔符:非最后一项才显示 -->
|
||||||
@@ -68,9 +88,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="u-flex">
|
<div class="u-flex">
|
||||||
<el-date-picker v-if="timeValue == 'custom'" v-model="query.createdAt" type="daterange"
|
<el-date-picker
|
||||||
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
|
v-if="timeValue == 'custom'"
|
||||||
@change="summarytrade" />
|
v-model="query.createdAt"
|
||||||
|
type="daterange"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
@change="summarytrade"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,7 +106,9 @@
|
|||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="item earnings">
|
<div class="item earnings">
|
||||||
<div class="num_wrap">
|
<div class="num_wrap">
|
||||||
<div class="num">{{ formatDecimal(trade.payAmount + trade.rechargeAmount || 0) }}</div>
|
<div class="num">
|
||||||
|
{{ formatDecimal(trade.payAmount + trade.rechargeAmount || 0) }}
|
||||||
|
</div>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
营业额(元)
|
营业额(元)
|
||||||
<el-tooltip popper-class="popper" effect="light" placement="bottom">
|
<el-tooltip popper-class="popper" effect="light" placement="bottom">
|
||||||
@@ -156,20 +185,27 @@
|
|||||||
<!-- <div class="t">{{ formatDecimal(tradeSale.totalpayAmount || 0) }}</div> -->
|
<!-- <div class="t">{{ formatDecimal(tradeSale.totalpayAmount || 0) }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="line_gropress">
|
<div class="line_gropress">
|
||||||
<div class="gropress l" :style="{
|
<div
|
||||||
width: `${trade.payAmount
|
class="gropress l"
|
||||||
? (trade.payAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) *
|
:style="{
|
||||||
100
|
width: `${
|
||||||
: 0
|
trade.payAmount
|
||||||
|
? (trade.payAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) * 100
|
||||||
|
: 0
|
||||||
}%`,
|
}%`,
|
||||||
}" />
|
}"
|
||||||
<div class="gropress r" :style="{
|
/>
|
||||||
width: `${trade.refundAmount
|
<div
|
||||||
? (trade.refundAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) *
|
class="gropress r"
|
||||||
100
|
:style="{
|
||||||
: 0
|
width: `${
|
||||||
|
trade.refundAmount
|
||||||
|
? (trade.refundAmount / (trade.payAmount * 1 + trade.refundAmount * 1)) *
|
||||||
|
100
|
||||||
|
: 0
|
||||||
}%`,
|
}%`,
|
||||||
}" />
|
}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="line_btm">
|
<div class="line_btm">
|
||||||
<el-icon class="icon el-icon-caret-right" />
|
<el-icon class="icon el-icon-caret-right" />
|
||||||
@@ -185,22 +221,30 @@
|
|||||||
<!-- <div class="t">{{ formatDecimal(tradeSale.totalVipAmount || 0) }}</div> -->
|
<!-- <div class="t">{{ formatDecimal(tradeSale.totalVipAmount || 0) }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="line_gropress">
|
<div class="line_gropress">
|
||||||
<div class="gropress l" :style="{
|
<div
|
||||||
width: `${trade.rechargeAmount
|
class="gropress l"
|
||||||
? (trade.rechargeAmount /
|
:style="{
|
||||||
(trade.rechargeAmount * 1 + trade.rechargeRefundAmount * 1)) *
|
width: `${
|
||||||
100
|
trade.rechargeAmount
|
||||||
: 0
|
? (trade.rechargeAmount /
|
||||||
|
(trade.rechargeAmount * 1 + trade.rechargeRefundAmount * 1)) *
|
||||||
|
100
|
||||||
|
: 0
|
||||||
}%`,
|
}%`,
|
||||||
}" />
|
}"
|
||||||
<div class="gropress r" :style="{
|
/>
|
||||||
width: `${trade.rechargeRefundAmount
|
<div
|
||||||
? (trade.rechargeRefundAmount /
|
class="gropress r"
|
||||||
(trade.rechargeAmount * 1 + trade.rechargeRefundAmount * 1)) *
|
:style="{
|
||||||
100
|
width: `${
|
||||||
: 0
|
trade.rechargeRefundAmount
|
||||||
|
? (trade.rechargeRefundAmount /
|
||||||
|
(trade.rechargeAmount * 1 + trade.rechargeRefundAmount * 1)) *
|
||||||
|
100
|
||||||
|
: 0
|
||||||
}%`,
|
}%`,
|
||||||
}" />
|
}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="line_btm">
|
<div class="line_btm">
|
||||||
<el-icon class="icon el-icon-caret-right" />
|
<el-icon class="icon el-icon-caret-right" />
|
||||||
@@ -251,8 +295,11 @@
|
|||||||
<div class="item item1">
|
<div class="item item1">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
客单价
|
客单价
|
||||||
<el-tooltip effect="dark" :content="`订单实付金额(${trade.payAmount})/就餐人数(${trade.customerCount || 0})`"
|
<el-tooltip
|
||||||
placement="top">
|
effect="dark"
|
||||||
|
:content="`订单实付金额(${trade.payAmount})/就餐人数(${trade.customerCount || 0})`"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<QuestionFilled />
|
<QuestionFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -260,15 +307,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<img class="img" src="@/assets/images/data_home_item1_icon.png" />
|
<img class="img" src="@/assets/images/data_home_item1_icon.png" />
|
||||||
<div class="t" style="color: #0080FF;">{{ formatDecimal(trade.avgPayAmount || 0) }}</div>
|
<div class="t" style="color: #0080ff">
|
||||||
|
{{ formatDecimal(trade.avgPayAmount || 0) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item item2">
|
<div class="item item2">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
翻台率
|
翻台率
|
||||||
<el-tooltip effect="dark"
|
<el-tooltip
|
||||||
|
effect="dark"
|
||||||
:content="`翻台率=(客单数(${trade.customerCount || 0})-桌台数(${trade.tableCount || 0}))/桌台数*100%`"
|
:content="`翻台率=(客单数(${trade.customerCount || 0})-桌台数(${trade.tableCount || 0}))/桌台数*100%`"
|
||||||
placement="top">
|
placement="top"
|
||||||
|
>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<QuestionFilled />
|
<QuestionFilled />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -276,7 +327,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<img class="img" src="@/assets/images/data_home_item2_icon.png" />
|
<img class="img" src="@/assets/images/data_home_item2_icon.png" />
|
||||||
<div class="t" style="color: #FFB200;">{{ trade.turnoverRate || 0 }}%</div>
|
<div class="t" style="color: #ffb200">{{ trade.turnoverRate || 0 }}%</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item item3">
|
<div class="item item3">
|
||||||
@@ -295,43 +346,57 @@
|
|||||||
<div class="left">
|
<div class="left">
|
||||||
<span>新客立减</span>
|
<span>新客立减</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.newCustomerDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.newCustomerDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>满减活动</span>
|
<span>满减活动</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.fullDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.fullDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>优惠券抵扣</span>
|
<span>优惠券抵扣</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.couponDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.couponDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>积分抵扣</span>
|
<span>积分抵扣</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.pointDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.pointDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>霸王餐</span>
|
<span>霸王餐</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.backDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.backDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>会员折扣</span>
|
<span>会员折扣</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.memberDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.memberDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<span>订单改价</span>
|
<span>订单改价</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="num">{{ multiplyAndFormat(trade.orderPriceDiscountAmount || 0) }}</span>
|
<span class="num">
|
||||||
|
{{ multiplyAndFormat(trade.orderPriceDiscountAmount || 0) }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -342,14 +407,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<img class="img" src="@/assets/images/data_home_item3_icon.png" />
|
<img class="img" src="@/assets/images/data_home_item3_icon.png" />
|
||||||
<div class="t" style="color: #FF8000;">{{ formatDecimal(trade.discountAmount || 0) }}</div>
|
<div class="t" style="color: #ff8000">
|
||||||
|
{{ formatDecimal(trade.discountAmount || 0) }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item item4">
|
<div class="item item4">
|
||||||
<div class="title">优惠笔数</div>
|
<div class="title">优惠笔数</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<img class="img" src="@/assets/images/data_home_item4_icon.png" />
|
<img class="img" src="@/assets/images/data_home_item4_icon.png" />
|
||||||
<div class="t" style="color: #00CB71;">{{ trade.discountCount || 0 }}</div>
|
<div class="t" style="color: #00cb71">{{ trade.discountCount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item item5">
|
<div class="item item5">
|
||||||
@@ -357,13 +424,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="title">毛利润</div>
|
<div class="title">毛利润</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<div class="t" style="color: #0000C2;">{{ trade.profitAmount || 0 }}</div>
|
<div class="t" style="color: #0000c2">{{ trade.profitAmount || 0 }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="title">毛利率</div>
|
<div class="title">毛利率</div>
|
||||||
<div class="icon_wrap">
|
<div class="icon_wrap">
|
||||||
<div class="t" style="color: #0000C2;">{{ trade.profitRate || 0 }}%</div>
|
<div class="t" style="color: #0000c2">{{ trade.profitRate || 0 }}%</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -392,10 +459,18 @@
|
|||||||
<div class="item">
|
<div class="item">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="tab_wrap">
|
<div class="tab_wrap">
|
||||||
<div class="item" :class="{ active: lineChartType == 0 }" @click="lineChartTypeChange(0)">
|
<div
|
||||||
|
class="item"
|
||||||
|
:class="{ active: lineChartType == 0 }"
|
||||||
|
@click="lineChartTypeChange(0)"
|
||||||
|
>
|
||||||
销售趋势
|
销售趋势
|
||||||
</div>
|
</div>
|
||||||
<div class="item" :class="{ active: lineChartType == 1 }" @click="lineChartTypeChange(1)">
|
<div
|
||||||
|
class="item"
|
||||||
|
:class="{ active: lineChartType == 1 }"
|
||||||
|
@click="lineChartTypeChange(1)"
|
||||||
|
>
|
||||||
支付占比
|
支付占比
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -404,9 +479,20 @@
|
|||||||
<el-radio-button value="30">30天</el-radio-button>
|
<el-radio-button value="30">30天</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
<div v-show="lineChartType == 0" ref="saleChart" v-loading="saleLoading" class="chart" style="height: 350px" />
|
<div
|
||||||
<div v-show="lineChartType == 1" ref="payChart" v-loading="payChartLoading" class="chart"
|
v-show="lineChartType == 0"
|
||||||
style="height: 350px" />
|
ref="saleChart"
|
||||||
|
v-loading="saleLoading"
|
||||||
|
class="chart"
|
||||||
|
style="height: 350px"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
v-show="lineChartType == 1"
|
||||||
|
ref="payChart"
|
||||||
|
v-loading="payChartLoading"
|
||||||
|
class="chart"
|
||||||
|
style="height: 350px"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 商品销售排行 -->
|
<!-- 商品销售排行 -->
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -466,7 +552,12 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="initInterestRate" v-loading="initInterestRateLoading" class="chart" style="height: 350px" />
|
<div
|
||||||
|
ref="initInterestRate"
|
||||||
|
v-loading="initInterestRateLoading"
|
||||||
|
class="chart"
|
||||||
|
style="height: 350px"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 成本(元) -->
|
<!-- 成本(元) -->
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -505,12 +596,16 @@
|
|||||||
<script>
|
<script>
|
||||||
import importData from "@/components/importData/index.vue";
|
import importData from "@/components/importData/index.vue";
|
||||||
import dataSummaryApi from "@/api/order/data-summary";
|
import dataSummaryApi from "@/api/order/data-summary";
|
||||||
|
import finceApi from "@/api/order/fince";
|
||||||
|
|
||||||
import ShopApi from "@/api/account/shop";
|
import ShopApi from "@/api/account/shop";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import { debounce, formatDecimal } from "@/utils/tools";
|
import { debounce, formatDecimal } from "@/utils/tools";
|
||||||
import { formatDateRange } from './utils/index.js'
|
import { formatDateRange } from "./utils/index.js";
|
||||||
import { multiplyAndFormat } from '@/utils/index.js'
|
import { multiplyAndFormat } from "@/utils/index.js";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "home",
|
name: "home",
|
||||||
components: { importData },
|
components: { importData },
|
||||||
@@ -635,12 +730,12 @@ export default {
|
|||||||
shopInfo: JSON.parse(localStorage.getItem("userInfo")),
|
shopInfo: JSON.parse(localStorage.getItem("userInfo")),
|
||||||
initInterestRateLoading: true,
|
initInterestRateLoading: true,
|
||||||
initInterestRate: null,
|
initInterestRate: null,
|
||||||
initInterestRateTime: '',
|
initInterestRateTime: "",
|
||||||
costLoading: true,
|
costLoading: true,
|
||||||
costRef: null,
|
costRef: null,
|
||||||
costUpdateTime: '',
|
costUpdateTime: "",
|
||||||
interestRateDay: '7',
|
interestRateDay: "7",
|
||||||
costDay: '7'
|
costDay: "7",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -660,11 +755,11 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let shopInfo = JSON.parse(localStorage.getItem('userInfo'))
|
let shopInfo = JSON.parse(localStorage.getItem("userInfo"));
|
||||||
if (shopInfo.isHeadShop) {
|
if (shopInfo.isHeadShop) {
|
||||||
this.shopId = shopInfo.id
|
this.shopId = shopInfo.id;
|
||||||
} else {
|
} else {
|
||||||
this.shopId = localStorage.getItem('shopId')
|
this.shopId = localStorage.getItem("shopId");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 增加首页提示是否账号30天过期
|
// 增加首页提示是否账号30天过期
|
||||||
@@ -680,8 +775,8 @@ export default {
|
|||||||
this.dateProduct();
|
this.dateProduct();
|
||||||
// this.summaryDateGet();
|
// this.summaryDateGet();
|
||||||
this.timeChange(this.timeValue);
|
this.timeChange(this.timeValue);
|
||||||
this.profitRateBarChart()
|
this.profitRateBarChart();
|
||||||
this.costLineChart()
|
this.costLineChart();
|
||||||
|
|
||||||
this.__resizeHandler = debounce(() => {
|
this.__resizeHandler = debounce(() => {
|
||||||
if (this.saleChart) {
|
if (this.saleChart) {
|
||||||
@@ -710,18 +805,33 @@ export default {
|
|||||||
// }
|
// }
|
||||||
}, 100);
|
}, 100);
|
||||||
window.addEventListener("resize", this.__resizeHandler);
|
window.addEventListener("resize", this.__resizeHandler);
|
||||||
this.geiShopList()
|
this.geiShopList();
|
||||||
// this.initCardUserChart();
|
// this.initCardUserChart();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
updateData(e) {
|
||||||
|
finceApi
|
||||||
|
.financeBase({
|
||||||
|
shopId: this.shopId,
|
||||||
|
type: "all",
|
||||||
|
date: e,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
ElMessageBox.confirm("经营数据重新计算中,请稍后刷新页面查看", "提示", {
|
||||||
|
confirmButtonText: "知道了",
|
||||||
|
showCancelButton: false,
|
||||||
|
type: "warning",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
importDataClose() {
|
importDataClose() {
|
||||||
// this.summaryGet();
|
// this.summaryGet();
|
||||||
this.dateAmount();
|
this.dateAmount();
|
||||||
this.dateProduct();
|
this.dateProduct();
|
||||||
// this.summaryDateGet();
|
// this.summaryDateGet();
|
||||||
this.timeChange(this.timeValue);
|
this.timeChange(this.timeValue);
|
||||||
this.profitRateBarChart()
|
this.profitRateBarChart();
|
||||||
this.costLineChart()
|
this.costLineChart();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 获取分店列表
|
* 获取分店列表
|
||||||
@@ -729,29 +839,29 @@ export default {
|
|||||||
async geiShopList() {
|
async geiShopList() {
|
||||||
try {
|
try {
|
||||||
if (this.shopInfo.isHeadShop) {
|
if (this.shopInfo.isHeadShop) {
|
||||||
let res = await ShopApi.getBranchList()
|
let res = await ShopApi.getBranchList();
|
||||||
this.branchList = res;
|
this.branchList = res;
|
||||||
this.shopId = res[0].shopId
|
this.shopId = res[0].shopId;
|
||||||
} else {
|
} else {
|
||||||
this.shopId = this.shopInfo.id
|
this.shopId = this.shopInfo.id;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('获取分店列表===', error);
|
console.log("获取分店列表===", error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shopChange() {
|
shopChange() {
|
||||||
this.summarytrade();
|
this.summarytrade();
|
||||||
this.lineChartTypeChange(this.lineChartType)
|
this.lineChartTypeChange(this.lineChartType);
|
||||||
this.dateProduct()
|
this.dateProduct();
|
||||||
|
|
||||||
this.profitRateBarChart()
|
this.profitRateBarChart();
|
||||||
this.costLineChart()
|
this.costLineChart();
|
||||||
},
|
},
|
||||||
// 切换时间
|
// 切换时间
|
||||||
timeChange(e, index = 0) {
|
timeChange(e, index = 0) {
|
||||||
this.dataListActive = index;
|
this.dataListActive = index;
|
||||||
this.timeValue = e;
|
this.timeValue = e;
|
||||||
this.query.createdAt = formatDateRange(e)
|
this.query.createdAt = formatDateRange(e);
|
||||||
if (e != "custom") {
|
if (e != "custom") {
|
||||||
this.summarytrade();
|
this.summarytrade();
|
||||||
}
|
}
|
||||||
@@ -767,7 +877,7 @@ export default {
|
|||||||
beginDate: this.query.createdAt[0],
|
beginDate: this.query.createdAt[0],
|
||||||
endDate: this.query.createdAt[1],
|
endDate: this.query.createdAt[1],
|
||||||
rangeType: this.timeValue,
|
rangeType: this.timeValue,
|
||||||
shopId: this.shopId
|
shopId: this.shopId,
|
||||||
});
|
});
|
||||||
this.trade = res;
|
this.trade = res;
|
||||||
this.tradeSale = res.sale;
|
this.tradeSale = res.sale;
|
||||||
@@ -990,7 +1100,7 @@ export default {
|
|||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
borderColor: "#eee",
|
borderColor: "#eee",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
|
boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
|
||||||
},
|
},
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
@@ -1006,11 +1116,11 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
grid: {
|
grid: {
|
||||||
top: '5%',
|
top: "5%",
|
||||||
right: '5%',
|
right: "5%",
|
||||||
bottom: '8%',
|
bottom: "8%",
|
||||||
left: '8%',
|
left: "8%",
|
||||||
containLabel: true // 确保标签不溢出,不影响点的显示
|
containLabel: true, // 确保标签不溢出,不影响点的显示
|
||||||
},
|
},
|
||||||
color: "#165DFF", // 折线和默认点的颜色
|
color: "#165DFF", // 折线和默认点的颜色
|
||||||
yAxis: [
|
yAxis: [
|
||||||
@@ -1035,8 +1145,8 @@ export default {
|
|||||||
borderColor: "#000", // 黑色边框
|
borderColor: "#000", // 黑色边框
|
||||||
borderWidth: 2, // 边框宽度
|
borderWidth: 2, // 边框宽度
|
||||||
// 悬浮时填充色不变(仍为 #165DFF)
|
// 悬浮时填充色不变(仍为 #165DFF)
|
||||||
color: "#165DFF"
|
color: "#165DFF",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// 确保所有数据点都显示(避免自动隐藏)
|
// 确保所有数据点都显示(避免自动隐藏)
|
||||||
showAllSymbol: true,
|
showAllSymbol: true,
|
||||||
@@ -1044,8 +1154,8 @@ export default {
|
|||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: "#165DFF", // 点的填充色(与折线一致)
|
color: "#165DFF", // 点的填充色(与折线一致)
|
||||||
borderWidth: 1, // 基础状态可加细边框(可选,不加则无)
|
borderWidth: 1, // 基础状态可加细边框(可选,不加则无)
|
||||||
borderColor: "#fff" // 基础状态边框颜色(与背景区分,可选)
|
borderColor: "#fff", // 基础状态边框颜色(与背景区分,可选)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -1131,8 +1241,8 @@ export default {
|
|||||||
this.initInterestRate = echarts.init(this.$refs.initInterestRate);
|
this.initInterestRate = echarts.init(this.$refs.initInterestRate);
|
||||||
|
|
||||||
// 预处理数据:将毛利率和净利率按索引对应(关键,用于手动匹配)
|
// 预处理数据:将毛利率和净利率按索引对应(关键,用于手动匹配)
|
||||||
const profitRateData = data.map(item => item.profitRate || 0);
|
const profitRateData = data.map((item) => item.profitRate || 0);
|
||||||
const netProfitRateData = data.map(item => item.netProfitRate || 0);
|
const netProfitRateData = data.map((item) => item.netProfitRate || 0);
|
||||||
|
|
||||||
this.initInterestRate.setOption({
|
this.initInterestRate.setOption({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -1159,7 +1269,7 @@ export default {
|
|||||||
backgroundColor: "#fff",
|
backgroundColor: "#fff",
|
||||||
borderColor: "#eee",
|
borderColor: "#eee",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
boxShadow: "0 2px 8px rgba(0,0,0,0.08)"
|
boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
|
||||||
},
|
},
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
@@ -1184,10 +1294,10 @@ export default {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
grid: {
|
grid: {
|
||||||
top: '5%',
|
top: "5%",
|
||||||
right: '5%',
|
right: "5%",
|
||||||
bottom: '8%',
|
bottom: "8%",
|
||||||
left: '8%',
|
left: "8%",
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@@ -1196,7 +1306,7 @@ export default {
|
|||||||
barGap: "0%", // 保持柱子紧贴
|
barGap: "0%", // 保持柱子紧贴
|
||||||
barWidth: time.length <= 7 ? "50%" : "30%",
|
barWidth: time.length <= 7 ? "50%" : "30%",
|
||||||
data: profitRateData, // 预处理后的毛利率数据
|
data: profitRateData, // 预处理后的毛利率数据
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -1359,9 +1469,12 @@ export default {
|
|||||||
async profitRateBarChart() {
|
async profitRateBarChart() {
|
||||||
try {
|
try {
|
||||||
this.initInterestRateLoading = true;
|
this.initInterestRateLoading = true;
|
||||||
const res = await dataSummaryApi.profitRateBarChart({ day: this.interestRateDay, shopId: this.shopId });
|
const res = await dataSummaryApi.profitRateBarChart({
|
||||||
|
day: this.interestRateDay,
|
||||||
|
shopId: this.shopId,
|
||||||
|
});
|
||||||
|
|
||||||
this.initInterestRateTime = dayjs().format('HH:mm')
|
this.initInterestRateTime = dayjs().format("HH:mm");
|
||||||
|
|
||||||
const data = res.map((item) => {
|
const data = res.map((item) => {
|
||||||
return {
|
return {
|
||||||
@@ -1385,7 +1498,7 @@ export default {
|
|||||||
this.costLoading = true;
|
this.costLoading = true;
|
||||||
const res = await dataSummaryApi.costLineChart({ day: this.costDay, shopId: this.shopId });
|
const res = await dataSummaryApi.costLineChart({ day: this.costDay, shopId: this.shopId });
|
||||||
|
|
||||||
this.costUpdateTime = dayjs().format('HH:mm')
|
this.costUpdateTime = dayjs().format("HH:mm");
|
||||||
|
|
||||||
const data = res.map((item) => item.productCostAmount || 0);
|
const data = res.map((item) => item.productCostAmount || 0);
|
||||||
const time = res.map((item) => item.tradeDay);
|
const time = res.map((item) => item.tradeDay);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
<span v-if="!downloadLoading">导出Excel</span>
|
<span v-if="!downloadLoading">导出Excel</span>
|
||||||
<span v-else>下载中...</span>
|
<span v-else>下载中...</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button icon="Printer" :loading="printLoading" @click="$refs.printBusinessDialogRef.show()">打印</el-button>
|
||||||
<importData :type="7" @close="getTableData" />
|
<importData :type="7" @close="getTableData" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -185,6 +186,7 @@
|
|||||||
@current-change="paginationChange" @size-change="sizeChange"
|
@current-change="paginationChange" @size-change="sizeChange"
|
||||||
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||||
</div>
|
</div>
|
||||||
|
<printBusinessDialog ref="printBusinessDialogRef" title="商品报表" @success="printBusinessConfirm" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -197,9 +199,10 @@ import ShopApi from "@/api/account/shop";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { downloadFile, multiplyAndFormat } from "@/utils/index";
|
import { downloadFile, multiplyAndFormat } from "@/utils/index";
|
||||||
import { formatDateRange } from './utils/index.js'
|
import { formatDateRange } from './utils/index.js'
|
||||||
|
import printBusinessDialog from '@/components/printBusinessDialog.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { importData },
|
components: { importData, printBusinessDialog },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
multiplyAndFormat,
|
multiplyAndFormat,
|
||||||
@@ -233,7 +236,8 @@ export default {
|
|||||||
// dayjs(time):将原生 Date 转为 dayjs 对象
|
// dayjs(time):将原生 Date 转为 dayjs 对象
|
||||||
// isAfter:判断目标日期是否在今天之后
|
// isAfter:判断目标日期是否在今天之后
|
||||||
return dayjs(time).isAfter(dayjs().startOf('day'));
|
return dayjs(time).isAfter(dayjs().startOf('day'));
|
||||||
}
|
},
|
||||||
|
printLoading: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
filters: {
|
filters: {
|
||||||
@@ -255,6 +259,34 @@ export default {
|
|||||||
this.geiShopList();
|
this.geiShopList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 确认打印
|
||||||
|
printBusinessConfirm(res) {
|
||||||
|
this.printHandle(res.date)
|
||||||
|
},
|
||||||
|
// 打印
|
||||||
|
async printHandle(date) {
|
||||||
|
try {
|
||||||
|
const shopStaff = JSON.parse(localStorage.getItem('shopStaff')) || { name: '' }
|
||||||
|
const shopName = localStorage.getItem('shopName')
|
||||||
|
|
||||||
|
this.printLoading = true
|
||||||
|
|
||||||
|
await saleSummaryApi.print({
|
||||||
|
beginDate: date[0],
|
||||||
|
endDate: date[1],
|
||||||
|
categoryId: this.query.prodCategoryId,
|
||||||
|
productName: this.query.productName,
|
||||||
|
shopId: this.shopId,
|
||||||
|
rangeType: this.timeValue,
|
||||||
|
operator: shopStaff.name || shopName
|
||||||
|
})
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.printLoading = false
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 获取分店列表
|
* 获取分店列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
<el-table-column prop="shopName" align="center" label="商户名称" />
|
<el-table-column prop="shopName" align="center" label="商户名称" />
|
||||||
<el-table-column prop="staffName" align="center" label="职员名称" />
|
<el-table-column prop="staffName" align="center" label="职员名称" />
|
||||||
<el-table-column prop="orderCount" align="center" label="订单数量" />
|
<el-table-column prop="orderCount" align="center" label="订单数量" />
|
||||||
<el-table-column prop="handAmount" align="center" label="应交金额" />
|
<el-table-column prop="orderTurnover" align="center" label="应交金额" />
|
||||||
<el-table-column prop="quickInAmount" align="center" label="快捷收款金额" />
|
<el-table-column prop="balance" align="center" label="余额支付" />
|
||||||
<el-table-column prop="refundAmount" align="center" label="退款金额" />
|
<el-table-column prop="refundAmount" align="center" label="退款金额" />
|
||||||
<el-table-column prop="handAmount" align="center" label="总收入" />
|
<el-table-column prop="turnover" align="center" label="总收入" />
|
||||||
<el-table-column prop="loginTime" align="center" label="开始时间" />
|
<el-table-column prop="loginTime" align="center" label="开始时间" />
|
||||||
<el-table-column prop="handoverTime" align="center" label="交班时间" />
|
<el-table-column prop="handoverTime" align="center" label="交班时间" />
|
||||||
<el-table-column label="操作" align="center">
|
<el-table-column label="操作" align="center">
|
||||||
|
|||||||
@@ -15,9 +15,13 @@ const modalConfig: IModalConfig<addRequest> = {
|
|||||||
},
|
},
|
||||||
formAction: function (data) {
|
formAction: function (data) {
|
||||||
let obj = { ...data }
|
let obj = { ...data }
|
||||||
obj.printType = data.printType.join(',')
|
console.log("打印类型", data);
|
||||||
|
// obj.printType = data.printType.join(',')
|
||||||
obj.categoryIds = JSON.stringify(data.categoryIdsArr)
|
obj.categoryIds = JSON.stringify(data.categoryIdsArr)
|
||||||
obj.categoryList = JSON.stringify(data.categoryIdsArr)
|
obj.categoryList = JSON.stringify(data.categoryIdsArr)
|
||||||
|
if (data.classifyPrint == 0) {
|
||||||
|
obj.categoryIds = ''
|
||||||
|
}
|
||||||
// obj.categoryIds = '[' + data.categoryIdsArr.join(',') + ']'
|
// obj.categoryIds = '[' + data.categoryIdsArr.join(',') + ']'
|
||||||
return printerApi.add(obj);
|
return printerApi.add(obj);
|
||||||
},
|
},
|
||||||
@@ -85,7 +89,7 @@ const modalConfig: IModalConfig<addRequest> = {
|
|||||||
{
|
{
|
||||||
type: "select",
|
type: "select",
|
||||||
label: "打印类型",
|
label: "打印类型",
|
||||||
prop: "subType",
|
prop: "printType",
|
||||||
rules: [{ required: false, message: "请选择打印类型", trigger: "blur" }],
|
rules: [{ required: false, message: "请选择打印类型", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择打印类型",
|
placeholder: "请选择打印类型",
|
||||||
@@ -103,7 +107,7 @@ const modalConfig: IModalConfig<addRequest> = {
|
|||||||
{
|
{
|
||||||
type: "select",
|
type: "select",
|
||||||
label: "打印机品牌",
|
label: "打印机品牌",
|
||||||
prop: "contentType",
|
prop: "brand",
|
||||||
rules: [{ required: true, message: "请选择打印机品牌", trigger: "blur" }],
|
rules: [{ required: true, message: "请选择打印机品牌", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择打印机品牌",
|
placeholder: "请选择打印机品牌",
|
||||||
@@ -139,27 +143,27 @@ const modalConfig: IModalConfig<addRequest> = {
|
|||||||
label: "",
|
label: "",
|
||||||
initialValue: []
|
initialValue: []
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
type: "radio",
|
type: "radio",
|
||||||
label: "打印数量",
|
label: "打印数量",
|
||||||
prop: "printQty",
|
prop: "printNum",
|
||||||
options: options.printQty,
|
options: options.printQty,
|
||||||
initialValue: options.printQty[0].value
|
initialValue: options.printQty[0].value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "radio",
|
type: "radio",
|
||||||
label: "打印方式",
|
label: "打印方式",
|
||||||
prop: "printMethod",
|
prop: "kitchenPrintMode",
|
||||||
options: options.printMethod,
|
options: options.printMethod,
|
||||||
initialValue: options.printMethod[0].value
|
initialValue: options.printMethod[0].value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "checkbox",
|
type: "custom",
|
||||||
label: "打印类型",
|
label: "打印类型",
|
||||||
prop: "printType",
|
prop: "printContentType",
|
||||||
options: options.printType,
|
options: options.printType,
|
||||||
initialValue: options.printType.map(v => v.value)
|
initialValue: options.printType.map(v => v.value),
|
||||||
|
slotName: 'printTypeSlot'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "打印机状态",
|
label: "打印机状态",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
export const options: optionObject = {
|
export const options: optionObject = {
|
||||||
connectionType: [
|
connectionType: [
|
||||||
{ label: "USB", value: 'USB' },
|
{ label: "USB", value: 'USB' },
|
||||||
{ label: "网络", value: '网络' },
|
{ label: "云打印", value: '云打印' },
|
||||||
{ label: "蓝牙", value: '蓝牙' },
|
{ label: "局域网", value: '局域网' },
|
||||||
],
|
],
|
||||||
subType: [
|
subType: [
|
||||||
{ label: "标签", value: 'label' },
|
{ label: "标签", value: 'label' },
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ const contentConfig: IContentConfig<getListRequest> = {
|
|||||||
label: "状态",
|
label: "状态",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "status",
|
prop: "status",
|
||||||
templet: "switch",
|
templet: "custom",
|
||||||
slotName: "status",
|
slotName: "status"
|
||||||
},
|
},
|
||||||
{ label: "创建时间", align: "center", prop: "createTime" },
|
{ label: "创建时间", align: "center", prop: "createTime" },
|
||||||
// {
|
// {
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ const modalConfig: IModalConfig<editRequest> = {
|
|||||||
obj.categoryIds = JSON.stringify(data.categoryIdsArr)
|
obj.categoryIds = JSON.stringify(data.categoryIdsArr)
|
||||||
obj.categoryList = JSON.stringify(data.categoryIdsArr)
|
obj.categoryList = JSON.stringify(data.categoryIdsArr)
|
||||||
}
|
}
|
||||||
|
if (data.classifyPrint == 0) {
|
||||||
|
obj.categoryIds = ''
|
||||||
|
}
|
||||||
return printerApi.edit(obj);
|
return printerApi.edit(obj);
|
||||||
},
|
},
|
||||||
beforeSubmit(data) {
|
beforeSubmit(data) {
|
||||||
@@ -157,13 +160,12 @@ const modalConfig: IModalConfig<editRequest> = {
|
|||||||
initialValue: options.printMethod[0].value
|
initialValue: options.printMethod[0].value
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "checkbox",
|
type: "custom",
|
||||||
label: "打印类型",
|
label: "打印类型",
|
||||||
prop: "printType",
|
prop: "printContentType",
|
||||||
options: options.printType,
|
options: '',
|
||||||
initialValue: options.printType.map(v => v.value)
|
initialValue: ''
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "打印机状态",
|
label: "打印机状态",
|
||||||
prop: "status",
|
prop: "status",
|
||||||
@@ -174,6 +176,16 @@ const modalConfig: IModalConfig<editRequest> = {
|
|||||||
inactiveValue: 0,
|
inactiveValue: 0,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "媒体音开关",
|
||||||
|
prop: "volumeSwitch",
|
||||||
|
type: "switch",
|
||||||
|
initialValue: 1,
|
||||||
|
attrs: {
|
||||||
|
activeValue: 1,
|
||||||
|
inactiveValue: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,16 +9,16 @@
|
|||||||
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
||||||
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
||||||
<template #status="scope">
|
<!-- <template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template> -->
|
||||||
<template #contentType="scope">
|
<template #contentType="scope">
|
||||||
{{ scope.row.contentType == 'yxyPrinter' ? "云想印" : "飞鹅" }}
|
{{ scope.row.contentType == "yxyPrinter" ? "云想印" : "飞鹅" }}
|
||||||
</template>
|
</template>
|
||||||
<template #subType="scope">
|
<template #subType="scope">
|
||||||
{{ scope.row.subType == 'label' ? "标签" : "小票" }}
|
{{ scope.row.subType == "label" ? "标签" : "小票" }}
|
||||||
</template>
|
</template>
|
||||||
<template #caozuo="scope">
|
<template #caozuo="scope">
|
||||||
{{ scope }}
|
{{ scope }}
|
||||||
@@ -26,10 +26,18 @@
|
|||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #status="scope">
|
||||||
|
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0"
|
||||||
|
@click="statusChange($event, scope.row)"></el-switch>
|
||||||
|
</template>
|
||||||
<template #operate="scope">
|
<template #operate="scope">
|
||||||
<div v-if="scope.row.connectionType != 'USB'">
|
<div v-if="scope.row.connectionType != 'USB'">
|
||||||
<el-button @click="handleEditClick(scope.row)" icon="Edit" type="primary" link>编辑</el-button>
|
<el-button @click="handleEditClick(scope.row)" icon="Edit" type="primary" link>
|
||||||
<el-button @click="handdeleteevent(scope.row)" icon="Delete" type="danger" link>删除</el-button>
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="handdeleteevent(scope.row)" icon="Delete" type="danger" link>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- <template #mobile="scope">
|
<!-- <template #mobile="scope">
|
||||||
@@ -39,10 +47,21 @@
|
|||||||
</page-content>
|
</page-content>
|
||||||
|
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
|
<!-- <page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #printTypeSlot="scope">
|
||||||
|
<div class="row" v-for="(item, index) in printTypeList" :key="index">
|
||||||
|
<div class="title">{{ item.label }}</div>
|
||||||
|
<div class="cont">
|
||||||
|
<el-checkbox-group v-model="item.values" @change="printTypeChange($event, index, scope)">
|
||||||
|
<el-checkbox :label="item.label" :value="item.value" v-for="item in item.list"
|
||||||
|
:key="item.value"></el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #classifyPrintData="scope">
|
<template #classifyPrintData="scope">
|
||||||
<template v-if="scope.formData.classifyPrint == 1">
|
<template v-if="scope.formData.classifyPrint == 1">
|
||||||
<el-checkbox-group v-model="scope.formData.categoryIdsArr">
|
<el-checkbox-group v-model="scope.formData.categoryIdsArr">
|
||||||
@@ -52,13 +71,24 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal> -->
|
||||||
|
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
<!-- <page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
||||||
</template>
|
</template>
|
||||||
|
<template #printTypeSlot="scope">
|
||||||
|
<div class="row" v-for="(item, index) in printTypeList" :key="index">
|
||||||
|
<div class="title">{{ item.label }}</div>
|
||||||
|
<div class="cont">
|
||||||
|
<el-checkbox-group v-model="item.values" @change="printTypeChange($event, index, scope)">
|
||||||
|
<el-checkbox :label="item.label" :value="item.value" v-for="item in item.list"
|
||||||
|
:key="item.value"></el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #classifyPrintData="scope">
|
<template #classifyPrintData="scope">
|
||||||
<template v-if="scope.formData.classifyPrint == 1">
|
<template v-if="scope.formData.classifyPrint == 1">
|
||||||
<el-checkbox-group v-model="scope.formData.categoryIdsArr">
|
<el-checkbox-group v-model="scope.formData.categoryIdsArr">
|
||||||
@@ -68,11 +98,103 @@
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal> -->
|
||||||
|
|
||||||
|
<el-dialog :title="form.id ? '编辑打印机' : '添加打印机'" width="800px" v-model="visible" @closed="dialogClosed"
|
||||||
|
@open="dialogOpen">
|
||||||
|
<div style="height: 60vh;overflow-y: auto;" ref="formDivRef">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
||||||
|
<el-form-item label="设备名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入设备名称"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备类型">
|
||||||
|
<el-radio-group v-model="form.connectionType">
|
||||||
|
<el-radio-button label="USB" value="USB"></el-radio-button>
|
||||||
|
<el-radio-button label="云打印" value="云打印"></el-radio-button>
|
||||||
|
<el-radio-button label="局域网" value="局域网"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="小票类型">
|
||||||
|
<el-radio-group v-model="form.printType">
|
||||||
|
<el-radio-button label="标签" value="label"></el-radio-button>
|
||||||
|
<el-radio-button label="小票" value="cash"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="打印机品牌" prop="brand">
|
||||||
|
<el-radio-group v-model="form.brand">
|
||||||
|
<el-radio-button label="飞鹅"></el-radio-button>
|
||||||
|
<el-radio-button label="云想印"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="ip地址/MAC地址" prop="address">
|
||||||
|
<el-input v-model="form.address" placeholder="请输入ip地址/MAC地址"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="端口" prop="port">
|
||||||
|
<el-input v-model="form.port" placeholder="请输入端口"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="小票尺寸" prop="receiptSize">
|
||||||
|
<el-radio-group v-model="form.receiptSize">
|
||||||
|
<el-radio-button label="58mm"></el-radio-button>
|
||||||
|
<el-radio-button label="80mm"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="打印数量" prop="printNum">
|
||||||
|
<el-input-number v-model="form.printNum" :step="1" :min="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="打印内容" prop="printContentType">
|
||||||
|
<div class="row" v-for="(item, index) in printTypeList" :key="index">
|
||||||
|
<div class="title">{{ item.label }}</div>
|
||||||
|
<div class="cont">
|
||||||
|
<el-checkbox-group v-model="item.values" @change="printTypeChange($event, index)">
|
||||||
|
<el-checkbox :label="item.label" :value="item.value" v-for="item in item.list"
|
||||||
|
:key="item.value"></el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="打印模式" prop="kitchenPrintMode">
|
||||||
|
<el-radio-group v-model="form.kitchenPrintMode">
|
||||||
|
<el-radio-button label="整单" value="all"></el-radio-button>
|
||||||
|
<el-radio-button label="单个" value="only"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-text type="info" style="margin-left: 14px;">仅针对厨房制作单的打印</el-text>
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="分类打印">
|
||||||
|
<div class="column">
|
||||||
|
<div style="display: flex;align-items: center;">
|
||||||
|
<el-radio-group v-model="form.classifyPrint">
|
||||||
|
<el-radio-button label="所有" value="0"></el-radio-button>
|
||||||
|
<el-radio-button label="部分分类" value="1" v-if="printTypeList[1].values.length > 0"></el-radio-button>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-text type="info" style="margin-left: 14px;">仅针对厨房制作单的打印</el-text>
|
||||||
|
</div>
|
||||||
|
<template v-if="form.classifyPrint == 1">
|
||||||
|
<el-checkbox-group v-model="form.categoryIds">
|
||||||
|
<el-checkbox v-for="item in PrinterTypeList" :value="item.id" :label="item.name"></el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="媒体音量">
|
||||||
|
<el-switch v-model="form.volumeSwitch" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="启用状态">
|
||||||
|
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="loading" @click="submitHandle">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import _ from 'lodash'
|
||||||
import UserAPI from "@/api/account/printer";
|
import UserAPI from "@/api/account/printer";
|
||||||
import type { IObject, IOperatData } from "@/components/CURD/types";
|
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||||
import usePage from "@/components/CURD/usePage";
|
import usePage from "@/components/CURD/usePage";
|
||||||
@@ -80,6 +202,166 @@ import addModalConfig from "./config/add";
|
|||||||
import contentConfig from "./config/content";
|
import contentConfig from "./config/content";
|
||||||
import editModalConfig from "./config/edit";
|
import editModalConfig from "./config/edit";
|
||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
|
import { options } from './config/config'
|
||||||
|
import printerApi, { type addRequest } from "@/api/account/printer";
|
||||||
|
|
||||||
|
const printTypeList = ref([
|
||||||
|
{
|
||||||
|
label: '前台',
|
||||||
|
values: [],
|
||||||
|
list: [
|
||||||
|
{ label: '客看单', value: 'GUEST_ORDER' },
|
||||||
|
{ label: '预结算单', value: 'PRE_ORDER' },
|
||||||
|
{ label: '结算单', value: 'ORDER' },
|
||||||
|
{ label: '退菜单', value: 'RETURN_ORDER' },
|
||||||
|
{ label: '退款单', value: 'REFUND_ORDER' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '后厨',
|
||||||
|
values: [],
|
||||||
|
list: [
|
||||||
|
{ label: '后厨-整单', value: 'ALL_KITCHEN' },
|
||||||
|
{ label: '后厨-分单', value: 'ONLY_KITCHEN' },
|
||||||
|
{ label: '后厨-退菜单', value: 'REFUND_KITCHEN' },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '其它',
|
||||||
|
values: [],
|
||||||
|
list: [
|
||||||
|
{ label: '交班单', value: 'HANDOVER' },
|
||||||
|
{ label: '排队取号', value: 'CALL' },
|
||||||
|
{ label: '储值单', value: 'RECHARGE' },
|
||||||
|
{ label: '入库单', value: 'STOCK' },
|
||||||
|
{ label: '盘点单', value: 'STOCK_CHECK' },
|
||||||
|
{ label: '商品报表', value: 'PRODUCT_REPORT' },
|
||||||
|
{ label: '经营日报', value: 'DAY_REPORT' },
|
||||||
|
{ label: '日结单', value: 'DAY_ORDER' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const visible = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const obj = {
|
||||||
|
id: '',
|
||||||
|
name: '', // 设备名称
|
||||||
|
connectionType: '云打印', // 连接方式 USB、云打印、局域网
|
||||||
|
printType: 'cash', // 打印类型 label标签 cash小票
|
||||||
|
brand: '', // 打印机品牌 飞鹅/云想印
|
||||||
|
address: '', // ip地址/MAC地址
|
||||||
|
port: '', // 端口
|
||||||
|
receiptSize: '58mm', // 小票尺寸 58mm 80mm
|
||||||
|
printNum: 1, // 打印数量
|
||||||
|
printContentType: '', // 打印内容
|
||||||
|
kitchenPrintMode: 'all', // 打印模式(厨房打印菜品) all整单 /only单个
|
||||||
|
classifyPrint: '0', // 分类打印 0-所有 1-部分分类
|
||||||
|
categoryIds: [], // 分类Id
|
||||||
|
status: 1, // 0 禁用 1启用
|
||||||
|
volumeSwitch: 1, // 媒体声音开关 0关1开
|
||||||
|
}
|
||||||
|
const form = ref({ ...obj })
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入设备名称',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
brand: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择打印机品牌',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
printNum: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择打印数量',
|
||||||
|
trigger: 'change'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// kitchenPrintMode: [
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// message: '请选择打印模式',
|
||||||
|
// trigger: 'change'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function dialogClosed() {
|
||||||
|
formRef.value.resetFields()
|
||||||
|
form.value = { ...obj }
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDivRef = ref(null)
|
||||||
|
async function dialogOpen() {
|
||||||
|
await nextTick()
|
||||||
|
if (formDivRef.value) {
|
||||||
|
// console.log('开始滚动到顶部')
|
||||||
|
formDivRef.value.scrollTop = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印类型切换
|
||||||
|
function printTypeChange(e, index, scope) {
|
||||||
|
if (index == 1 && printTypeList.value[index].values.length == 0) {
|
||||||
|
form.value.categoryList = []
|
||||||
|
}
|
||||||
|
|
||||||
|
let arr = []
|
||||||
|
printTypeList.value.forEach(item => {
|
||||||
|
arr.push(...item.values)
|
||||||
|
})
|
||||||
|
|
||||||
|
form.value.printContentType = arr.join(',')
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitHandle() {
|
||||||
|
console.log('submitHandle===', form.value);
|
||||||
|
formRef.value.validate(async valid => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true
|
||||||
|
const data = { ...form.value }
|
||||||
|
data.categoryIds = form.value.categoryIds.join(',')
|
||||||
|
if (form.value.id) {
|
||||||
|
await printerApi.edit(data)
|
||||||
|
} else {
|
||||||
|
await printerApi.add(data)
|
||||||
|
}
|
||||||
|
ElMessage.success(form.value.id ? '编辑成功' : '添加成功')
|
||||||
|
visible.value = false
|
||||||
|
|
||||||
|
handleQueryClick();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 300);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更改状态
|
||||||
|
async function statusChange(e, data) {
|
||||||
|
try {
|
||||||
|
await printerApi.edit({
|
||||||
|
id: data.id,
|
||||||
|
status: data.status
|
||||||
|
});
|
||||||
|
handleQueryClick();
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -98,11 +380,11 @@ const {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPrinterType();
|
getPrinterType();
|
||||||
});
|
});
|
||||||
let PrinterTypeList = ref([])
|
let PrinterTypeList = ref([]);
|
||||||
// 获取商品分类
|
// 获取商品分类
|
||||||
async function getPrinterType() {
|
async function getPrinterType() {
|
||||||
let res = await UserAPI.getPrinterType();
|
let res = await UserAPI.getPrinterType();
|
||||||
PrinterTypeList.value = res.records
|
PrinterTypeList.value = res.records;
|
||||||
}
|
}
|
||||||
function handdeleteevent(item) {
|
function handdeleteevent(item) {
|
||||||
ElMessageBox.confirm("确认删除?", "警告", {
|
ElMessageBox.confirm("确认删除?", "警告", {
|
||||||
@@ -114,28 +396,45 @@ function handdeleteevent(item) {
|
|||||||
ElMessage.success("删除成功");
|
ElMessage.success("删除成功");
|
||||||
handleQueryClick();
|
handleQueryClick();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
// addModalRef.value?.setModalVisible();
|
||||||
|
visible.value = true
|
||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
form.value = { ...row }
|
||||||
editModalRef.value?.setModalVisible();
|
visible.value = true
|
||||||
// 根据id获取数据进行填充
|
|
||||||
let data = await UserAPI.get(row.id);
|
|
||||||
data.printType = data.printType.split(',');
|
|
||||||
|
|
||||||
if (data.categoryIds) {
|
form.value.categoryIds = form.value.categoryIds.split(',')
|
||||||
data.categoryIdsArr = JSON.parse(data.categoryIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.classifyPrint = data.classifyPrint * 1;
|
const printContentTypes = row.printContentType.split(',')
|
||||||
|
printTypeList.value.forEach(val => {
|
||||||
|
val.values = _.map(
|
||||||
|
_.filter(val.list, item => printContentTypes.includes(item.value)),
|
||||||
|
'value'
|
||||||
|
);
|
||||||
|
})
|
||||||
|
|
||||||
editModalRef.value?.setFormData(data);
|
// editModalRef.value?.handleDisabled(false);
|
||||||
|
// editModalRef.value?.setModalVisible();
|
||||||
|
// // 根据id获取数据进行填充
|
||||||
|
// let data = await UserAPI.get(row.id);
|
||||||
|
// data.printType = data.printType.split(",");
|
||||||
|
|
||||||
|
// if (data.categoryIds) {
|
||||||
|
// data.categoryIdsArr = JSON.parse(data.categoryIds);
|
||||||
|
// } else {
|
||||||
|
// data.categoryIdsArr = [];
|
||||||
|
// }
|
||||||
|
// console.log(data.categoryIdsArr);
|
||||||
|
// console.log(data);
|
||||||
|
|
||||||
|
// data.classifyPrint = data.classifyPrint * 1;
|
||||||
|
|
||||||
|
// editModalRef.value?.setFormData(data);
|
||||||
}
|
}
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
function handleToolbarClick(name: string) {
|
function handleToolbarClick(name: string) {
|
||||||
|
|||||||
@@ -1,5 +1,112 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="gyq_container">
|
||||||
<h1>Index</h1>
|
<div class="item_wrap">
|
||||||
|
<div class="title">您好,欢迎登录</div>
|
||||||
|
<div class="item_list">
|
||||||
|
<div class="item" v-for="(item, index) in quickStore.quickMenus.splice(0, 6)" :key="item.id"
|
||||||
|
@click="menuClick(item.menuId)">
|
||||||
|
<img class="icon" :src="icons[index + 1]" alt="">
|
||||||
|
{{ returnMenuName(item.menuId) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, nextTick } from "vue";
|
||||||
|
import { useQuickStore, usePermissionStore, useUserStore } from "@/store";
|
||||||
|
|
||||||
|
import icon1 from "@/assets/index_quick1.png";
|
||||||
|
import icon2 from "@/assets/index_quick2.png";
|
||||||
|
import icon3 from "@/assets/index_quick3.png";
|
||||||
|
import icon4 from "@/assets/index_quick4.png";
|
||||||
|
import icon5 from "@/assets/index_quick5.png";
|
||||||
|
import icon6 from "@/assets/index_quick6.png";
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
1: icon1,
|
||||||
|
2: icon2,
|
||||||
|
3: icon3,
|
||||||
|
4: icon4,
|
||||||
|
5: icon5,
|
||||||
|
6: icon6,
|
||||||
|
};
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const quickStore = useQuickStore();
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
|
|
||||||
|
function returnMenuName(menuId) {
|
||||||
|
return permissionStore.returnMenuName(menuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function menuClick(menuId) {
|
||||||
|
permissionStore.menuJump(menuId);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await nextTick();
|
||||||
|
console.log('quickStore.quickMenus', quickStore.quickMenus);
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.gyq_container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: url('@/assets/index_bg.png') no-repeat center center / cover;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item_wrap {
|
||||||
|
padding-left: 300px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 40px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item_list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
grid-template-rows: repeat(2, 1fr);
|
||||||
|
grid-column-gap: 90px;
|
||||||
|
grid-row-gap: 90px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
width: 152px;
|
||||||
|
height: 83px;
|
||||||
|
border-radius: 20px;
|
||||||
|
background: linear-gradient(115deg, #9EC4FF 5.9%, #6668E8 111.62%);
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #fff;
|
||||||
|
padding-left: 30px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
left: -30px;
|
||||||
|
top: -20px;
|
||||||
|
width: 83px;
|
||||||
|
height: 78px;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="form.id ? '编辑耗材类型' : '添加耗材类型'" width="600px" v-model="visible" @close="onClose">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="120" label-position="right">
|
||||||
|
<el-form-item label="耗材类型名称" prop="name">
|
||||||
|
<el-input v-model="form.name" placeholder="请输入耗材类型名称" :maxlength="20"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="启用">
|
||||||
|
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleOk" :loading="confirmLoading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import Api from "@/api/product/cons-group";
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const form = ref({
|
||||||
|
name: '',
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入耗材类型名称',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
const confirmLoading = ref(false)
|
||||||
|
function handleOk() {
|
||||||
|
formRef.value.validate(async vaild => {
|
||||||
|
try {
|
||||||
|
if (vaild) {
|
||||||
|
confirmLoading.value = true
|
||||||
|
if (form.value.id) {
|
||||||
|
await Api.edit(form.value)
|
||||||
|
ElMessage.success('编辑成功')
|
||||||
|
} else {
|
||||||
|
await Api.add(form.value)
|
||||||
|
ElMessage.success('添加成功')
|
||||||
|
}
|
||||||
|
emit('success')
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
confirmLoading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClose() {
|
||||||
|
formRef.value.resetFields()
|
||||||
|
form.value.name = ''
|
||||||
|
form.value.status = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(obj) {
|
||||||
|
visible.value = true
|
||||||
|
if (obj && obj.id) {
|
||||||
|
form.value = _.cloneDeep(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
@@ -9,17 +9,9 @@
|
|||||||
@reset-click="handleResetClick"
|
@reset-click="handleResetClick"
|
||||||
/> -->
|
/> -->
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<page-content
|
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
||||||
ref="contentRef"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
:content-config="contentConfig"
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
||||||
@add-click="handleAddClick"
|
|
||||||
@edit-click="handleEditClick"
|
|
||||||
@export-click="handleExportClick"
|
|
||||||
@search-click="handleSearchClick"
|
|
||||||
@toolbar-click="handleToolbarClick"
|
|
||||||
@operat-click="handleOperatClick"
|
|
||||||
@filter-change="handleFilterChange"
|
|
||||||
>
|
|
||||||
<template #status="scope">
|
<template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -29,36 +21,22 @@
|
|||||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
</template>
|
</template>
|
||||||
<template #switch="scope">
|
<template #switch="scope">
|
||||||
<el-switch
|
<el-switch v-model="scope.row[scope.prop]" disabled :active-value="1" :inactive-value="0"></el-switch>
|
||||||
v-model="scope.row[scope.prop]"
|
|
||||||
disabled
|
|
||||||
:active-value="1"
|
|
||||||
:inactive-value="0"
|
|
||||||
></el-switch>
|
|
||||||
</template>
|
</template>
|
||||||
<template #mobile="scope">
|
<template #mobile="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
<copy-button
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
v-if="scope.row[scope.prop]"
|
|
||||||
:text="scope.row[scope.prop]"
|
|
||||||
style="margin-left: 2px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<page-modal
|
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick"></page-modal>
|
||||||
ref="addModalRef"
|
|
||||||
:modal-config="addModalConfig"
|
|
||||||
@submit-click="handleSubmitClick"
|
|
||||||
></page-modal>
|
|
||||||
|
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<page-modal
|
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick"></page-modal>
|
||||||
ref="editModalRef"
|
|
||||||
:modal-config="editModalConfig"
|
<!-- 添加分类 -->
|
||||||
@submit-click="handleSubmitClick"
|
<addClassificationModal ref="addClassificationModalRef" @success="handleResetClick" />
|
||||||
></page-modal>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -72,6 +50,9 @@ import editModalConfig from "./config/edit";
|
|||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
import { returnOptionsLabel } from "./config/config";
|
import { returnOptionsLabel } from "./config/config";
|
||||||
import { isSyncStatus } from "@/utils/index";
|
import { isSyncStatus } from "@/utils/index";
|
||||||
|
import addClassificationModal from "./components/addClassificationModal.vue";
|
||||||
|
|
||||||
|
const addClassificationModalRef = ref(null)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -98,16 +79,18 @@ if (isSyncStatus()) {
|
|||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
addClassificationModalRef.value.open()
|
||||||
|
// addModalRef.value?.setModalVisible();
|
||||||
// addModalConfig.formItems[2]!.attrs!.data =
|
// addModalConfig.formItems[2]!.attrs!.data =
|
||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
addClassificationModalRef.value.open(row)
|
||||||
editModalRef.value?.setModalVisible();
|
// editModalRef.value?.handleDisabled(false);
|
||||||
// 根据id获取数据进行填充
|
// editModalRef.value?.setModalVisible();
|
||||||
console.log(row);
|
// // 根据id获取数据进行填充
|
||||||
editModalRef.value?.setFormData({ ...row });
|
// console.log(row);
|
||||||
|
// editModalRef.value?.setFormData({ ...row });
|
||||||
}
|
}
|
||||||
1;
|
1;
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
<el-input v-model="form.conName" placeholder="请输入耗材名称"></el-input>
|
<el-input v-model="form.conName" placeholder="请输入耗材名称"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="耗材分类" prop="consGroupId">
|
<el-form-item label="耗材分类" prop="consGroupId">
|
||||||
<el-select v-model="form.consGroupId" placeholder="请选择耗材分类" style="width: 200px">
|
<div class="center" style="gap: 14px;">
|
||||||
<el-option v-for="option in consGroups" :key="option.conTypeId" :label="option.label"
|
<el-select v-model="form.consGroupId" placeholder="请选择耗材分类" style="width: 200px">
|
||||||
:value="option.id"></el-option>
|
<el-option v-for="option in consGroups" :key="option.conTypeId" :label="option.label"
|
||||||
</el-select>
|
:value="option.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" icon="Plus" @click="addClassificationModalRef.open()">添加耗材类型</el-button>
|
||||||
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="耗材价格" prop="price">
|
<el-form-item label="耗材价格" prop="price">
|
||||||
<div class="center">
|
<div class="center">
|
||||||
@@ -54,6 +57,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<addClassificationModal ref="addClassificationModalRef" @success="getConsGroups" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +66,9 @@ import { ref, reactive, computed } from "vue";
|
|||||||
import consApi from "@/api/product/cons";
|
import consApi from "@/api/product/cons";
|
||||||
import consGroupApi from "@/api/product/cons-group";
|
import consGroupApi from "@/api/product/cons-group";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import addClassificationModal from "../../classification/components/addClassificationModal.vue";
|
||||||
|
|
||||||
|
const addClassificationModalRef = ref(null)
|
||||||
|
|
||||||
const consGroups = ref([]);
|
const consGroups = ref([]);
|
||||||
const rules = {
|
const rules = {
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ const contentConfig: IContentConfig = {
|
|||||||
align: "center",
|
align: "center",
|
||||||
prop: "conName",
|
prop: "conName",
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: "单位",
|
// label: "单位",
|
||||||
align: "center",
|
// align: "center",
|
||||||
prop: "conUnit",
|
// prop: "conUnit",
|
||||||
templet: "custom",
|
// templet: "custom",
|
||||||
slotName: "conUnit",
|
// slotName: "conUnit",
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: "所属商品",
|
label: "所属商品",
|
||||||
align: "center",
|
align: "center",
|
||||||
@@ -112,14 +112,24 @@ const contentConfig: IContentConfig = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "库存数量",
|
label: "库存数量",
|
||||||
align: "center",
|
align: "left",
|
||||||
prop: "stockNumber",
|
prop: "stockNumber",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "stockNumber",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "预警值",
|
label: "预警值",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "conWarning",
|
prop: "conWarning",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
width: '120',
|
||||||
|
label: "是否检测耗材",
|
||||||
|
align: "center",
|
||||||
|
prop: "isStock",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "isStock",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "是否启用",
|
label: "是否启用",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|||||||
@@ -10,6 +10,25 @@
|
|||||||
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
||||||
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
||||||
|
<template #stockNumber="scope">
|
||||||
|
<div class="columne">
|
||||||
|
<div class="center">
|
||||||
|
<el-text>第一单位</el-text>
|
||||||
|
<el-text>{{ scope.row.stockNumber }}/{{ scope.row.conUnit }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="center" v-if="scope.row.conUnitTwo">
|
||||||
|
<el-text>第二单位</el-text>
|
||||||
|
<el-text>{{ scope.row.stockNumber / scope.row.conUnitTwoConvert }}/{{ scope.row.conUnitTwo }}</el-text>
|
||||||
|
</div>
|
||||||
|
<div class="center" v-else>
|
||||||
|
<el-text type="info">未设置第二单位</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #isStock="scope">
|
||||||
|
<el-switch v-model="scope.row.isStock" :active-value="1" :inactive-value="0"
|
||||||
|
@click="isStockChange($event, scope.row)"></el-switch>
|
||||||
|
</template>
|
||||||
<template #status="scope">
|
<template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -124,6 +143,12 @@ const {
|
|||||||
handleFilterChange,
|
handleFilterChange,
|
||||||
} = usePage();
|
} = usePage();
|
||||||
|
|
||||||
|
async function isStockChange(e, row) {
|
||||||
|
// console.log('isStockChange.e', e);
|
||||||
|
// console.log('isStockChange.row', row);
|
||||||
|
await consApi.edit(row)
|
||||||
|
}
|
||||||
|
|
||||||
function toGoods(id: number | string) {
|
function toGoods(id: number | string) {
|
||||||
router.push({ path: "/product/index", query: { id: id } });
|
router.push({ path: "/product/index", query: { id: id } });
|
||||||
}
|
}
|
||||||
@@ -280,6 +305,11 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.goodslang {
|
.goodslang {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|||||||
@@ -74,12 +74,19 @@ const accountList = reactive([
|
|||||||
{ username: "19107220837", type: 'danger', label: '快乐时光店铺' },
|
{ username: "19107220837", type: 'danger', label: '快乐时光店铺' },
|
||||||
// { username: "18199991111", type: 'success', label: '草莓加盟主店可直接管理' },
|
// { username: "18199991111", type: 'success', label: '草莓加盟主店可直接管理' },
|
||||||
{ username: "18821670757", type: 'success', label: '高歌的小店' },
|
{ username: "18821670757", type: 'success', label: '高歌的小店' },
|
||||||
|
{ username: "18821670757", staffUserName: '18821670758', type: 'primary', label: '高歌的小店的员工-张三' },
|
||||||
{ username: "191123456", type: 'primary', label: '酸橘子' },
|
{ username: "191123456", type: 'primary', label: '酸橘子' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// 快捷模拟登录
|
// 快捷模拟登录
|
||||||
function accountHandle(item) {
|
function accountHandle(item) {
|
||||||
state.loginForm.username = item.username;
|
state.loginForm.username = item.username;
|
||||||
|
if (item.staffUserName) {
|
||||||
|
state.loginForm.loginType = 1
|
||||||
|
state.loginForm.staffUserName = item.staffUserName
|
||||||
|
} else {
|
||||||
|
state.loginForm.loginType = 0
|
||||||
|
}
|
||||||
state.loginForm.code = 666666
|
state.loginForm.code = 666666
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
state.loginForm.password = `czg${d.getHours().toString().padStart(2, '0')}${d.getMinutes().toString().padStart(2, '0')}`;
|
state.loginForm.password = `czg${d.getHours().toString().padStart(2, '0')}${d.getMinutes().toString().padStart(2, '0')}`;
|
||||||
@@ -191,6 +198,12 @@ function handleLogin() {
|
|||||||
userStore
|
userStore
|
||||||
.login(user)
|
.login(user)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
|
|
||||||
|
console.log('login===', res);
|
||||||
|
|
||||||
|
localStorage.setItem('shopStaff', JSON.stringify(res.shopStaff))
|
||||||
|
|
||||||
|
|
||||||
const token = getToken();
|
const token = getToken();
|
||||||
console.log("token", token);
|
console.log("token", token);
|
||||||
$douyin_checkIn({
|
$douyin_checkIn({
|
||||||
|
|||||||
163
src/views/online-shop/components/addGoodsGroup.vue
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="forms.id ? '编辑分组' : '添加分组'" width="600px" v-model="visible" @close="onClose">
|
||||||
|
<el-form :model="forms" label-width="120px" ref="elFormref" :rules="rules">
|
||||||
|
<el-form-item label="分组名称" prop="name">
|
||||||
|
<el-input v-model="forms.name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择商品">
|
||||||
|
<el-button type="primary" icon="Plus" @click="addgoods">添加商品</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="" v-if="selectData.length">
|
||||||
|
<!-- 选责商品列表 -->
|
||||||
|
<selectGoodslist @deleteItememit="deleteItem($event)" :list="selectData"></selectGoodslist>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分组状态">
|
||||||
|
<el-radio-group v-model="forms.status">
|
||||||
|
<el-radio :value="1" label="启用" />
|
||||||
|
<el-radio :value="0" label="禁用" />
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="售卖时间管控">
|
||||||
|
<el-radio-group v-model="forms.useTime">
|
||||||
|
<el-radio :value="1" label="启用" />
|
||||||
|
<el-radio :value="0" label="禁用" />
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间选择" v-if="forms.useTime == 1">
|
||||||
|
<el-time-picker value-format="HH:mm:ss" v-model="forms.time" is-range range-separator="到"
|
||||||
|
start-placeholder="开始时间" end-placeholder="结束时间" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排列方式">
|
||||||
|
<el-radio-group v-model="forms.sortMode">
|
||||||
|
<el-radio value="0" label="默认" />
|
||||||
|
<el-radio value="1" label="价格由高到低" />
|
||||||
|
<el-radio value="2" label="价格由低到高" />
|
||||||
|
<el-radio value="3" label="销量由高到低" />
|
||||||
|
<el-radio value="4" label="销量由低到高" />
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分组排序">
|
||||||
|
<el-input-number v-model="forms.sort" controls-position="right" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="addConfirm" :loading="confirmLoading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
<!-- 新增添加商品 -->
|
||||||
|
<GoodsSelect ref="GoodsSelectRef" @success="e => selectData = e" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import selectGoodslist from '../goodsGroupconfig/selectGoodslist.vue';
|
||||||
|
import UserAPI from "@/api/onlineShop/goodsGroupconfig";
|
||||||
|
import GoodsSelect from '@/components/GoodsSelect/index.vue'
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const GoodsSelectRef = ref(null)
|
||||||
|
const elFormref = ref(null);
|
||||||
|
|
||||||
|
let selectData = ref([]);
|
||||||
|
const formsObj = {
|
||||||
|
name: "",
|
||||||
|
status: 1,
|
||||||
|
useTime: 0,
|
||||||
|
sortMode: "0",
|
||||||
|
sort: 1,
|
||||||
|
time: "",
|
||||||
|
saleEndTime: '',
|
||||||
|
saleStartTime: '',
|
||||||
|
productIds: '',
|
||||||
|
productList: ''
|
||||||
|
}
|
||||||
|
let forms = ref(_.cloneDeep(formsObj));
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
name: [{ required: true, message: "请输入分组名称", trigger: "blur" }],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
function onClose() {
|
||||||
|
forms.value = _.cloneDeep(formsObj)
|
||||||
|
elFormref.value.resetFields()
|
||||||
|
selectData.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加商品
|
||||||
|
async function addgoods() {
|
||||||
|
GoodsSelectRef.value.show(selectData.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除商品
|
||||||
|
function deleteItem(data) {
|
||||||
|
selectData.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
const confirmLoading = ref(false)
|
||||||
|
// 添加编辑商品分组
|
||||||
|
function addConfirm() {
|
||||||
|
elFormref.value.validate(async (valid, fields) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
let obj = {
|
||||||
|
...forms.value,
|
||||||
|
productList: selectData.value,
|
||||||
|
};
|
||||||
|
// 商品选择的合集
|
||||||
|
if (selectData.value.length) {
|
||||||
|
let arr = [];
|
||||||
|
selectData.value.forEach((item, index) => {
|
||||||
|
arr.push(item.id);
|
||||||
|
});
|
||||||
|
obj.productIds = arr;
|
||||||
|
}
|
||||||
|
console.log(obj, "商品分组的参数");
|
||||||
|
if (obj.time && obj.time.length) {
|
||||||
|
obj.saleStartTime = obj.time[0];
|
||||||
|
obj.saleEndTime = obj.time[1];
|
||||||
|
}
|
||||||
|
if (forms.value.id) {
|
||||||
|
if (obj.useTime == 0) {
|
||||||
|
obj.saleStartTime = null;
|
||||||
|
obj.saleEndTime = null;
|
||||||
|
}
|
||||||
|
let res = await UserAPI.update(obj);
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage.success("编辑成功");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let res = await UserAPI.addunit(obj);
|
||||||
|
if (res.code == 200) {
|
||||||
|
ElMessage.success("添加成功");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visible.value = false
|
||||||
|
emit('success')
|
||||||
|
} else {
|
||||||
|
console.log("error submit!", fields);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(obj) {
|
||||||
|
visible.value = true
|
||||||
|
if (obj && obj.id) {
|
||||||
|
forms.value = _.cloneDeep(obj)
|
||||||
|
selectData.value = obj.productList || []
|
||||||
|
forms.value.time = [obj.saleStartTime, obj.saleEndTime]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -5,17 +5,9 @@
|
|||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<page-content
|
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
||||||
ref="contentRef"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
:content-config="contentConfig"
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
||||||
@add-click="handleAddClick"
|
|
||||||
@edit-click="handleEditClick"
|
|
||||||
@export-click="handleExportClick"
|
|
||||||
@search-click="handleSearchClick"
|
|
||||||
@toolbar-click="handleToolbarClick"
|
|
||||||
@operat-click="handleOperatClick"
|
|
||||||
@filter-change="handleFilterChange"
|
|
||||||
>
|
|
||||||
<template #status="scope">
|
<template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -29,11 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #mobile="scope">
|
<template #mobile="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
<copy-button
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
v-if="scope.row[scope.prop]"
|
|
||||||
:text="scope.row[scope.prop]"
|
|
||||||
style="margin-left: 2px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
|
||||||
@@ -62,11 +50,7 @@
|
|||||||
</page-modal> -->
|
</page-modal> -->
|
||||||
|
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<page-modal
|
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
||||||
ref="editModalRef"
|
|
||||||
:modal-config="editModalConfig"
|
|
||||||
@submit-click="handleSubmitClick"
|
|
||||||
>
|
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
||||||
</template>
|
</template>
|
||||||
@@ -79,33 +63,20 @@
|
|||||||
添加商品
|
添加商品
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- 选责商品列表 -->
|
<!-- 选责商品列表 -->
|
||||||
<selectGoodslist
|
<selectGoodslist @deleteItememit="deleteItem($event)" :list="selectData"></selectGoodslist>
|
||||||
@deleteItememit="deleteItem($event)"
|
|
||||||
:list="selectData"
|
|
||||||
></selectGoodslist>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #addmanagementtime="scope">
|
<template #addmanagementtime="scope">
|
||||||
<template v-if="scope.formData.useTime == 1">
|
<template v-if="scope.formData.useTime == 1">
|
||||||
{{ scope.formData }}
|
{{ scope.formData }}
|
||||||
<el-time-picker
|
<el-time-picker value-format="HH:mm:ss" v-model="scope.formData.saleTime" is-range range-separator="到"
|
||||||
value-format="HH:mm:ss"
|
start-placeholder="开始时间" end-placeholder="结束时间" />
|
||||||
v-model="scope.formData.saleTime"
|
|
||||||
is-range
|
|
||||||
range-separator="到"
|
|
||||||
start-placeholder="开始时间"
|
|
||||||
end-placeholder="结束时间"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<page-content
|
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
|
||||||
ref="contentRef"
|
|
||||||
:content-config="contentConfig2"
|
|
||||||
@operat-click="handleOperatClick"
|
|
||||||
>
|
|
||||||
<template #status="scope">
|
<template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -113,32 +84,17 @@
|
|||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 添加/编辑分组 -->
|
||||||
|
<addGoodsGroup ref="addGoodsGroupRef" @success="handleQueryClick" />
|
||||||
|
|
||||||
<!-- 新增添加商品 -->
|
<!-- 新增添加商品 -->
|
||||||
<myDialog
|
<myDialog title="选择商品" width="50%" ref="myDialogRef" @Confirm="subitgood" @close="resetSelectData">
|
||||||
title="选择商品"
|
<page-search ref="searchRefs" :search-config="searchConfig2" @query-click="searchs"
|
||||||
width="50%"
|
@reset-click="handleResetClick" />
|
||||||
ref="myDialogRef"
|
<page-content ref="contentRefs" v-if="switchref" :content-config="contentConfig2" @add-click="handleAddClick"
|
||||||
@Confirm="subitgood"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
@close="resetSelectData"
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
||||||
>
|
|
||||||
<page-search
|
|
||||||
ref="searchRefs"
|
|
||||||
:search-config="searchConfig2"
|
|
||||||
@query-click="searchs"
|
|
||||||
@reset-click="handleResetClick"
|
|
||||||
/>
|
|
||||||
<page-content
|
|
||||||
ref="contentRefs"
|
|
||||||
v-if="switchref"
|
|
||||||
:content-config="contentConfig2"
|
|
||||||
@add-click="handleAddClick"
|
|
||||||
@edit-click="handleEditClick"
|
|
||||||
@export-click="handleExportClick"
|
|
||||||
@search-click="handleSearchClick"
|
|
||||||
@toolbar-click="handleToolbarClick"
|
|
||||||
@operat-click="handleOperatClick"
|
|
||||||
@filter-change="handleFilterChange"
|
|
||||||
>
|
|
||||||
<template #status="scope">
|
<template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -152,21 +108,17 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #mobile="scope">
|
<template #mobile="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
<copy-button
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
v-if="scope.row[scope.prop]"
|
|
||||||
:text="scope.row[scope.prop]"
|
|
||||||
style="margin-left: 2px"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
|
||||||
<!-- <el-table :data="selectData" border style="width: 100%">
|
<el-table :data="selectData" border style="width: 100%">
|
||||||
<el-table-column prop="date" align="center" label="Date" />
|
<el-table-column prop="date" align="center" label="Date" />
|
||||||
<el-table-column prop="address" align="center" label="Address" />
|
<el-table-column prop="address" align="center" label="Address" />
|
||||||
</el-table> -->
|
</el-table>
|
||||||
</myDialog>
|
</myDialog>
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<myDialog :title="title" width="30%" ref="myDialogRefAdd" @Confirm="addConfirm()">
|
<!-- <myDialog :title="title" width="50%" ref="myDialogRefAdd" @Confirm="addConfirm()">
|
||||||
<el-form :model="forms" label-width="120px" ref="elFormref" :rules="rules">
|
<el-form :model="forms" label-width="120px" ref="elFormref" :rules="rules">
|
||||||
<el-form-item label="分组名称" prop="name">
|
<el-form-item label="分组名称" prop="name">
|
||||||
<el-input v-model="forms.name" />
|
<el-input v-model="forms.name" />
|
||||||
@@ -175,11 +127,7 @@
|
|||||||
<el-button type="primary" icon="Plus" @click="addgoods">添加商品</el-button>
|
<el-button type="primary" icon="Plus" @click="addgoods">添加商品</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="" v-if="selectData.length">
|
<el-form-item label="" v-if="selectData.length">
|
||||||
<!-- 选责商品列表 -->
|
<selectGoodslist @deleteItememit="deleteItem($event)" :list="selectData"></selectGoodslist>
|
||||||
<selectGoodslist
|
|
||||||
@deleteItememit="deleteItem($event)"
|
|
||||||
:list="selectData"
|
|
||||||
></selectGoodslist>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="分组状态">
|
<el-form-item label="分组状态">
|
||||||
<el-radio-group v-model="forms.status">
|
<el-radio-group v-model="forms.status">
|
||||||
@@ -194,14 +142,8 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="时间选择" v-if="forms.useTime == 1">
|
<el-form-item label="时间选择" v-if="forms.useTime == 1">
|
||||||
<el-time-picker
|
<el-time-picker value-format="HH:mm:ss" v-model="forms.time" is-range range-separator="到"
|
||||||
value-format="HH:mm:ss"
|
start-placeholder="开始时间" end-placeholder="结束时间" />
|
||||||
v-model="forms.time"
|
|
||||||
is-range
|
|
||||||
range-separator="到"
|
|
||||||
start-placeholder="开始时间"
|
|
||||||
end-placeholder="结束时间"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="排列方式">
|
<el-form-item label="排列方式">
|
||||||
<el-radio-group v-model="forms.sortMode">
|
<el-radio-group v-model="forms.sortMode">
|
||||||
@@ -216,7 +158,7 @@
|
|||||||
<el-input-number v-model="forms.sort" controls-position="right" />
|
<el-input-number v-model="forms.sort" controls-position="right" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</myDialog>
|
</myDialog> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -235,6 +177,7 @@ import searchConfig2 from "./goodsGroupconfig/search2";
|
|||||||
import myDialog from "@/components/mycomponents/myDialog.vue";
|
import myDialog from "@/components/mycomponents/myDialog.vue";
|
||||||
import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue";
|
import selectGoodslist from "./goodsGroupconfig/selectGoodslist.vue";
|
||||||
import { isSyncStatus } from "@/utils/index";
|
import { isSyncStatus } from "@/utils/index";
|
||||||
|
import addGoodsGroup from "./components/addGoodsGroup.vue";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -268,10 +211,13 @@ if (isSyncStatus()) {
|
|||||||
|
|
||||||
let switchref = ref(false);
|
let switchref = ref(false);
|
||||||
|
|
||||||
|
const addGoodsGroupRef = ref(null)
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
addGoodsGroupRef.value.open()
|
||||||
selectData.value = [];
|
// addModalRef.value?.setModalVisible();
|
||||||
|
// selectData.value = [];
|
||||||
// 加载上级规格下拉数据源
|
// 加载上级规格下拉数据源
|
||||||
// addModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
// addModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
@@ -377,22 +323,22 @@ function deleteItem(data: any) {
|
|||||||
|
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
// editModalRef.value?.handleDisabled(false);
|
||||||
title.value = "编辑分组";
|
// title.value = "编辑分组";
|
||||||
// 加载部门下拉数据源
|
// 加载部门下拉数据源
|
||||||
// editModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
// editModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
||||||
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
// 根据id获取数据进行填充
|
// 根据id获取数据进行填充
|
||||||
const data = await UserAPI.getunitinfo(row.id);
|
// const data = await UserAPI.getunitinfo(row.id);
|
||||||
let obj = { ...data };
|
// let obj = { ...data };
|
||||||
selectData.value = data.productList;
|
// selectData.value = data.productList;
|
||||||
obj.time = [obj.saleStartTime, obj.saleEndTime];
|
// obj.time = [obj.saleStartTime, obj.saleEndTime];
|
||||||
for (let key in obj) {
|
// for (let key in obj) {
|
||||||
forms[key] = obj[key];
|
// forms[key] = obj[key];
|
||||||
}
|
// }
|
||||||
myDialogRefAdd.value.open();
|
addGoodsGroupRef.value.open(row)
|
||||||
// editModalRef.value?.setFormData(obj);
|
// editModalRef.value?.setFormData(obj);
|
||||||
// editModalRef.value?.setModalVisible();
|
// editModalRef.value?.setModalVisible();
|
||||||
}
|
}
|
||||||
@@ -400,19 +346,20 @@ async function handleEditClick(row: IObject) {
|
|||||||
function handleToolbarClick(name: string) {
|
function handleToolbarClick(name: string) {
|
||||||
console.log(name);
|
console.log(name);
|
||||||
if (name === "custom1") {
|
if (name === "custom1") {
|
||||||
forms = reactive({
|
// forms = reactive({
|
||||||
name: "",
|
// name: "",
|
||||||
status: 1,
|
// status: 1,
|
||||||
useTime: 0,
|
// useTime: 0,
|
||||||
sortMode: "0",
|
// sortMode: "0",
|
||||||
sort: 1,
|
// sort: 1,
|
||||||
time: "",
|
// time: "",
|
||||||
});
|
// });
|
||||||
selectData.value = [];
|
// selectData.value = [];
|
||||||
title.value = "新增分组";
|
// title.value = "新增分组";
|
||||||
|
|
||||||
// 新增
|
// // 新增
|
||||||
myDialogRefAdd.value.open();
|
// myDialogRefAdd.value.open();
|
||||||
|
addGoodsGroupRef.value.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 其他操作列
|
// 其他操作列
|
||||||
|
|||||||
@@ -9,13 +9,20 @@
|
|||||||
<div class="form">
|
<div class="form">
|
||||||
<div class="preview_wrap">
|
<div class="preview_wrap">
|
||||||
<div class="phone_wrap">
|
<div class="phone_wrap">
|
||||||
|
<!-- 首页背景 -->
|
||||||
<div class="index_bg" v-if="tableActive == 'index_bg'">
|
<div class="index_bg" v-if="tableActive == 'index_bg'">
|
||||||
<img class="bg" v-if="!isJsonArrayString(selectItem.value)" :src="selectItem.value" alt="">
|
<!-- 多图轮播 -->
|
||||||
<el-carousel height="500px" v-else>
|
<el-carousel height="500px"
|
||||||
<el-carousel-item v-for="item in JSON.parse(selectItem.value)">
|
v-if="isJsonArrayString(selectItem.value) && JSON.parse(selectItem.value).length > 0">
|
||||||
|
<el-carousel-item v-for="(item, idx) in JSON.parse(selectItem.value)" :key="idx">
|
||||||
<img class="bg" :src="item" />
|
<img class="bg" :src="item" />
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
|
<!-- 单图渲染 -->
|
||||||
|
<img class="bg" v-else-if="selectItem.value" :src="selectItem.value" alt="" />
|
||||||
|
<!-- 空状态提示 -->
|
||||||
|
<div class="empty-tip" v-else>暂无图片,请上传</div>
|
||||||
|
|
||||||
<div class="menu_wrap">
|
<div class="menu_wrap">
|
||||||
<div class="menu_wrap_div">
|
<div class="menu_wrap_div">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
@@ -46,8 +53,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 个人中心背景 -->
|
||||||
<div class="my_bg" v-if="tableActive == 'my_bg'">
|
<div class="my_bg" v-if="tableActive == 'my_bg'">
|
||||||
<img class="bg" :src="selectItem.value" />
|
<img class="bg" :src="selectItem.value" v-if="selectItem.value" />
|
||||||
|
<div class="empty-tip my-empty-tip" v-else>暂无图片,请上传</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item" style="display: flex">
|
<div class="item" style="display: flex">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
@@ -108,10 +118,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 会员背景 -->
|
||||||
<div class="member_bg" v-if="tableActive == 'member_bg'">
|
<div class="member_bg" v-if="tableActive == 'member_bg'">
|
||||||
<div class="card_wrap">
|
<div class="card_wrap">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img class="bg" :src="selectItem.value" />
|
<img class="bg" :src="selectItem.value" v-if="selectItem.value" />
|
||||||
|
<div class="empty-tip member-empty-tip" v-else>暂无图片,请上传</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="ewm">
|
<div class="ewm">
|
||||||
<i class="icon el-icon-menu"></i>
|
<i class="icon el-icon-menu"></i>
|
||||||
@@ -155,18 +168,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 商品列表背景 -->
|
||||||
<div class="shopinfo_bg" v-if="tableActive == 'shopinfo_bg'">
|
<div class="shopinfo_bg" v-if="tableActive == 'shopinfo_bg'">
|
||||||
<img class="bg" :src="selectItem.value" v-if="!isJsonArrayString(selectItem.value)" />
|
<!-- 多图轮播 -->
|
||||||
<el-carousel height="120px" v-else>
|
<el-carousel height="120px"
|
||||||
<el-carousel-item v-for="item in JSON.parse(selectItem.value)">
|
v-if="isJsonArrayString(selectItem.value) && JSON.parse(selectItem.value).length > 0">
|
||||||
|
<el-carousel-item v-for="(item, idx) in JSON.parse(selectItem.value)" :key="idx">
|
||||||
<img class="bg" :src="item" />
|
<img class="bg" :src="item" />
|
||||||
</el-carousel-item>
|
</el-carousel-item>
|
||||||
</el-carousel>
|
</el-carousel>
|
||||||
|
<!-- 单图渲染 -->
|
||||||
|
<img class="bg" v-else-if="selectItem.value" :src="selectItem.value" alt="" />
|
||||||
|
<!-- 空状态提示 -->
|
||||||
|
<div class="empty-tip shopinfo-empty-tip" v-else>暂无图片,请上传</div>
|
||||||
|
|
||||||
<div class="shop_name">{{ shopName }}</div>
|
<div class="shop_name">{{ shopName }}</div>
|
||||||
<img class="content" src="@/assets/images/shop_editor_bg.png" alt="" />
|
<img class="content" src="@/assets/images/shop_editor_bg.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 小票logo -->
|
||||||
<div class="ticket_wrap" v-if="tableActive == 'ticket_logo'">
|
<div class="ticket_wrap" v-if="tableActive == 'ticket_logo'">
|
||||||
<img class="logo" :src="selectItem.value" />
|
<img class="logo" :src="selectItem.value" v-if="selectItem.value" />
|
||||||
|
<div class="empty-tip ticket-empty-tip" v-else>暂无图片,请上传</div>
|
||||||
<img class="ewm" src="@/assets/images/1024.png" />
|
<img class="ewm" src="@/assets/images/1024.png" />
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="num">123</span>
|
<span class="num">123</span>
|
||||||
@@ -185,42 +209,48 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="editor_wrap">
|
<div class="editor_wrap">
|
||||||
<div class="header" style="padding-bottom: 20px">
|
<div class="header" style="padding-bottom: 20px">
|
||||||
<div class="t1">
|
<div class="t1">{{ selectItem.name }}</div>
|
||||||
{{ selectItem.name }}
|
|
||||||
</div>
|
|
||||||
<div class="t2">注:点击图片更换</div>
|
<div class="t2">注:点击图片更换</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form_item">
|
<div class="form_item">
|
||||||
<div class="upload_wrap" style="display: flex;flex-direction: column;gap: 28px;"
|
<!-- 多图上传 -->
|
||||||
|
<div class="upload_wrap" style="display: flex; flex-direction: column; gap: 28px"
|
||||||
v-if="selectItem.autoKey == 'index_bg' || selectItem.autoKey == 'shopinfo_bg'">
|
v-if="selectItem.autoKey == 'index_bg' || selectItem.autoKey == 'shopinfo_bg'">
|
||||||
<MultiImageUpload v-model="imgList" @uploadStart="uploading = true" @uploadAllSuccess="MultiOnSuccess" />
|
<MultiImageUpload v-model="imgList" @uploadStart="uploading = true" @uploadAllSuccess="MultiOnSuccess" />
|
||||||
<div>
|
|
||||||
<el-button type="primary" size="large" @click="doSubmit" :loading="uploading"
|
|
||||||
loading-text="图片上传中...">确认修改</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<!-- 单图上传 -->
|
||||||
|
<div v-else style="display: flex;">
|
||||||
<SingleImageUpload v-model="selectItem.value" @onSuccess="onSuccess">
|
<SingleImageUpload v-model="selectItem.value" @onSuccess="onSuccess">
|
||||||
<img v-if="selectItem.value" :src="selectItem.value" class="avatar" />
|
<img v-if="selectItem.value" :src="selectItem.value" class="avatar" />
|
||||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||||
</SingleImageUpload>
|
</SingleImageUpload>
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-upload
|
<div class="model_wapra">
|
||||||
:headers="headers"
|
<!-- 个人中心模板图 -->
|
||||||
class="avatar-uploader"
|
<template v-if="selectItem.autoKey == 'my_bg'">
|
||||||
:action="qiNiuUploadApi"
|
<div class="title">个人中心模板图</div>
|
||||||
:show-file-list="false"
|
<div class="user-bg-list" v-if="userBgList.length > 0">
|
||||||
:on-success="handleSuccess"
|
<img v-for="(url, index) in userBgList" :key="index" :src="url" @click="selectUserBg(url)"
|
||||||
style="width: 200px; height: 200px"
|
class="user-bg-item" />
|
||||||
>
|
</div>
|
||||||
<img v-if="selectItem.value" :src="selectItem.value" class="avatar" />
|
</template>
|
||||||
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
<!-- VIP背景模板图 -->
|
||||||
</el-upload> -->
|
<template v-else-if="selectItem.autoKey == 'member_bg'">
|
||||||
<!-- <div class="title" style="padding-left: 20px;">跳转路径</div>
|
<div class="title">会员卡背景模板图</div>
|
||||||
<el-input style="width: 300px;margin-left: 20px;" />
|
<div class="user-bg-list" v-if="vipBgList.length > 0">
|
||||||
<el-button type="primary" style="margin-left: 20px;">修改</el-button> -->
|
<img v-for="(url, index) in vipBgList" :key="index" :src="url" @click="selectVipBg(url)"
|
||||||
|
class="user-bg-item" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" size="large" @click="doSubmit" :loading="uploading" loading-text="图片上传中...">
|
||||||
|
确认修改
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -230,7 +260,13 @@
|
|||||||
<script>
|
<script>
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import shopExtendApi from "@/api/account/shopExtend";
|
import shopExtendApi from "@/api/account/shopExtend";
|
||||||
|
// 确保SvgIcon组件已正确引入
|
||||||
|
import SvgIcon from "@/components/SvgIcon/index.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
SvgIcon,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableActive: "index_bg",
|
tableActive: "index_bg",
|
||||||
@@ -238,91 +274,151 @@ export default {
|
|||||||
selectItem: {},
|
selectItem: {},
|
||||||
imageUrl: "",
|
imageUrl: "",
|
||||||
imgList: [],
|
imgList: [],
|
||||||
shopName: '',
|
shopName: "",
|
||||||
uploading: false
|
uploading: false,
|
||||||
|
userBgList: [
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/5c8673150d8e449ba035e3f65866b4ed.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/c442af63d29443c687b24d2a3abbf02b.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/1da89980fa0f4c7abffbcdacc2c3a059.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/16296e40f2634d0da0cf1ff377b2b848.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/f442c0d005b94664ac4b37f7fa19731b.png',
|
||||||
|
],
|
||||||
|
vipBgList: [
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/c2add99b9b21464889bc14823b97c40e.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/c0e65f576a1a485da7fac34658b87c24.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/629b8c12b8904140bf84df3a57b3c021.png',
|
||||||
|
'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/2/cd06e01ad7e848359cdca718f5a06231.png'
|
||||||
|
]
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 刷新列表数据
|
// 选择会员背景模板图
|
||||||
|
selectVipBg(url) {
|
||||||
|
this.selectItem.value = url;
|
||||||
|
// this.doSubmit();
|
||||||
|
},
|
||||||
|
// 选择个人中心背景模板图
|
||||||
|
selectUserBg(url) {
|
||||||
|
this.selectItem.value = url;
|
||||||
|
// this.doSubmit();
|
||||||
|
},
|
||||||
|
// 提交修改
|
||||||
async doSubmit() {
|
async doSubmit() {
|
||||||
// console.log('this.selectItem.value', this.selectItem.value);
|
// 多图类型强制同步imgList到selectItem.value
|
||||||
// return
|
if (["index_bg", "shopinfo_bg"].includes(this.selectItem.autoKey)) {
|
||||||
|
this.selectItem.value =
|
||||||
|
this.imgList.length > 0 ? JSON.stringify(this.imgList) : "";
|
||||||
|
}
|
||||||
|
|
||||||
// this.selectItem.value = JSON.stringify(this.imgList)
|
let data = {
|
||||||
await shopExtendApi.edit({
|
|
||||||
...this.selectItem,
|
...this.selectItem,
|
||||||
autokey: this.selectItem.autoKey,
|
autokey: this.selectItem.autoKey,
|
||||||
});
|
};
|
||||||
ElMessage({
|
|
||||||
message: "编辑成功",
|
if (data.value === "") {
|
||||||
type: "success",
|
ElMessage({
|
||||||
});
|
message: "请上传图片",
|
||||||
this.getList();
|
type: "warning",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await shopExtendApi.edit(data);
|
||||||
|
ElMessage({
|
||||||
|
message: "编辑成功",
|
||||||
|
type: "success", // 修复提示类型错误
|
||||||
|
});
|
||||||
|
this.getList();
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage({
|
||||||
|
message: "编辑失败:" + (error.message || "未知错误"),
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 单图上传成功
|
// 单图上传成功
|
||||||
onSuccess(response) {
|
onSuccess(response) {
|
||||||
this.doSubmit();
|
this.doSubmit();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 多图上传成功
|
// 多图上传成功
|
||||||
async MultiOnSuccess(response) {
|
async MultiOnSuccess(response) {
|
||||||
console.log(response);
|
this.uploading = false;
|
||||||
// console.log(this.imgList);
|
// 确保imgList有值再序列化
|
||||||
// console.log(this.imgList);
|
this.selectItem.value =
|
||||||
// await nextTick()
|
this.imgList.length > 0 ? JSON.stringify(this.imgList) : "";
|
||||||
this.uploading = false
|
// 强制触发视图更新
|
||||||
this.selectItem.value = JSON.stringify(this.imgList)
|
this.$forceUpdate();
|
||||||
console.log('onSuccess.selectItem.value', this.selectItem.value);
|
ElMessage({
|
||||||
|
message: "图片上传成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断字符串是否为合法的 JSON 数组
|
* 判断字符串是否为合法的 JSON 数组
|
||||||
* @param {string} str - 待判断的字符串
|
* @param {string} str - 待判断的字符串
|
||||||
* @returns {boolean} true=是JSON数组字符串 / false=普通字符串/其他
|
* @returns {boolean} true=是JSON数组字符串 / false=普通字符串/其他
|
||||||
*/
|
*/
|
||||||
isJsonArrayString(str) {
|
isJsonArrayString(str) {
|
||||||
// 1. 非字符串直接返回 false
|
if (typeof str !== "string" || str.trim() === "") {
|
||||||
if (typeof str !== 'string') {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 空字符串返回 false(根据业务可调整)
|
|
||||||
if (str.trim() === '') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 3. 尝试解析 JSON
|
|
||||||
const parsed = JSON.parse(str);
|
const parsed = JSON.parse(str);
|
||||||
// 4. 校验解析结果是否为数组
|
|
||||||
return Array.isArray(parsed);
|
return Array.isArray(parsed);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// 解析失败(普通字符串/非法 JSON)→ 返回 false
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 切换类型
|
// 切换类型
|
||||||
selectItemChange(key) {
|
selectItemChange(key) {
|
||||||
this.tableActive = key;
|
this.tableActive = key;
|
||||||
const { autoKey, id, name, value } = this.tableData.find((item) => item.autoKey == key);
|
const targetItem = this.tableData.find((item) => item.autoKey === key) || {};
|
||||||
this.selectItem = { autoKey, id, name, value };
|
// 深拷贝避免引用问题
|
||||||
if (this.isJsonArrayString(value)) {
|
this.selectItem = { ...targetItem };
|
||||||
this.imgList = JSON.parse(value)
|
|
||||||
|
// 多图类型特殊处理
|
||||||
|
if (["index_bg", "shopinfo_bg"].includes(key)) {
|
||||||
|
if (this.isJsonArrayString(targetItem.value)) {
|
||||||
|
this.imgList = JSON.parse(targetItem.value);
|
||||||
|
} else {
|
||||||
|
// 非JSON数组时,若有单图值则转为数组,否则置空
|
||||||
|
this.imgList = targetItem.value ? [targetItem.value] : [];
|
||||||
|
}
|
||||||
|
// 同步更新selectItem.value为JSON数组
|
||||||
|
this.selectItem.value = JSON.stringify(this.imgList);
|
||||||
} else {
|
} else {
|
||||||
this.imgList = []
|
this.imgList = [];
|
||||||
|
// 单图类型保留原有值
|
||||||
|
this.selectItem.value = targetItem.value || "";
|
||||||
}
|
}
|
||||||
console.log(this.selectItem);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取装修数据
|
// 获取装修数据
|
||||||
async getList() {
|
async getList() {
|
||||||
try {
|
try {
|
||||||
let res = await shopExtendApi.get({});
|
const res = await shopExtendApi.get({});
|
||||||
this.tableData = res;
|
this.tableData = res || [];
|
||||||
this.tableActive = !this.tableActive ? res[0].autoKey : this.tableActive;
|
// 确保有数据时再切换
|
||||||
this.selectItemChange(this.tableActive);
|
if (this.tableData.length > 0) {
|
||||||
|
this.tableActive = this.tableActive || this.tableData[0].autoKey;
|
||||||
|
this.selectItemChange(this.tableActive);
|
||||||
|
}
|
||||||
|
// 补充店铺名称(根据实际接口返回调整)
|
||||||
|
this.shopName = "我的店铺";
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.error("获取装修数据失败:", error);
|
||||||
|
ElMessage({
|
||||||
|
message: "获取数据失败,请刷新重试",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -336,7 +432,7 @@ export default {
|
|||||||
gap: 30px;
|
gap: 30px;
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
width: 100px;
|
padding: 0 20px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border: 1px solid $color;
|
border: 1px solid $color;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -366,6 +462,64 @@ export default {
|
|||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
// 空状态通用样式
|
||||||
|
.empty-tip {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 首页空状态
|
||||||
|
.index_bg .empty-tip {
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品列表空状态
|
||||||
|
.shopinfo_bg .empty-tip {
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 个人中心空状态
|
||||||
|
.my-empty-tip {
|
||||||
|
height: 180px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会员背景空状态
|
||||||
|
.member-empty-tip {
|
||||||
|
height: 144px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 小票logo空状态
|
||||||
|
.ticket-empty-tip {
|
||||||
|
height: 80px;
|
||||||
|
width: 80px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.index_bg {
|
.index_bg {
|
||||||
padding-bottom: 50px;
|
padding-bottom: 50px;
|
||||||
|
|
||||||
@@ -653,35 +807,36 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.info_wrap {
|
.info_wrap {
|
||||||
padding: 20px 10px;
|
padding: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: #efefef;
|
background-color: #f5f5f5;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
color: #555;
|
font-size: 20px;
|
||||||
font-size: 24px;
|
color: #999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.t1 {
|
.t1 {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.t2 {
|
.t2 {
|
||||||
font-size: 10px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -696,52 +851,55 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.shop_name {
|
.shop_name {
|
||||||
padding: 10px 10px 0 10px;
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ticket_wrap {
|
.ticket_wrap {
|
||||||
padding: 15px;
|
padding: 10px;
|
||||||
position: relative;
|
|
||||||
|
.logo {
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
object-fit: contain;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.ewm {
|
.ewm {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
position: absolute;
|
object-fit: contain;
|
||||||
top: 10px;
|
margin-bottom: 10px;
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: 90px;
|
|
||||||
height: 30px;
|
|
||||||
object-fit: cover;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
margin-top: 5px;
|
font-size: 12px;
|
||||||
display: flex;
|
color: #666;
|
||||||
align-items: center;
|
margin-bottom: 4px;
|
||||||
|
|
||||||
|
.num {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.sku {
|
.sku {
|
||||||
font-size: 12px;
|
color: #999;
|
||||||
color: #666;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.b {
|
.b {
|
||||||
font-weight: bold;
|
font-weight: 500;
|
||||||
}
|
color: #333;
|
||||||
|
|
||||||
.num {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -749,28 +907,63 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor_wrap {
|
.editor_wrap {
|
||||||
padding-left: 20px;
|
flex: 1;
|
||||||
|
padding-left: 40px;
|
||||||
.header {
|
|
||||||
.t2 {
|
|
||||||
color: #999;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.form_item {
|
.form_item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
|
gap: 30px;
|
||||||
|
|
||||||
.avatar {
|
.model_wapra {
|
||||||
display: block;
|
.title {
|
||||||
width: 200px;
|
font-size: 16px;
|
||||||
height: 200px;
|
color: #333;
|
||||||
object-fit: cover;
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.user-bg-list {
|
||||||
flex-shrink: 0;
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.user-bg-item {
|
||||||
|
width: 120px;
|
||||||
|
height: 80px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #40a9ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.avatar-uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c8c8c;
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
line-height: 178px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
98
src/views/order/index/components/GoodsListCollapse.vue
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<div class="goods_info">
|
||||||
|
<div v-for="(item, index) in showList" :key="item.id || index" class="row">
|
||||||
|
<el-image :src="item.productImg" class="cover" lazy />
|
||||||
|
<div class="info">
|
||||||
|
<div class="name">
|
||||||
|
<span :class="[item.isVip == 1 ? 'colorStyle' : '']">
|
||||||
|
{{ item.productName }}
|
||||||
|
</span>
|
||||||
|
<span v-if="item.refundNum" class="refund">(退 - {{ item.refundNum }})</span>
|
||||||
|
</div>
|
||||||
|
<div class="sku">{{ item.skuName }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="needShowMore" class="show-more" @click="showAll = !showAll">
|
||||||
|
{{ showAll ? "收起" : "查看全部" }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
|
// 接收商品列表
|
||||||
|
const props = defineProps<{
|
||||||
|
goods: any[];
|
||||||
|
}>();
|
||||||
|
|
||||||
|
// 组件内部独立状态,自己控制,不影响外部
|
||||||
|
const showAll = ref(false);
|
||||||
|
|
||||||
|
// 计算需要展示的列表
|
||||||
|
const showList = computed(() => {
|
||||||
|
const list = props.goods || [];
|
||||||
|
return showAll.value ? list : list.slice(0, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 是否需要显示查看更多
|
||||||
|
const needShowMore = computed(() => {
|
||||||
|
return (props.goods || []).length > 2;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.goods_info {
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 2px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sku {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.show-more {
|
||||||
|
color: #1989fa;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorStyle {
|
||||||
|
color: #ffc315;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refund {
|
||||||
|
color: #ff9731;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -93,13 +93,8 @@
|
|||||||
<div>
|
<div>
|
||||||
实收金额:
|
实收金额:
|
||||||
<span style="color: red">¥{{ detail.payAmount }}</span>
|
<span style="color: red">¥{{ detail.payAmount }}</span>
|
||||||
<el-button
|
<el-button v-if="detail.status != 'unpaid' && detail.refundAmount < detail.payAmount" size="small"
|
||||||
v-if="detail.status != 'unpaid' && detail.refundAmount < detail.payAmount"
|
type="danger" class="u-m-l-10" @click="tuikuan()">
|
||||||
size="small"
|
|
||||||
type="danger"
|
|
||||||
class="u-m-l-10"
|
|
||||||
@click="tuikuan()"
|
|
||||||
>
|
|
||||||
<span>退款</span>
|
<span>退款</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -116,7 +111,11 @@
|
|||||||
退款详情>
|
退款详情>
|
||||||
</span> -->
|
</span> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="color-red">退款方式:{{ detail.refundType }}</div>
|
<div class="color-red">
|
||||||
|
<span v-if="detail.refundType">
|
||||||
|
退款方式:{{ detail.refundType === "cash" ? "现金退款" : "原路退回" }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -126,35 +125,22 @@
|
|||||||
<div style="margin-bottom: 16px; font-size: 16px">商品信息</div>
|
<div style="margin-bottom: 16px; font-size: 16px">商品信息</div>
|
||||||
<template v-for="(item, index) in detail.detailMap" :key="index">
|
<template v-for="(item, index) in detail.detailMap" :key="index">
|
||||||
<h4>第{{ index }}次下单</h4>
|
<h4>第{{ index }}次下单</h4>
|
||||||
<el-table
|
<el-table :data="item" :ref="'refTable' + index" @select-all="tableSelectAll($event, index)">
|
||||||
:data="item"
|
|
||||||
:ref="'refTable' + index"
|
|
||||||
@select-all="tableSelectAll($event, index)"
|
|
||||||
>
|
|
||||||
<!-- <el-table-column type="selection" width="55" /> -->
|
<!-- <el-table-column type="selection" width="55" /> -->
|
||||||
<el-table-column label="数量" type="selection">
|
<el-table-column label="数量" type="selection">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div v-if="detail.status == 'unpaid'">
|
<div v-if="detail.status == 'unpaid'">
|
||||||
<el-checkbox
|
<el-checkbox v-if="scope.row.num - scope.row.returnNum > 0" v-model="scope.row.checked" />
|
||||||
v-if="scope.row.num - scope.row.returnNum > 0"
|
|
||||||
v-model="scope.row.checked"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<el-checkbox
|
<el-checkbox v-if="scope.row.num - scope.row.refundNum > 0" v-model="scope.row.checked" />
|
||||||
v-if="scope.row.num - scope.row.refundNum > 0"
|
|
||||||
v-model="scope.row.checked"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="商品" width="150">
|
<el-table-column label="商品" width="150">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="shop_info">
|
<div class="shop_info">
|
||||||
<el-image
|
<el-image :src="scope.row.productImg" style="width: 40px; height: 40px"></el-image>
|
||||||
:src="scope.row.productImg"
|
|
||||||
style="width: 40px; height: 40px"
|
|
||||||
></el-image>
|
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span :class="[scope.row.isVip == 1 ? 'colorStyle' : '']">
|
<span :class="[scope.row.isVip == 1 ? 'colorStyle' : '']">
|
||||||
{{ scope.row.productName }}
|
{{ scope.row.productName }}
|
||||||
@@ -187,32 +173,17 @@
|
|||||||
<el-table-column label="实付">
|
<el-table-column label="实付">
|
||||||
<template v-slot="scope">¥{{ scope.row.payAmount }}</template>
|
<template v-slot="scope">¥{{ scope.row.payAmount }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column v-if="detail.status == 'unpaid'" label="可退菜数量" align="center" width="130px">
|
||||||
v-if="detail.status == 'unpaid'"
|
|
||||||
label="可退菜数量"
|
|
||||||
align="center"
|
|
||||||
width="130px"
|
|
||||||
>
|
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-input-number
|
<el-input-number v-if="scope.row.checked" :min="0" style="width: 100px" v-model="scope.row.selNumber"
|
||||||
v-if="scope.row.checked"
|
:max="scope.row.num - scope.row.returnNum"></el-input-number>
|
||||||
:min="0"
|
|
||||||
style="width: 100px"
|
|
||||||
v-model="scope.row.selNumber"
|
|
||||||
:max="scope.row.num - scope.row.returnNum"
|
|
||||||
></el-input-number>
|
|
||||||
<span class="" v-else>{{ scope.row.num - scope.row.returnNum }}</span>
|
<span class="" v-else>{{ scope.row.num - scope.row.returnNum }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column v-else label="可退款数量" align="center" width="130px">
|
<el-table-column v-else label="可退款数量" align="center" width="130px">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-input-number
|
<el-input-number v-if="scope.row.checked" :min="0" style="width: 100px" v-model="scope.row.selNumber"
|
||||||
v-if="scope.row.checked"
|
:max="scope.row.num - scope.row.refundNum - scope.row.returnNum"></el-input-number>
|
||||||
:min="0"
|
|
||||||
style="width: 100px"
|
|
||||||
v-model="scope.row.selNumber"
|
|
||||||
:max="scope.row.num - scope.row.refundNum - scope.row.returnNum"
|
|
||||||
></el-input-number>
|
|
||||||
<span class="" v-else>
|
<span class="" v-else>
|
||||||
{{ scope.row.num - scope.row.refundNum - scope.row.returnNum }}
|
{{ scope.row.num - scope.row.refundNum - scope.row.returnNum }}
|
||||||
</span>
|
</span>
|
||||||
@@ -227,23 +198,13 @@
|
|||||||
<el-table-column label="操作" fixed="right">
|
<el-table-column label="操作" fixed="right">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<template v-if="detail.status != 'unpaid'">
|
<template v-if="detail.status != 'unpaid'">
|
||||||
<el-button
|
<el-button v-if="canTuikuan(scope.row)" link size="small" @click="tuikuan(scope.row)">
|
||||||
v-if="canTuikuan(scope.row)"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="tuikuan(scope.row)"
|
|
||||||
>
|
|
||||||
<span>退款</span>
|
<span>退款</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<span class="color-999" v-if="scope.row.status == 'refund'">已退款</span>
|
<span class="color-999" v-if="scope.row.status == 'refund'">已退款</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="detail.status == 'unpaid'">
|
<template v-if="detail.status == 'unpaid'">
|
||||||
<el-button
|
<el-button v-if="canTuicai(scope.row)" link size="small" @click="tuicai(scope.row)">
|
||||||
v-if="canTuicai(scope.row)"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="tuicai(scope.row)"
|
|
||||||
>
|
|
||||||
<span>退菜</span>
|
<span>退菜</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<span class="color-999" v-else>已退菜</span>
|
<span class="color-999" v-else>已退菜</span>
|
||||||
@@ -253,41 +214,25 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
<!-- 退款 -->
|
<!-- 退款 -->
|
||||||
<div
|
<div class="u-p-20 u-flex u-row-right" v-if="
|
||||||
class="u-p-20 u-flex u-row-right"
|
detail.status !== 'refund' &&
|
||||||
v-if="
|
detail.status !== 'unpaid' &&
|
||||||
detail.status !== 'refund' &&
|
detail.status !== 'cancelled'
|
||||||
detail.status !== 'unpaid' &&
|
">
|
||||||
detail.status !== 'cancelled'
|
<el-checkbox v-model="allSelected" @change="allSelectedChange" label="全选"></el-checkbox>
|
||||||
"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
v-model="allSelected"
|
|
||||||
@change="allSelectedChange"
|
|
||||||
label="全选"
|
|
||||||
></el-checkbox>
|
|
||||||
<el-button type="danger" class="u-m-l-20" @click.stop="tuikuan('all')">退款</el-button>
|
<el-button type="danger" class="u-m-l-20" @click.stop="tuikuan('all')">退款</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 退菜 -->
|
<!-- 退菜 -->
|
||||||
<div class="u-p-20 u-flex u-row-right" v-if="detail.status == 'unpaid'">
|
<div class="u-p-20 u-flex u-row-right" v-if="detail.status == 'unpaid'">
|
||||||
<el-checkbox
|
<el-checkbox v-model="allSelected" @change="allSelectedChange" label="全选"></el-checkbox>
|
||||||
v-model="allSelected"
|
|
||||||
@change="allSelectedChange"
|
|
||||||
label="全选"
|
|
||||||
></el-checkbox>
|
|
||||||
<el-button type="danger" class="u-m-l-20" @click.stop="tuicai('all')">退菜</el-button>
|
<el-button type="danger" class="u-m-l-20" @click.stop="tuicai('all')">退菜</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
<!-- 退款 -->
|
<!-- 退款 -->
|
||||||
<return-money
|
<return-money :modal="false" ref="refReturnMoney" :max="selGoods.num" :goods="selGoods"
|
||||||
:modal="false"
|
@confirm="refReturnMoneyConfirm"></return-money>
|
||||||
ref="refReturnMoney"
|
|
||||||
:max="selGoods.num"
|
|
||||||
:goods="selGoods"
|
|
||||||
@confirm="refReturnMoneyConfirm"
|
|
||||||
></return-money>
|
|
||||||
<!-- 退菜 -->
|
<!-- 退菜 -->
|
||||||
<order-return-cart ref="refReturnCart" @confirm="refReturnCartConfirm"></order-return-cart>
|
<order-return-cart ref="refReturnCart" @confirm="refReturnCartConfirm"></order-return-cart>
|
||||||
</div>
|
</div>
|
||||||
@@ -462,6 +407,12 @@ export default {
|
|||||||
},
|
},
|
||||||
tuikuan(item) {
|
tuikuan(item) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
let arrs = []
|
||||||
|
for (let i in this.detail.detailMap) {
|
||||||
|
this.detail.detailMap[i].map((v) => {
|
||||||
|
arrs.push(v);
|
||||||
|
});
|
||||||
|
}
|
||||||
this.$refs.refReturnMoney.open([], this.detail);
|
this.$refs.refReturnMoney.open([], this.detail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -480,6 +431,9 @@ export default {
|
|||||||
if (arr.length == 0) {
|
if (arr.length == 0) {
|
||||||
return ElMessage.error("请选择要退款的商品和数量");
|
return ElMessage.error("请选择要退款的商品和数量");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('tuikuan===', arr);
|
||||||
|
|
||||||
this.$refs.refReturnMoney.open(arr, this.detail);
|
this.$refs.refReturnMoney.open(arr, this.detail);
|
||||||
},
|
},
|
||||||
tuicai(item) {
|
tuicai(item) {
|
||||||
@@ -498,7 +452,7 @@ export default {
|
|||||||
if (arr.length == 0) {
|
if (arr.length == 0) {
|
||||||
return ElMessage.error("请选择要退菜的商品和数量");
|
return ElMessage.error("请选择要退菜的商品和数量");
|
||||||
}
|
}
|
||||||
console.log(arr);
|
console.log('tuicai===', arr);
|
||||||
this.$refs.refReturnCart.open(arr, this.detail);
|
this.$refs.refReturnCart.open(arr, this.detail);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,7 @@
|
|||||||
<div class="u-flex u-col-top" v-if="goodsList && goodsList.length">
|
<div class="u-flex u-col-top" v-if="goodsList && goodsList.length">
|
||||||
<span class="u-m-0">退款商品</span>
|
<span class="u-m-0">退款商品</span>
|
||||||
<div class="u-p-l-20 goods-list">
|
<div class="u-p-l-20 goods-list">
|
||||||
<div
|
<div class="u-flex u-font-12 goods-list-item" v-for="(goods, index) in goodsList" :key="index">
|
||||||
class="u-flex u-font-12 goods-list-item"
|
|
||||||
v-for="(goods, index) in goodsList"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<span class="">
|
<span class="">
|
||||||
{{ goods.productName }}
|
{{ goods.productName }}
|
||||||
</span>
|
</span>
|
||||||
@@ -35,12 +31,7 @@
|
|||||||
<div class="flex u-row-between">
|
<div class="flex u-row-between">
|
||||||
<span class="color-red">退款金额</span>
|
<span class="color-red">退款金额</span>
|
||||||
<div class="u-flex u-flex-1 u-p-l-20">
|
<div class="u-flex u-flex-1 u-p-l-20">
|
||||||
<el-input-number
|
<el-input-number type="number" v-model="number" :min="min" :max="canReturnMoney"></el-input-number>
|
||||||
type="number"
|
|
||||||
v-model="number"
|
|
||||||
:min="min"
|
|
||||||
:max="canReturnMoney"
|
|
||||||
></el-input-number>
|
|
||||||
<span class="u-m-l-10">可退{{ canReturnMoney }}元</span>
|
<span class="u-m-l-10">可退{{ canReturnMoney }}元</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,13 +64,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="u-flex u-flex-wrap tags">
|
<div class="u-flex u-flex-wrap tags">
|
||||||
<div
|
<div class="tag" v-for="(tag, index) in tags" @click="changeSel(tag)" :key="index"
|
||||||
class="tag"
|
:class="{ active: tag.checked }">
|
||||||
v-for="(tag, index) in tags"
|
|
||||||
@click="changeSel(tag)"
|
|
||||||
:key="index"
|
|
||||||
:class="{ active: tag.checked }"
|
|
||||||
>
|
|
||||||
{{ tag.label }}
|
{{ tag.label }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -94,16 +80,22 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<safe-password ref="refPassword" @confirm="pwdConfirm"></safe-password>
|
<safe-password ref="refPassword" @confirm="pwdConfirm"></safe-password>
|
||||||
|
<!-- 退款退菜推库存的操作弹窗 -->
|
||||||
|
<refundConsModal ref="refundConsModalRef" :list="refundList" @success="refundConsModalSuccess" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import safePassword from "./password.vue";
|
import safePassword from "./password.vue";
|
||||||
import { useUserStore } from "@/store/modules/user";
|
import { useUserStore } from "@/store/modules/user";
|
||||||
|
import { useCartsStore } from "@/store/modules/carts";
|
||||||
|
import categoryApi from "@/api/product/productclassification";
|
||||||
|
import refundConsModal from "@/components/refundConsModal.vue";
|
||||||
const shopUser = useUserStore();
|
const shopUser = useUserStore();
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
safePassword,
|
safePassword,
|
||||||
|
refundConsModal
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
modal: {
|
modal: {
|
||||||
@@ -135,6 +127,8 @@ export default {
|
|||||||
goods: {
|
goods: {
|
||||||
productId: -999,
|
productId: -999,
|
||||||
},
|
},
|
||||||
|
refundList: [],
|
||||||
|
refundStock: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -196,18 +190,26 @@ export default {
|
|||||||
.join(",");
|
.join(",");
|
||||||
const note = selTag + (this.note.length > 0 ? "," + this.note : "");
|
const note = selTag + (this.note.length > 0 ? "," + this.note : "");
|
||||||
console.log(note);
|
console.log(note);
|
||||||
this.$emit("confirm", {
|
|
||||||
|
const data = {
|
||||||
refundAmount: this.number,
|
refundAmount: this.number,
|
||||||
cash: this.cash,
|
cash: this.cash,
|
||||||
refundReason: note,
|
refundReason: note,
|
||||||
refundDetails: this.goodsList.map((v) => {
|
refundDetails: this.goodsList.map((v) => {
|
||||||
return { id: v.id, num: v.num };
|
return { id: v.id, num: v.selNumber };
|
||||||
}),
|
}),
|
||||||
...e,
|
...e,
|
||||||
});
|
refundStock: this.refundStock
|
||||||
|
}
|
||||||
|
this.$emit("confirm", data);
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
confirm() {
|
// 退款推库存的操作
|
||||||
|
refundConsModalSuccess(e) {
|
||||||
|
this.refundStock = e
|
||||||
|
this.emitTuikuan()
|
||||||
|
},
|
||||||
|
async confirm() {
|
||||||
const selTag = this.tags
|
const selTag = this.tags
|
||||||
.filter((item) => item.checked)
|
.filter((item) => item.checked)
|
||||||
.map((item) => item.label)
|
.map((item) => item.label)
|
||||||
@@ -220,14 +222,58 @@ export default {
|
|||||||
this.$refs.refPassword.open();
|
this.$refs.refPassword.open();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 在这里给订单的商品补全库存信息 start
|
||||||
|
const carts = useCartsStore();
|
||||||
|
let categorys = JSON.parse(localStorage.getItem('categorys'))
|
||||||
|
let shopInfo = JSON.parse(localStorage.getItem('userInfo'))
|
||||||
|
|
||||||
|
if (!categorys) {
|
||||||
|
categorys = await categoryApi.getList({})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.goodsList.forEach(item => {
|
||||||
|
carts.goods.forEach(val => {
|
||||||
|
if (item.productId == val.id) {
|
||||||
|
if (shopInfo.refundMode == 1) {
|
||||||
|
// 跟随分类退款模式
|
||||||
|
categorys.forEach(v => {
|
||||||
|
if (val.categoryId == v.id) {
|
||||||
|
item.refundMode = v.refundMode
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 跟随商品退款模式及
|
||||||
|
item.refundMode = val.refundMode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
console.log('this.goodsList===', this.goodsList);
|
||||||
|
// 在这里给订单的商品补全库存信息 end
|
||||||
|
|
||||||
|
this.goodsList.forEach(item => {
|
||||||
|
if (item.refundMode == 3) {
|
||||||
|
this.refundList.push({
|
||||||
|
name: item.productName,
|
||||||
|
num: item.selNumber
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.refundList.length > 0) {
|
||||||
|
this.$refs.refundConsModalRef.show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
this.emitTuikuan();
|
this.emitTuikuan();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() { },
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-tag) {
|
:deep(.el-tag) {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
@@ -237,6 +283,7 @@ export default {
|
|||||||
line-height: 35px;
|
line-height: 35px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
.tag {
|
.tag {
|
||||||
margin: 10px 10px 0 0;
|
margin: 10px 10px 0 0;
|
||||||
@@ -246,6 +293,7 @@ export default {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #000;
|
color: #000;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
color: #1890ff;
|
color: #1890ff;
|
||||||
background: #e8f4ff;
|
background: #e8f4ff;
|
||||||
@@ -253,14 +301,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.number-box .el-input__inner::-webkit-inner-spin-button) {
|
:deep(.number-box .el-input__inner::-webkit-inner-spin-button) {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.number-box .el-input__inner::-webkit-outer-spin-button) {
|
:deep(.number-box .el-input__inner::-webkit-outer-spin-button) {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-list-item {
|
.goods-list-item {
|
||||||
height: 24px;
|
height: 24px;
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
@@ -268,6 +319,7 @@ export default {
|
|||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-list-item:not(:first-child) {
|
.goods-list-item:not(:first-child) {
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import type { statusType } from "@/api/order/order";
|
|||||||
export const statusOptions: statusOptions[] = [
|
export const statusOptions: statusOptions[] = [
|
||||||
{ label: "全部", value: "" },
|
{ label: "全部", value: "" },
|
||||||
{ label: "待支付", value: "unpaid" },
|
{ label: "待支付", value: "unpaid" },
|
||||||
{ label: "制作中", value: "in-production" },
|
// { label: "制作中", value: "in-production" },
|
||||||
{ label: "待取餐", value: "wait-out" },
|
// { label: "待取餐", value: "wait-out" },
|
||||||
{ label: "订单完成", value: "done" },
|
{ label: "订单完成", value: "done" },
|
||||||
{ label: "申请退单", value: "refunding" },
|
// { label: "申请退单", value: "refunding" },
|
||||||
{ label: "退单", value: "refund" },
|
{ label: "退单", value: "refund" },
|
||||||
{ label: "部分退单", value: "part_refund" },
|
{ label: "部分退单", value: "part_refund" },
|
||||||
{ label: "取消订单", value: "cancelled" },
|
{ label: "取消订单", value: "cancelled" },
|
||||||
@@ -107,6 +107,14 @@ export function returnOptionsLabel(optionsType: optionsType, value: string | num
|
|||||||
const option = options.find((item) => item.value === value);
|
const option = options.find((item) => item.value === value);
|
||||||
return option ? option.label : "";
|
return option ? option.label : "";
|
||||||
}
|
}
|
||||||
|
export function returnPayTypeOptionsLabel(optionsType: optionsType, value: string | number) {
|
||||||
|
const options = returnOptions(optionsType).filter(v => v.value);
|
||||||
|
if (!options) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const option = options.find((item) => item.value === value);
|
||||||
|
return option ? option.label : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface options {
|
export interface options {
|
||||||
|
|||||||
@@ -86,6 +86,14 @@ const contentConfig: IContentConfig = {
|
|||||||
prop: "payAmount",
|
prop: "payAmount",
|
||||||
width: 120,
|
width: 120,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "支付方式",
|
||||||
|
align: "center",
|
||||||
|
prop: "payType",
|
||||||
|
width: 120,
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "payType",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "订单金额 (扣除各类折扣)",
|
label: "订单金额 (扣除各类折扣)",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|||||||
@@ -2,19 +2,37 @@
|
|||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<!-- 搜索 -->
|
<!-- 搜索 -->
|
||||||
<page-search ref="searchRef" :search-config="searchConfig" :isOpenAutoSearch="true" @query-click="handleQueryClick"
|
<page-search
|
||||||
@reset-click="handleResetClick" />
|
ref="searchRef"
|
||||||
|
:search-config="searchConfig"
|
||||||
|
:isOpenAutoSearch="true"
|
||||||
|
@query-click="handleQueryClick"
|
||||||
|
@reset-click="handleResetClick"
|
||||||
|
/>
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
<page-content
|
||||||
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
ref="contentRef"
|
||||||
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
:content-config="contentConfig"
|
||||||
|
@add-click="handleAddClick"
|
||||||
|
@edit-click="handleEditClick"
|
||||||
|
@export-click="handleExportClick"
|
||||||
|
@search-click="handleSearchClick"
|
||||||
|
@toolbar-click="handleToolbarClick"
|
||||||
|
@operat-click="handleOperatClick"
|
||||||
|
@filter-change="handleFilterChange"
|
||||||
|
>
|
||||||
<template #originAmount="scope">
|
<template #originAmount="scope">
|
||||||
{{ returnOriginAmount(scope.row) }}
|
{{ returnOriginAmount(scope.row) }}
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #orderNo="scope">
|
<template #orderNo="scope">
|
||||||
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
|
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
|
||||||
<el-tooltip class="box-item" effect="dark" :content="scope.row.orderNo" placement="top-start">
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
:content="scope.row.orderNo"
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
{{ scope.row.orderNo }}
|
{{ scope.row.orderNo }}
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,7 +44,7 @@
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #goods="scope">
|
<template #goods="scope">
|
||||||
<div class="goods_info">
|
<!-- <div class="goods_info">
|
||||||
<div v-for="item in scope.row.goods" :key="item.id" class="row">
|
<div v-for="item in scope.row.goods" :key="item.id" class="row">
|
||||||
<el-image :src="item.productImg" class="cover" lazy />
|
<el-image :src="item.productImg" class="cover" lazy />
|
||||||
<div class="info">
|
<div class="info">
|
||||||
@@ -39,7 +57,8 @@
|
|||||||
<div class="sku">{{ item.skuName }}</div>
|
<div class="sku">{{ item.skuName }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
<GoodsListCollapse :goods="scope.row.goods" />
|
||||||
</template>
|
</template>
|
||||||
<template #table="scope">
|
<template #table="scope">
|
||||||
<div>
|
<div>
|
||||||
@@ -47,14 +66,14 @@
|
|||||||
名称:
|
名称:
|
||||||
<el-tag type="primary">{{ scope.row.tableName || "无" }}</el-tag>
|
<el-tag type="primary">{{ scope.row.tableName || "无" }}</el-tag>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="scope.row.tableCode">编号:{{ scope.row.tableCode }}</p>
|
<!-- <p v-if="scope.row.tableCode">编号:{{ scope.row.tableCode }}</p> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 打印状态 -->
|
<!-- 打印状态 -->
|
||||||
<template #printStatus="scope">
|
<template #printStatus="scope">
|
||||||
<span v-if="scope.row.printStatus.length > 0" style="color: var(--el-color-danger)">
|
<span v-if="scope.row.printStatus.length > 0" style="color: var(--el-color-danger)">
|
||||||
打印失败({{scope.row.printStatus.map(item => item.name).join('、')}})
|
打印失败({{ scope.row.printStatus.map((item) => item.name).join("、") }})
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -68,14 +87,25 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #mobile="scope">
|
<template #mobile="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
<copy-button
|
||||||
|
v-if="scope.row[scope.prop]"
|
||||||
|
:text="scope.row[scope.prop]"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #payType="scope">
|
||||||
|
{{ returnPayTypeOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
</template>
|
</template>
|
||||||
<template #operate="scope">
|
<template #operate="scope">
|
||||||
<div>
|
<div>
|
||||||
<el-button link @click="printOrderHandle(scope.row)">打印</el-button>
|
<el-button link @click="printOrderHandle(scope.row)">打印</el-button>
|
||||||
<el-button link @click="showdetail(scope.row)">详情</el-button>
|
<el-button link @click="showdetail(scope.row)">详情</el-button>
|
||||||
<el-button v-if="scope.row.status == 'done'" link>开票</el-button>
|
<!-- <el-button v-if="scope.row.status == 'done'" link>开票</el-button> -->
|
||||||
<el-button v-if="scope.row.status == 'unpaid'" type="primary" @click="toPayOrder(scope.row)">
|
<el-button
|
||||||
|
v-if="scope.row.status == 'unpaid'"
|
||||||
|
type="primary"
|
||||||
|
@click="toPayOrder(scope.row)"
|
||||||
|
>
|
||||||
结账
|
结账
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -91,7 +121,11 @@
|
|||||||
</page-modal>
|
</page-modal>
|
||||||
|
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
<page-modal
|
||||||
|
ref="editModalRef"
|
||||||
|
:modal-config="editModalConfig"
|
||||||
|
@submit-click="handleSubmitClick"
|
||||||
|
>
|
||||||
<template #url="scope">
|
<template #url="scope">
|
||||||
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
|
<FileUpload v-model="scope.formData[scope.prop]" :limit="1" v-bind="scope.attrs" />
|
||||||
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
|
<!-- <Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" /> -->
|
||||||
@@ -111,8 +145,8 @@ import addModalConfig from "./config/add";
|
|||||||
import contentConfig from "./config/content";
|
import contentConfig from "./config/content";
|
||||||
import editModalConfig from "./config/edit";
|
import editModalConfig from "./config/edit";
|
||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
import { returnOptionsLabel } from "./config/config";
|
import { returnOptionsLabel, returnPayTypeOptionsLabel } from "./config/config";
|
||||||
|
import GoodsListCollapse from "./components/GoodsListCollapse.vue";
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
contentRef,
|
contentRef,
|
||||||
@@ -161,7 +195,7 @@ async function printOrderHandle(order: getListResponse) {
|
|||||||
try {
|
try {
|
||||||
await orderApi.printOrder({
|
await orderApi.printOrder({
|
||||||
id: order.id,
|
id: order.id,
|
||||||
type: 0
|
type: 0,
|
||||||
});
|
});
|
||||||
ElMessage.success("打印成功");
|
ElMessage.success("打印成功");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -370,7 +404,7 @@ function showdetail(row: OrderInfoVo) {
|
|||||||
left: 36%;
|
left: 36%;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
|
|
||||||
>div:first-child {
|
> div:first-child {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -381,7 +415,7 @@ function showdetail(row: OrderInfoVo) {
|
|||||||
transform: translateX(-80px);
|
transform: translateX(-80px);
|
||||||
}
|
}
|
||||||
|
|
||||||
>div:last-child {
|
> div:last-child {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,11 @@
|
|||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
<template #refundMode="scope">
|
||||||
|
<!-- <el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||||
|
@click="isRefundStockChange($event, scope)" /> -->
|
||||||
|
<el-text>{{ returnLabel(scope.row[scope.prop]) }}</el-text>
|
||||||
|
</template>
|
||||||
<template #slotNameimage="scope">
|
<template #slotNameimage="scope">
|
||||||
<el-image v-if="scope.row.pic" :src="scope.row.pic" lazy style="width: 40px; height: 40px" />
|
<el-image v-if="scope.row.pic" :src="scope.row.pic" lazy style="width: 40px; height: 40px" />
|
||||||
<div v-else>无</div>
|
<div v-else>无</div>
|
||||||
@@ -28,20 +32,20 @@
|
|||||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
<addCategory ref="addCategoryRef" @success="handleQueryClick" />
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
|
<!-- <page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal> -->
|
||||||
|
|
||||||
<!-- 编辑 -->
|
<!-- 编辑 -->
|
||||||
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
<!-- <page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
||||||
<template #gender="scope">
|
<template #gender="scope">
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
||||||
</template>
|
</template>
|
||||||
</page-modal>
|
</page-modal> -->
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
|
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
|
||||||
@@ -67,6 +71,20 @@ import contentConfig2 from "./categoryconfig/content2";
|
|||||||
import editModalConfig from "./categoryconfig/edit";
|
import editModalConfig from "./categoryconfig/edit";
|
||||||
import searchConfig from "./categoryconfig/search";
|
import searchConfig from "./categoryconfig/search";
|
||||||
import { isSyncStatus, downloadFile } from "@/utils/index";
|
import { isSyncStatus, downloadFile } from "@/utils/index";
|
||||||
|
import addCategory from "./components/addCategory.vue";
|
||||||
|
|
||||||
|
const addCategoryRef = ref(null)
|
||||||
|
|
||||||
|
const options = ref([
|
||||||
|
{ label: "退菜退库存", value: 1 },
|
||||||
|
{ label: "仅退菜不退库存", value: 2 },
|
||||||
|
{ label: "每次询问-退菜后弹窗提示,可手动选择", value: 3 },
|
||||||
|
])
|
||||||
|
|
||||||
|
function returnLabel(value: number) {
|
||||||
|
const option = options.value.find((option) => option.value === value);
|
||||||
|
return option ? option.label : "未知";
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -106,9 +124,20 @@ async function handleExportClick() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 退菜是否退库存开关切换
|
||||||
|
async function isRefundStockChange(e: any, scope: any) {
|
||||||
|
try {
|
||||||
|
await UserAPI.update(scope.row);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
ElMessage.error("操作失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
addCategoryRef.value.open()
|
||||||
|
// addModalRef.value?.setModalVisible();
|
||||||
// 加载部门下拉数据源
|
// 加载部门下拉数据源
|
||||||
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
@@ -116,15 +145,16 @@ async function handleAddClick() {
|
|||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
addCategoryRef.value.open(row)
|
||||||
// 加载部门下拉数据源
|
// editModalRef.value?.handleDisabled(false);
|
||||||
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// // 加载部门下拉数据源
|
||||||
// 加载角色下拉数据源
|
// // editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// // 加载角色下拉数据源
|
||||||
// 根据id获取数据进行填充
|
// // editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
const data = await UserAPI.getunitinfo(row.id);
|
// // 根据id获取数据进行填充
|
||||||
editModalRef.value?.setFormData(data);
|
// const data = await UserAPI.getunitinfo(row.id);
|
||||||
editModalRef.value?.setModalVisible();
|
// editModalRef.value?.setFormData(data);
|
||||||
|
// editModalRef.value?.setModalVisible();
|
||||||
}
|
}
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
function handleToolbarClick(name: string) {
|
function handleToolbarClick(name: string) {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const modalConfig: IModalConfig<UserForm> = {
|
|||||||
draggable: true,
|
draggable: true,
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
labelWidth: 100,
|
labelWidth: 120,
|
||||||
},
|
},
|
||||||
formAction: UserAPI.addunit,
|
formAction: UserAPI.addunit,
|
||||||
beforeSubmit(data) {
|
beforeSubmit(data) {
|
||||||
@@ -31,6 +31,26 @@ const modalConfig: IModalConfig<UserForm> = {
|
|||||||
prop: "pic",
|
prop: "pic",
|
||||||
type: "UpImage",
|
type: "UpImage",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '退菜是否退库存',
|
||||||
|
prop: 'refundMode',
|
||||||
|
type: 'radio',
|
||||||
|
options: [
|
||||||
|
{ label: "退菜退库存", value: 1 },
|
||||||
|
{ label: "仅退菜不退库存", value: 2 },
|
||||||
|
{ label: "每次询问-退菜后弹窗提示,可手动选择", value: 3 },
|
||||||
|
],
|
||||||
|
initialValue: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "排序",
|
||||||
|
prop: "sort",
|
||||||
|
type: "input-number",
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请输入排序",
|
||||||
|
},
|
||||||
|
initialValue: 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "开关",
|
label: "开关",
|
||||||
prop: "status",
|
prop: "status",
|
||||||
@@ -44,15 +64,6 @@ const modalConfig: IModalConfig<UserForm> = {
|
|||||||
inactiveValue: 0,
|
inactiveValue: 0,
|
||||||
},
|
},
|
||||||
initialValue: 1,
|
initialValue: 1,
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "排序",
|
|
||||||
prop: "sort",
|
|
||||||
type: "input-number",
|
|
||||||
attrs: {
|
|
||||||
placeholder: "请输入排序",
|
|
||||||
},
|
|
||||||
initialValue: 1,
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
templet: "switch",
|
templet: "switch",
|
||||||
slotName: "status",
|
slotName: "status",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "退菜是否退库存",
|
||||||
|
align: "center",
|
||||||
|
prop: "refundMode",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "refundMode",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "操作",
|
label: "操作",
|
||||||
align: "center",
|
align: "center",
|
||||||
|
|||||||
@@ -35,6 +35,26 @@ const modalConfig: IModalConfig<UserForm> = {
|
|||||||
prop: "pic",
|
prop: "pic",
|
||||||
type: "UpImage",
|
type: "UpImage",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: '退菜是否退库存',
|
||||||
|
prop: 'refundMode',
|
||||||
|
type: 'radio',
|
||||||
|
options: [
|
||||||
|
{ label: "退菜退库存", value: 1 },
|
||||||
|
{ label: "仅退菜不退库存", value: 2 },
|
||||||
|
{ label: "每次询问-退菜后弹窗提示,可手动选择", value: 3 },
|
||||||
|
],
|
||||||
|
initialValue: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "排序",
|
||||||
|
prop: "sort",
|
||||||
|
type: "input-number",
|
||||||
|
attrs: {
|
||||||
|
placeholder: "请输入排序",
|
||||||
|
},
|
||||||
|
initialValue: 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "开关",
|
label: "开关",
|
||||||
prop: "status",
|
prop: "status",
|
||||||
@@ -48,15 +68,6 @@ const modalConfig: IModalConfig<UserForm> = {
|
|||||||
inactiveValue: 0,
|
inactiveValue: 0,
|
||||||
},
|
},
|
||||||
initialValue: 1,
|
initialValue: 1,
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "排序",
|
|
||||||
prop: "sort",
|
|
||||||
type: "input-number",
|
|
||||||
attrs: {
|
|
||||||
placeholder: "请输入排序",
|
|
||||||
},
|
|
||||||
initialValue: 1,
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
100
src/views/product/components/addCategory.vue
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="form.id ? '添加分类' : '编辑分类'" width="650px" v-model="visible" @close="closeHandle">
|
||||||
|
<el-form ref="formRef" :rules="rules" :model="form" label-position="right" label-width="120px">
|
||||||
|
<el-form-item label="分类名称" prop="name">
|
||||||
|
<el-input placeholder="请输入分类名称" v-model="form.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="分类图片">
|
||||||
|
<SingleImageUpload v-model="form.pic" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退菜是否退库存">
|
||||||
|
<el-radio-group v-model="form.refundMode">
|
||||||
|
<el-radio label="退菜退库存" :value="1"></el-radio>
|
||||||
|
<el-radio label="仅退菜不退库存" :value="2"></el-radio>
|
||||||
|
<el-radio label="每次询问-退菜后弹窗提示" :value="3"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="排序">
|
||||||
|
<el-input-number v-model="form.sort" :min="1" :step="1"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="状态">
|
||||||
|
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleOk" :loading="loading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import UserAPI from "@/api/product/productclassification";
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const form = ref({
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
pic: '',
|
||||||
|
refundMode: 1, // 退菜是否退库存 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示
|
||||||
|
sort: 1,
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
|
const rules = ref({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入单位名称',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
function handleOk() {
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true
|
||||||
|
if (form.value.id == '') {
|
||||||
|
await UserAPI.addunit(form.value)
|
||||||
|
} else {
|
||||||
|
await UserAPI.update(form.value)
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
visible.value = false
|
||||||
|
ElMessage.success(form.value.id ? '添加成功' : '编辑成功')
|
||||||
|
emit('success')
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandle() {
|
||||||
|
form.value.name = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(obj) {
|
||||||
|
visible.value = true
|
||||||
|
if (obj && obj.id) {
|
||||||
|
form.value = _.cloneDeep(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
417
src/views/product/components/addSkuModal.vue
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="form.id ? '编辑模板' : '新增模板'" width="900px" v-model="visible" @close="onClose">
|
||||||
|
<div class="form_wrap">
|
||||||
|
<div class="form_left">
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="100" label-position="right">
|
||||||
|
<el-form-item label="模板名称" prop="name">
|
||||||
|
<el-input v-model="form.name" :maxlength="20" placeholder="如:主食、酒水、辣度、大小等"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<transition-group name="slide">
|
||||||
|
<div class="sortable-parent" v-for="(item, index) in form.children" :key="item._id"
|
||||||
|
:data-parent-index="index"> <!-- 修复Vue3绑定语法 -->
|
||||||
|
<el-form-item label="规格名称">
|
||||||
|
<div class="center">
|
||||||
|
<el-input v-model="item.name" placeholder="如:口味、忌口、温度、分量等"></el-input>
|
||||||
|
<el-icon v-if="index > 0" size="20" @click="form.children.splice(index, 1)">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<transition-group name="fade" tag="div">
|
||||||
|
<el-form-item label="规格值" v-for="(val, i) in item.children" :key="val._id" :data-child-index="i">
|
||||||
|
<!-- 修复Vue3绑定语法 -->
|
||||||
|
<div class="center">
|
||||||
|
<div style="flex:1;">
|
||||||
|
<el-input v-model="val.name" placeholder="如:五香、微辣、大份、小份等"></el-input>
|
||||||
|
</div>
|
||||||
|
<el-icon v-if="i > 0" size="20" @click="form.children[index].children.splice(i, 1)">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</transition-group>
|
||||||
|
|
||||||
|
<el-form-item style="margin-top:-10px;">
|
||||||
|
<el-button size="small" @click="addSpecValue(index)">添加规格值</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
|
||||||
|
<el-form-item label-width="0">
|
||||||
|
<div class="flex_end">
|
||||||
|
<el-button type="primary" @click="addSpec">添加规格</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form_right">
|
||||||
|
<div class="preview_wrap">
|
||||||
|
<div class="title_wrap">
|
||||||
|
<el-text size="large">效果预览</el-text>
|
||||||
|
<el-text size="small">可拖动排序</el-text>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row_wrap" id="parent-sort">
|
||||||
|
<!-- 修复index未定义 + 绑定语法错误 -->
|
||||||
|
<div class="row" v-for="(item, index) in form.children" :key="item._id" :data-index="index">
|
||||||
|
<div class="row_top">
|
||||||
|
<el-text size="large">{{ item.name || '请输入规格名称' }}</el-text>
|
||||||
|
<el-icon size="20" class="drag-handle">
|
||||||
|
<Rank />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row_content" v-if="item.children.length" :id="`child-sort-${item._id}`">
|
||||||
|
<div class="tag" v-for="val in item.children" :key="val._id">
|
||||||
|
<el-text>{{ val.name || '请输入规格值' }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tag empty-tag" v-else>
|
||||||
|
<el-text>请添加规格值</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleOk" :loading="loading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { ref, onMounted, watch, nextTick } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { Delete, Rank } from '@element-plus/icons-vue'
|
||||||
|
import Sortable from 'sortablejs'
|
||||||
|
import UserAPI from "@/api/product/specificationsconfig";
|
||||||
|
|
||||||
|
const generateId = () => {
|
||||||
|
return Date.now() + '_' + Math.floor(Math.random() * 10000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const childrenObj = ref({
|
||||||
|
_id: generateId(),
|
||||||
|
name: '',
|
||||||
|
children: [{ _id: generateId(), name: '' }]
|
||||||
|
})
|
||||||
|
|
||||||
|
const formObj = {
|
||||||
|
_id: '',
|
||||||
|
name: '',
|
||||||
|
children: [_.cloneDeep(childrenObj.value)]
|
||||||
|
}
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const form = ref(formObj)
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const rules = ref({
|
||||||
|
name: [{ required: true, message: '模板名称不能为空', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
|
||||||
|
function onClose() {
|
||||||
|
form.value = _.cloneDeep(formObj)
|
||||||
|
// if (parentSortable) parentSortable.destroy()
|
||||||
|
// childSortableMap.forEach(s => s.destroy())
|
||||||
|
// childSortableMap.clear()
|
||||||
|
|
||||||
|
// setTimeout(() => {
|
||||||
|
// }, 50);
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSpec() {
|
||||||
|
form.value.children.push({
|
||||||
|
_id: generateId(),
|
||||||
|
name: '',
|
||||||
|
children: [{ _id: generateId(), name: '' }]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSpecValue(parentIndex) {
|
||||||
|
form.value.children[parentIndex].children.push({
|
||||||
|
_id: generateId(),
|
||||||
|
name: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
function handleOk() {
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
let flag = true
|
||||||
|
let pIndex = 0
|
||||||
|
let index = 0
|
||||||
|
form.value.children.forEach((item, index) => {
|
||||||
|
if (item.name == '') {
|
||||||
|
flag = false
|
||||||
|
pIndex = index
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item.children.forEach((val, i) => {
|
||||||
|
if (val.name == '') {
|
||||||
|
flag = false
|
||||||
|
pIndex = index
|
||||||
|
index = i
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!flag) {
|
||||||
|
ElMessage.error('请补全规格信息')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
console.log('最终提交数据:', form.value)
|
||||||
|
|
||||||
|
await UserAPI.quickAdd(form.value)
|
||||||
|
ElMessage.success(form.value.id ? '编辑成功' : '添加成功')
|
||||||
|
visible.value = false
|
||||||
|
loading.value = false
|
||||||
|
|
||||||
|
emit('success')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(obj) {
|
||||||
|
visible.value = true
|
||||||
|
if (obj && obj.id) {
|
||||||
|
obj.children.forEach(item => {
|
||||||
|
item._id = generateId()
|
||||||
|
item.children.forEach(val => {
|
||||||
|
val._id = generateId()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
form.value = _.cloneDeep(obj)
|
||||||
|
console.log(form.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
|
||||||
|
let parentSortable = null
|
||||||
|
const childSortableMap = new Map()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
nextTick(() => {
|
||||||
|
initParentSort()
|
||||||
|
initAllChildSort()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => form.value.children, () => {
|
||||||
|
nextTick(() => {
|
||||||
|
initParentSort()
|
||||||
|
initAllChildSort()
|
||||||
|
})
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
|
function initParentSort() {
|
||||||
|
const el = document.getElementById('parent-sort')
|
||||||
|
if (!el) return
|
||||||
|
if (parentSortable) parentSortable.destroy()
|
||||||
|
|
||||||
|
parentSortable = Sortable.create(el, {
|
||||||
|
handle: '.drag-handle', // 仅拖拽手柄生效
|
||||||
|
animation: 200,
|
||||||
|
ghostClass: 'sort-ghost', // 仅保留占位提示
|
||||||
|
forceFallback: true,
|
||||||
|
fallbackOnBody: false, // 禁用body上的克隆预览
|
||||||
|
fallbackClone: false, // 禁用拖拽克隆元素(核心:移除跟随预览)
|
||||||
|
// 移除dragClass,禁用拖拽预览样式
|
||||||
|
onEnd(evt) {
|
||||||
|
const { oldIndex, newIndex } = evt
|
||||||
|
if (oldIndex === newIndex) return
|
||||||
|
const moved = form.value.children.splice(oldIndex, 1)[0]
|
||||||
|
form.value.children.splice(newIndex, 0, moved)
|
||||||
|
nextTick(initAllChildSort)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function initAllChildSort() {
|
||||||
|
childSortableMap.forEach(s => s.destroy())
|
||||||
|
childSortableMap.clear()
|
||||||
|
|
||||||
|
form.value.children.forEach(item => {
|
||||||
|
const id = `child-sort-${item._id}`
|
||||||
|
const el = document.getElementById(id)
|
||||||
|
if (!el) return
|
||||||
|
|
||||||
|
const s = Sortable.create(el, {
|
||||||
|
animation: 200,
|
||||||
|
ghostClass: 'sort-ghost', // 仅保留占位提示
|
||||||
|
direction: 'horizontal',
|
||||||
|
forceFallback: true,
|
||||||
|
fallbackOnBody: false, // 禁用body上的克隆预览
|
||||||
|
fallbackClone: false, // 禁用拖拽克隆元素(核心)
|
||||||
|
draggable: '.tag', // 仅tag可拖拽
|
||||||
|
// 移除dragClass,禁用拖拽预览样式
|
||||||
|
onEnd(evt) {
|
||||||
|
const { oldIndex, newIndex } = evt
|
||||||
|
if (oldIndex === newIndex) return
|
||||||
|
const list = item.children
|
||||||
|
const moved = list.splice(oldIndex, 1)[0]
|
||||||
|
list.splice(newIndex, 0, moved)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
childSortableMap.set(id, s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.flex_end {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable-parent {
|
||||||
|
border: 1px solid #ececec;
|
||||||
|
padding: 14px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form_wrap {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
|
||||||
|
.form_left {
|
||||||
|
flex: 1;
|
||||||
|
height: 60vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form_right {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview_wrap {
|
||||||
|
border: 1px solid #ececec;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 14px;
|
||||||
|
|
||||||
|
.title_wrap {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row_wrap {
|
||||||
|
padding-top: 14px;
|
||||||
|
|
||||||
|
.row {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.row_top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
cursor: default;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
|
||||||
|
.drag-handle {
|
||||||
|
cursor: grab;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row_content {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
min-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
padding: 4px 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #e6e6e6;
|
||||||
|
cursor: grab;
|
||||||
|
user-select: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tag {
|
||||||
|
background: #f5f5f5;
|
||||||
|
color: #999;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 仅保留占位提示样式(无跟随预览)
|
||||||
|
:deep(.sort-ghost) {
|
||||||
|
opacity: 0.4;
|
||||||
|
background: #f5f5f5 !important;
|
||||||
|
border: 1px dashed #409eff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除所有拖拽预览相关样式
|
||||||
|
:deep(.parent-dragging),
|
||||||
|
:deep(.child-dragging) {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-move-active,
|
||||||
|
.fade-move-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-enter-from,
|
||||||
|
.slide-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
80
src/views/product/components/addUnit.vue
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="form.id ? '添加单位' : '编辑单位'" width="500px" v-model="visible" @close="closeHandle">
|
||||||
|
<el-form ref="formRef" :rules="rules" :model="form" label-position="right" label-width="80px">
|
||||||
|
<el-form-item label="单位名称" prop="name">
|
||||||
|
<el-input placeholder="请输入单位名称" v-model="form.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="handleOk" :loading="loading">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import UserAPI from "@/api/product/commonUnits";
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const loading = ref(false)
|
||||||
|
const formRef = ref(null)
|
||||||
|
const form = ref({
|
||||||
|
id: '',
|
||||||
|
name: ''
|
||||||
|
})
|
||||||
|
const rules = ref({
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入单位名称',
|
||||||
|
trigger: 'blur'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['success'])
|
||||||
|
function handleOk() {
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
try {
|
||||||
|
if (valid) {
|
||||||
|
loading.value = true
|
||||||
|
if (form.value.id == '') {
|
||||||
|
await UserAPI.addunit(form.value)
|
||||||
|
} else {
|
||||||
|
await UserAPI.update(form.value)
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
visible.value = false
|
||||||
|
ElMessage.success(form.value.id ? '添加成功' : '编辑成功')
|
||||||
|
emit('success')
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandle() {
|
||||||
|
form.value.name = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(obj) {
|
||||||
|
visible.value = true
|
||||||
|
if (obj && obj.id) {
|
||||||
|
form.value = _.cloneDeep(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -5,11 +5,12 @@
|
|||||||
<page-search ref="searchRef" :search-config="searchConfig" @query-click="newHandleQueryClick"
|
<page-search ref="searchRef" :search-config="searchConfig" @query-click="newHandleQueryClick"
|
||||||
@reset-click="handleResetClick2" />
|
@reset-click="handleResetClick2" />
|
||||||
<!-- 顶部数据 -->
|
<!-- 顶部数据 -->
|
||||||
<Statistics :data="gongjiData"></Statistics>
|
<!-- <Statistics :data="gongjiData"></Statistics> -->
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
<page-content ref="contentRef" :content-config="contentConfig" @add-click="handleAddClick"
|
||||||
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
@edit-click="handleEditClick" @export-click="handleExportClick" @search-click="handleSearchClick"
|
||||||
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange">
|
@toolbar-click="handleToolbarClick" @operat-click="handleOperatClick" @filter-change="handleFilterChange"
|
||||||
|
@selectChange="handleSelectionChange">
|
||||||
<!-- <template #status="scope">
|
<!-- <template #status="scope">
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
@@ -17,6 +18,12 @@
|
|||||||
</template> -->
|
</template> -->
|
||||||
<template #custom>
|
<template #custom>
|
||||||
<importData :type="3" @close="newHandleQueryClick" />
|
<importData :type="3" @close="newHandleQueryClick" />
|
||||||
|
<el-select :disabled="batchOperationSelectRows.length == 0"
|
||||||
|
:placeholder="`批量操作${batchOperationSelectRows.length == 0 ? '(请选择商品后操作)' : ''}`" v-model="batchOperationValue"
|
||||||
|
style="width: 240px;margin-left: 16px;">
|
||||||
|
<el-option v-for="item in batchOperationList" :key="item.id" :value="item.id" :label="item.lable"
|
||||||
|
@click="batchOperationChange(item.id)"></el-option>
|
||||||
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
<template #type="scope">
|
<template #type="scope">
|
||||||
{{ typeFilter(scope.row[scope.prop]) }}
|
{{ typeFilter(scope.row[scope.prop]) }}
|
||||||
@@ -29,7 +36,8 @@
|
|||||||
@click="handleSwitchChange(scope.row)"></el-switch>
|
@click="handleSwitchChange(scope.row)"></el-switch>
|
||||||
</template>
|
</template>
|
||||||
<template #isStock="scope">
|
<template #isStock="scope">
|
||||||
<el-switch disabled v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"></el-switch>
|
<el-switch v-if="!scope.row.productId" v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||||
|
:disabled="!scope.row.type" @click="isStockChange(scope.row)"></el-switch>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #kucunedit="scope">
|
<template #kucunedit="scope">
|
||||||
@@ -44,11 +52,16 @@
|
|||||||
<template #tuikuantuihui="scope">
|
<template #tuikuantuihui="scope">
|
||||||
<el-switch v-if="!scope.row.productId" v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
<el-switch v-if="!scope.row.productId" v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||||
@click="handleSwitchhaocai(scope.row)"></el-switch>
|
@click="handleSwitchhaocai(scope.row)"></el-switch>
|
||||||
|
<!-- <el-text>{{ returnLabel(scope.row[scope.prop]) }}</el-text> -->
|
||||||
</template>
|
</template>
|
||||||
<template #sellOut="scope">
|
<template #sellOut="scope">
|
||||||
<el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
<el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||||
@click="handleSwitchChangeTwo(scope.row)"></el-switch>
|
@click="handleSwitchChangeTwo(scope.row)"></el-switch>
|
||||||
</template>
|
</template>
|
||||||
|
<template #autoSellOut="scope">
|
||||||
|
<el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||||
|
@click="handleSwitchChangeTwo2($event, scope.row)"></el-switch>
|
||||||
|
</template>
|
||||||
<template #mobile="scope">
|
<template #mobile="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
@@ -95,7 +108,7 @@
|
|||||||
<el-input-number v-model="datas.number" :min="1" label="描述文字"></el-input-number>
|
<el-input-number v-model="datas.number" :min="1" label="描述文字"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="报损照片" label-width="">
|
<el-form-item label="报损照片" label-width="">
|
||||||
<MultiImageUpload v-model="datas.images" />
|
<MultiImageUpload v-model="datas.imgUrls" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="备注" label-width="">
|
<el-form-item label="备注" label-width="">
|
||||||
<el-input v-model="datas.remark" type="textarea" />
|
<el-input v-model="datas.remark" type="textarea" />
|
||||||
@@ -103,7 +116,7 @@
|
|||||||
</el-form>
|
</el-form>
|
||||||
</MyDialog>
|
</MyDialog>
|
||||||
<!-- 耗材绑定 -->
|
<!-- 耗材绑定 -->
|
||||||
<MyDialog ref="myDialogRefhaocai" @confirm="confirmhaocai" width="50%" title="耗材绑定">
|
<MyDialog ref="myDialogRefhaocai" @confirm="confirmhaocai" width="60%" title="耗材绑定">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="商品名">
|
<el-form-item label="商品名">
|
||||||
@@ -121,9 +134,10 @@
|
|||||||
<el-table-column label="序号" type="index" width="60"></el-table-column>
|
<el-table-column label="序号" type="index" width="60"></el-table-column>
|
||||||
<el-table-column label="耗材名称" prop="consInfoId">
|
<el-table-column label="耗材名称" prop="consInfoId">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-select v-model="scope.row.consInfoId" reserve-keyword placeholder="请输入关键词"
|
<el-select filterable v-model="scope.row.consInfoId" reserve-keyword placeholder="请输入关键词"
|
||||||
@change="selectionChange($event, scope.row)">
|
@change="selectionChange($event, scope.row)">
|
||||||
<el-option v-for="item in options" :key="item.id" :label="item.conName" :value="item.id"></el-option>
|
<el-option v-for="item in options" :key="item.id * 1" :label="item.conName"
|
||||||
|
:value="item.id * 1"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<!-- <div class="tips" v-if="scope.row.stockNumber">库存:{{ scope.row.stockNumber }}</div> -->
|
<!-- <div class="tips" v-if="scope.row.stockNumber">库存:{{ scope.row.stockNumber }}</div> -->
|
||||||
</template>
|
</template>
|
||||||
@@ -169,12 +183,45 @@
|
|||||||
<MyDialog ref="myDialogRefkucun" @confirm="confirmkucun" width="30%" title="库存修改">
|
<MyDialog ref="myDialogRefkucun" @confirm="confirmkucun" width="30%" title="库存修改">
|
||||||
<el-input-number v-model="kucundata.stockNumbers" :min="0" />
|
<el-input-number v-model="kucundata.stockNumbers" :min="0" />
|
||||||
</MyDialog>
|
</MyDialog>
|
||||||
|
<!-- 报损记录 -->
|
||||||
|
<MyDialog ref="myDialogRefRecord" :title="dataAll.dataTitle" width="70%" @confirm="myDialogRefRecord.close()">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<Table :list="dataAll.tableData"
|
||||||
|
v-if="dataAll.dataType == 'inSumTotal' || dataAll.dataType == 'winInNum' || dataAll.dataType == 'outSumTotal' || dataAll.dataType == 'lossOutNum'">
|
||||||
|
</Table>
|
||||||
|
<TableTwo :list="dataAll.tableData" v-else-if="dataAll.dataType == 'refundInNum'"></TableTwo>
|
||||||
|
<TableThree :list="dataAll.tableData" v-else-if="dataAll.dataType == 'salesNum'"></TableThree>
|
||||||
|
|
||||||
|
<TableFour :list="dataAll.tableData" v-else-if="dataAll.dataType == 'damageNum'"></TableFour>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Paging :pagingConfig="dataAll.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
|
||||||
|
</MyDialog>
|
||||||
|
<!-- 批量操作更改分类弹窗 -->
|
||||||
|
<el-dialog title="更改分类" width="400px" v-model="visibleBatchOperation" @close="bateOperationForm.categoryId = ''">
|
||||||
|
<el-form ref="bateOperationFormRef" :model="bateOperationForm" :rules="bateOperationFormRules"
|
||||||
|
label-position="right" label-width="120">
|
||||||
|
<el-form-item label="请选择分类" prop="categoryId">
|
||||||
|
<el-select v-model="bateOperationForm.categoryId" placeholder="请选择">
|
||||||
|
<el-option v-for="item in batchOperationCategorys" :key="item.id" :label="item.name"
|
||||||
|
:value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="visibleBatchOperation = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="batchOperationCategoryConfirm" :loading="batchOperationLoading">确
|
||||||
|
定</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import importData from "@/components/importData/index.vue";
|
import importData from "@/components/importData/index.vue";
|
||||||
import UserAPI from "@/api/product/index";
|
import UserAPI from "@/api/product/index";
|
||||||
|
import CategoryAPI from '@/api/product/productclassification'
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import type { IObject, IOperatData } from "@/components/CURD/types";
|
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||||
import usePage from "@/components/CURD/usePage";
|
import usePage from "@/components/CURD/usePage";
|
||||||
@@ -187,6 +234,89 @@ import editModalConfig from "./indexconfig/edit";
|
|||||||
import searchConfig from "./indexconfig/search";
|
import searchConfig from "./indexconfig/search";
|
||||||
import MyDialog from "@/components/mycomponents/myDialog.vue";
|
import MyDialog from "@/components/mycomponents/myDialog.vue";
|
||||||
import Statistics from "./indexconfig/statistics.vue";
|
import Statistics from "./indexconfig/statistics.vue";
|
||||||
|
import TableFour from './indexconfig/TableFour.vue'
|
||||||
|
|
||||||
|
const myDialogRefRecord = ref(null)
|
||||||
|
|
||||||
|
const refoundModeOptions = ref([
|
||||||
|
{ label: "退菜退库存", value: 1 },
|
||||||
|
{ label: "仅退菜不退库存", value: 2 },
|
||||||
|
{ label: "每次询问-退菜后弹窗提示,可手动选择", value: 3 },
|
||||||
|
])
|
||||||
|
|
||||||
|
function returnLabel(value: number) {
|
||||||
|
const option = refoundModeOptions.value.find((option) => option.value == value);
|
||||||
|
return option ? option.label : "未知";
|
||||||
|
}
|
||||||
|
|
||||||
|
let dataAll = reactive({
|
||||||
|
dataList: [],
|
||||||
|
tableData: [],
|
||||||
|
pagingConfig: {
|
||||||
|
total: 0, // 总数
|
||||||
|
pageSize: 10, // 每页数据数量
|
||||||
|
pageNumber: 1, // 当前页码
|
||||||
|
},
|
||||||
|
dataType: "",
|
||||||
|
dataTitle: ""
|
||||||
|
});
|
||||||
|
|
||||||
|
function sizeChange(val) {
|
||||||
|
dataAll.pagingConfig.pageSize = val
|
||||||
|
clickEvent(dataAll.dataType)
|
||||||
|
}
|
||||||
|
function currentChange(val) {
|
||||||
|
dataAll.pagingConfig.pageNumber = val
|
||||||
|
clickEvent(dataAll.dataType)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clickEvent(key) {
|
||||||
|
dataAll.dataType = key
|
||||||
|
let obj = {}
|
||||||
|
switch (key) {
|
||||||
|
case 'inSumTotal':
|
||||||
|
dataAll.dataTitle = '增加数据统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "in", inOutItem: "" }
|
||||||
|
break;
|
||||||
|
case 'winInNum':
|
||||||
|
dataAll.dataTitle = '手动增加统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "in", inOutItem: "win-in" }
|
||||||
|
break;
|
||||||
|
case 'refundInNum':
|
||||||
|
dataAll.dataTitle = '退货统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "in", inOutItem: "order-in" }
|
||||||
|
break;
|
||||||
|
case 'outSumTotal':
|
||||||
|
dataAll.dataTitle = '减少数量统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "out", inOutItem: "" }
|
||||||
|
break;
|
||||||
|
case 'lossOutNum':
|
||||||
|
dataAll.dataTitle = '手动减少统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "out", inOutItem: "loss-out" }
|
||||||
|
break;
|
||||||
|
case 'salesNum':
|
||||||
|
dataAll.dataTitle = '销量统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: "", inOutType: "out", inOutItem: "order-out" }
|
||||||
|
break;
|
||||||
|
case 'damageNum':
|
||||||
|
dataAll.dataTitle = '报损统计'
|
||||||
|
obj = { page: dataAll.pagingConfig.pageNumber, size: dataAll.pagingConfig.pageSize, productId: datas.productId, inOutType: "out", inOutItem: "damage-out" }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dataAll.tableData = []
|
||||||
|
|
||||||
|
let res = await UserAPI.stockFlow(obj);
|
||||||
|
dataAll.tableData = res.records
|
||||||
|
dataAll.tableData.forEach((item, index) => {
|
||||||
|
if (item.imgUrls.length > 7) {
|
||||||
|
item.imagesone = JSON.parse(item.imgUrls)[0]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dataAll.pagingConfig.total = res.totalRow
|
||||||
|
dataAll.pagingConfig.pageSize = res.pageSize
|
||||||
|
dataAll.pagingConfig.pageNumber = res.pageNumber
|
||||||
|
myDialogRefRecord.value.open()
|
||||||
|
}
|
||||||
|
|
||||||
const importDataRef = ref(null);
|
const importDataRef = ref(null);
|
||||||
|
|
||||||
@@ -233,7 +363,7 @@ const form = reactive({
|
|||||||
let datas = reactive({
|
let datas = reactive({
|
||||||
number: 0,
|
number: 0,
|
||||||
remark: "",
|
remark: "",
|
||||||
images: [],
|
imgUrls: [],
|
||||||
productId: null, // Added productId property
|
productId: null, // Added productId property
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -255,8 +385,8 @@ onMounted(async () => {
|
|||||||
// 获取耗材列表
|
// 获取耗材列表
|
||||||
gethaocaiList();
|
gethaocaiList();
|
||||||
|
|
||||||
const res = await UserAPI.getPage()
|
const res = await UserAPI.getPage();
|
||||||
form.warnLine = res.warnLine || ''
|
form.warnLine = res.warnLine || "";
|
||||||
// console.log('contentRef.value===', res);
|
// console.log('contentRef.value===', res);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -310,7 +440,7 @@ function getTongji(params: IObject | undefined) {
|
|||||||
|
|
||||||
// 显示批量导入
|
// 显示批量导入
|
||||||
function handleUploadClick() {
|
function handleUploadClick() {
|
||||||
importDataRef.value.show()
|
importDataRef.value.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出商品
|
// 导出商品
|
||||||
@@ -342,13 +472,25 @@ function createItem(val: IObject) {
|
|||||||
haocaiData.value.consList.push(item);
|
haocaiData.value.consList.push(item);
|
||||||
}
|
}
|
||||||
// 上架
|
// 上架
|
||||||
function handleSwitchChange(data: any) {
|
async function handleSwitchChange(data: any) {
|
||||||
|
console.log(data);
|
||||||
let obj = {
|
let obj = {
|
||||||
type: data.productId ? "sku" : "product",
|
type: data.productId ? "sku" : "product",
|
||||||
id: data.id,
|
id: data.id,
|
||||||
isSale: data.isSale,
|
isSale: data.isSale,
|
||||||
};
|
};
|
||||||
UserAPI.onOff(obj);
|
await UserAPI.onOff(obj);
|
||||||
|
ElMessage.success("修改成功!");
|
||||||
|
|
||||||
|
if (data.productId) {
|
||||||
|
//sku
|
||||||
|
contentRef.value?.fetchPageData();
|
||||||
|
} else {
|
||||||
|
//product
|
||||||
|
data.skuList.map((v) => {
|
||||||
|
v.isSale = data.isSale;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 售罄
|
// 售罄
|
||||||
function handleSwitchChangeTwo(data: any) {
|
function handleSwitchChangeTwo(data: any) {
|
||||||
@@ -358,7 +500,18 @@ function handleSwitchChangeTwo(data: any) {
|
|||||||
isSoldOut: data.isSoldStock,
|
isSoldOut: data.isSoldStock,
|
||||||
};
|
};
|
||||||
UserAPI.markIsSoldOut(obj);
|
UserAPI.markIsSoldOut(obj);
|
||||||
|
ElMessage.success("修改成功!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 自动售罄
|
||||||
|
function handleSwitchChangeTwo2(e: any, data: any) {
|
||||||
|
UserAPI.markIsAutoSoldOut({
|
||||||
|
id: data.id,
|
||||||
|
isAutoSoldStock: data.isAutoSoldStock
|
||||||
|
});
|
||||||
|
ElMessage.success("修改成功!");
|
||||||
|
}
|
||||||
|
|
||||||
function handleSwitchChangethree(data: any) {
|
function handleSwitchChangethree(data: any) {
|
||||||
let obj = {
|
let obj = {
|
||||||
type: data.type == "sku" ? "sku" : "product",
|
type: data.type == "sku" ? "sku" : "product",
|
||||||
@@ -368,6 +521,18 @@ function handleSwitchChangethree(data: any) {
|
|||||||
UserAPI.markIsSoldOut(obj);
|
UserAPI.markIsSoldOut(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function isStockChange(data: any) {
|
||||||
|
console.log(data);
|
||||||
|
let obj = {
|
||||||
|
type: "product",
|
||||||
|
id: data.id,
|
||||||
|
isSale: data.isStock,
|
||||||
|
optType: "stock",
|
||||||
|
};
|
||||||
|
await UserAPI.onOff(obj);
|
||||||
|
ElMessage.success("修改成功!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// 退款退回
|
// 退款退回
|
||||||
async function handleSwitchhaocai(row: IObject) {
|
async function handleSwitchhaocai(row: IObject) {
|
||||||
let res = await UserAPI.refundToStock({ isReturn: row.isRefundStock, id: row.id });
|
let res = await UserAPI.refundToStock({ isReturn: row.isRefundStock, id: row.id });
|
||||||
@@ -398,7 +563,7 @@ async function handleToolbarClick(name: string) {
|
|||||||
ElMessage.success("操作成功,数据正在后台同步中...");
|
ElMessage.success("操作成功,数据正在后台同步中...");
|
||||||
}
|
}
|
||||||
if (name === "upload") {
|
if (name === "upload") {
|
||||||
importDataRef.value.show()
|
importDataRef.value.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function confirm() {
|
async function confirm() {
|
||||||
@@ -423,10 +588,22 @@ async function confirmhaocai() {
|
|||||||
consList: haocaiData.value.consList,
|
consList: haocaiData.value.consList,
|
||||||
id: haocaiData.value.id,
|
id: haocaiData.value.id,
|
||||||
};
|
};
|
||||||
let res = await UserAPI.bind(obj);
|
|
||||||
ElMessage.success("成功");
|
let flag = true
|
||||||
handleResetClick();
|
obj.consList.forEach((el: any) => {
|
||||||
myDialogRefhaocai.value.close();
|
if (el.consInfoId == '') {
|
||||||
|
flag = false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (flag) {
|
||||||
|
let res = await UserAPI.bind(obj);
|
||||||
|
ElMessage.success("成功");
|
||||||
|
handleResetClick();
|
||||||
|
myDialogRefhaocai.value.close();
|
||||||
|
} else {
|
||||||
|
ElMessage.error("请选择耗材");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 商品规格
|
// 商品规格
|
||||||
function typeFilter(item: any) {
|
function typeFilter(item: any) {
|
||||||
@@ -444,17 +621,166 @@ function typeFilter(item: any) {
|
|||||||
}
|
}
|
||||||
// 其他操作列
|
// 其他操作列
|
||||||
async function handleOperatClick(data: IOperatData) {
|
async function handleOperatClick(data: IOperatData) {
|
||||||
|
console.log(data);
|
||||||
datas.productId = data.row.id;
|
datas.productId = data.row.id;
|
||||||
myDialogRefbaosun.value.open();
|
switch (data.name) {
|
||||||
datas.number = 1;
|
case 'cons':
|
||||||
datas.remark = "";
|
myDialogRefbaosun.value.open();
|
||||||
|
datas.number = 1;
|
||||||
|
datas.remark = "";
|
||||||
|
break;
|
||||||
|
case 'consRecord':
|
||||||
|
clickEvent('damageNum')
|
||||||
|
// myDialogRefRecord.value.open()
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gethaocaiList() {
|
async function gethaocaiList() {
|
||||||
let res = await UserAPI.productcons({ id: route.query.id });
|
let res = await UserAPI.productconsList({ id: route.query.id });
|
||||||
options.value = res.records;
|
options.value = res || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const batchOperationList = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
value: '1',
|
||||||
|
type: 'isSale',
|
||||||
|
lable: '批量上架'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
value: '0',
|
||||||
|
type: 'isSale',
|
||||||
|
lable: '批量下架'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
type: 'category',
|
||||||
|
lable: '批量更改商品分类'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
value: '1',
|
||||||
|
type: 'is_sold_stock',
|
||||||
|
lable: '批量售罄'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
value: '0',
|
||||||
|
type: 'is_sold_stock',
|
||||||
|
lable: '批量取消售罄'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
value: '1',
|
||||||
|
type: 'isAutoSoldStock',
|
||||||
|
lable: '批量自动售罄'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
value: '0',
|
||||||
|
type: 'isAutoSoldStock',
|
||||||
|
lable: '批量取消自动售罄'
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
function handleSelectionChange(rows) {
|
||||||
|
// console.log('handleSelectionChange', rows);
|
||||||
|
batchOperationSelectRows.value = rows
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择批量操作项目
|
||||||
|
const batchOperationValue = ref('')
|
||||||
|
const batchOperationSelectItem = ref('')
|
||||||
|
const batchOperationSelectRows = ref([])
|
||||||
|
function batchOperationChange(e: any) {
|
||||||
|
if (batchOperationSelectRows.value.length == 0) {
|
||||||
|
ElMessage.error('请选择商品')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
batchOperationSelectItem.value = batchOperationList.value.find(item => item.id == e)
|
||||||
|
if (batchOperationSelectItem.value.type == 'category') {
|
||||||
|
visibleBatchOperation.value = true
|
||||||
|
} else {
|
||||||
|
ElMessageBox.confirm(`是否确认对勾选商品执行「${batchOperationSelectItem.value.lable}」操作,操作不可撤销`, '提示').then(() => {
|
||||||
|
batchOperationConfirm()
|
||||||
|
}).catch(() => { })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认最后的操作
|
||||||
|
async function batchOperationConfirm() {
|
||||||
|
try {
|
||||||
|
const ids = batchOperationSelectRows.value.map(item => item.id)
|
||||||
|
let value = ''
|
||||||
|
if (batchOperationSelectItem.value.type == 'category') {
|
||||||
|
value = bateOperationForm.value.categoryId
|
||||||
|
} else {
|
||||||
|
value = batchOperationSelectItem.value.value
|
||||||
|
}
|
||||||
|
await UserAPI.batchOperate({
|
||||||
|
ids: ids.join(','), // 商品id集合
|
||||||
|
type: batchOperationSelectItem.value.type, // 操作类型
|
||||||
|
value: value, // 操作之,除分类外取value
|
||||||
|
})
|
||||||
|
newHandleQueryClick()
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const batchOperationCategorys = ref([])
|
||||||
|
const visibleBatchOperation = ref(false)
|
||||||
|
const batchOperationLoading = ref(false)
|
||||||
|
const bateOperationFormRef = ref(null)
|
||||||
|
const bateOperationForm = ref({
|
||||||
|
categoryId: ''
|
||||||
|
})
|
||||||
|
const bateOperationFormRules = ref({
|
||||||
|
categoryId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请选择分类',
|
||||||
|
blur: 'trigger'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 批量操作更改分类
|
||||||
|
function batchOperationCategoryConfirm() {
|
||||||
|
bateOperationFormRef.value.validate(async vaild => {
|
||||||
|
if (vaild) {
|
||||||
|
batchOperationLoading.value = true
|
||||||
|
await batchOperationConfirm()
|
||||||
|
batchOperationLoading.value = false
|
||||||
|
visibleBatchOperation.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商品分类
|
||||||
|
async function getCategorys() {
|
||||||
|
try {
|
||||||
|
batchOperationCategorys.value = await CategoryAPI.getList()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCategorys()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
/* 关键:隐藏子行的选择框 */
|
||||||
|
.el-table__row--level-1 .el-checkbox {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.table_btn_wrap {
|
.table_btn_wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<div style="margin-top: 10px;">
|
<div style="margin-top: 10px;">
|
||||||
<el-table :data="props.list" border style="">
|
<el-table :data="props.list" border style="">
|
||||||
<el-table-column prop="productName" align="center" label="商品名称/规格名称" />
|
<el-table-column prop="productName" align="center" label="商品名称/规格名称" />
|
||||||
<el-table-column prop="beforeNumber" align="center" label="原库存" />
|
<!-- <el-table-column prop="beforeNumber" align="center" label="原库存" />
|
||||||
<el-table-column prop="afterNumber" align="center" label="变动后库存" />
|
<el-table-column prop="afterNumber" align="center" label="变动后库存" /> -->
|
||||||
<el-table-column prop="inOutNumber" align="center" label="报损数量" />
|
<el-table-column prop="inOutNumber" align="center" label="报损数量" />
|
||||||
<el-table-column prop="createUserName" align="center" label="报损人" />
|
<el-table-column prop="createUserName" align="center" label="报损人" />
|
||||||
<el-table-column prop="remark" align="center" label="备注" />
|
<el-table-column prop="remark" align="center" label="备注" />
|
||||||
|
|||||||
@@ -1,185 +1,201 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="addgoods">
|
<div class="addgoods">
|
||||||
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="150px" class="demo-ruleForm" status-icon>
|
<div class="form_wrap">
|
||||||
<el-form-item label="商品名称" required>
|
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="150px" class="demo-ruleForm" status-icon>
|
||||||
<el-col :span="12">
|
<el-steps :active="stepsActiveName" finish-status="success" simple>
|
||||||
<el-form-item prop="name">
|
<el-step title="基础信息" />
|
||||||
<el-input v-model="ruleForm.name" placeholder="请输入商品名称" :disabled="isSyncStatus()" />
|
<el-step title="耗材设置/关联推荐商品" />
|
||||||
</el-form-item>
|
</el-steps>
|
||||||
</el-col>
|
<div style="padding-top: 20px;">
|
||||||
</el-form-item>
|
<!-- 基础信息 -->
|
||||||
<el-form-item label="商品介绍">
|
<div v-show="stepsActiveName == 0">
|
||||||
<el-col :span="12">
|
<el-form-item label="商品名称" required>
|
||||||
<el-form-item>
|
<el-col :span="12">
|
||||||
<el-input v-model="ruleForm.shortTitle" type="textarea" placeholder="请输入商品介绍" :disabled="isSyncStatus()" />
|
<el-form-item prop="name">
|
||||||
</el-form-item>
|
<el-input v-model="ruleForm.name" placeholder="请输入商品名称" :disabled="isSyncStatus()" />
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="单位" required>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="unitId">
|
|
||||||
<el-select v-model="ruleForm.unitId" placeholder="请选择单位" :disabled="isSyncStatus()">
|
|
||||||
<el-option :label="item.name" :value="item.id" v-for="item in datas.Company" :key="item.id" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="商品分类" required>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item prop="region">
|
|
||||||
<el-select v-model="ruleForm.categoryId" placeholder="请选择商品分类" :disabled="isSyncStatus()">
|
|
||||||
<el-option :label="item.name" :value="item.id" v-for="item in datas.classification" :key="item.id" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- <el-form-item label="商品图片" required prop="images">
|
|
||||||
<MultiImageUpload v-model="ruleForm.images" />
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="商品图片" required prop="images">
|
|
||||||
<div style="display: flex; flex-wrap: wrap">
|
|
||||||
<div v-for="(item, index) in ruleForm.images" :key="index" style="position: relative" class="showStyle">
|
|
||||||
<el-icon class="buttonstyle" @click="deleteEvent(item)">
|
|
||||||
<DeleteFilled />
|
|
||||||
</el-icon>
|
|
||||||
<img style="width: 148px; height: 148px; margin-right: 6px" class="imgStyle" :src="item" alt="" />
|
|
||||||
</div>
|
|
||||||
<div class="upImgStyle" @click="addimgEvent">+</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<div class="tips">注:第一张图为商品封面图,图片尺寸为750×750</div>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 选择图片 -->
|
|
||||||
<AddImg ref="addImg" @successEvent="successEvent"></AddImg>
|
|
||||||
|
|
||||||
<el-form-item label="商品类型">
|
|
||||||
<el-radio-group v-model="ruleForm.type" @change="changeTypeEnum(ruleForm.type)" :disabled="isSyncStatus()">
|
|
||||||
<el-radio value="single">单规格商品</el-radio>
|
|
||||||
<el-radio value="sku">多规格商品</el-radio>
|
|
||||||
<el-radio value="package">套餐商品</el-radio>
|
|
||||||
<el-radio value="weight">称重商品</el-radio>
|
|
||||||
<!-- <el-radio label="coupon">团购券</el-radio> -->
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="套餐商品" v-if="ruleForm.type == 'package'">
|
|
||||||
<div style="display: block; width: 100%">
|
|
||||||
<div class="head-container">
|
|
||||||
<el-radio-group v-model="ruleForm.groupType" @change="typeChange">
|
|
||||||
<el-radio-button :label="0">固定套餐</el-radio-button>
|
|
||||||
<el-radio-button :label="1">可选套餐</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<div v-if="ruleForm.groupType == 0">
|
|
||||||
<el-table border :data="item.goods" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
|
|
||||||
<el-table-column label="名称" prop="proName"></el-table-column>
|
|
||||||
<el-table-column label="规格" prop="skuName"></el-table-column>
|
|
||||||
<el-table-column label="价格" prop="price"></el-table-column>
|
|
||||||
<el-table-column label="数量" prop="number">
|
|
||||||
<template v-slot="scope">
|
|
||||||
<el-input-number v-model="scope.row.number" :min="0" />
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column width="150">
|
|
||||||
<template #header>
|
|
||||||
<el-button type="primary" @click="addgoods(-1)" :disabled="isSyncStatus()">
|
|
||||||
添加商品
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
<template v-slot="scope">
|
|
||||||
<el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
|
|
||||||
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
|
|
||||||
<el-button type="text"
|
|
||||||
@click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)">删除</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<div v-if="ruleForm.groupType == 1">
|
|
||||||
<div class="group_wrap" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
|
|
||||||
<el-form inline :model="item">
|
|
||||||
<el-form-item label="规格组名">
|
|
||||||
<el-input v-model="item.title" :disabled="isSyncStatus()" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="`本组菜品${item.goods.length}选`">
|
|
||||||
<el-input v-model="item.number" :disabled="isSyncStatus()" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="商品介绍">
|
||||||
|
<el-col :span="12">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="ruleForm.proGroupVo.splice(index, 1)" :disabled="isSyncStatus()">
|
<el-input v-model="ruleForm.shortTitle" type="textarea" placeholder="请输入商品介绍"
|
||||||
删除
|
:disabled="isSyncStatus()" />
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-col>
|
||||||
<div style="margin-top: 20px">
|
</el-form-item>
|
||||||
<el-table border :data="item.goods">
|
<el-form-item label="单位" required prop="unitId">
|
||||||
<el-table-column label="名称" prop="proName"></el-table-column>
|
<el-select v-model="ruleForm.unitId" placeholder="请选择单位" :disabled="isSyncStatus()" style="width: 330px;">
|
||||||
<el-table-column label="规格" prop="skuName"></el-table-column>
|
<el-option :label="item.name" :value="item.id" v-for="item in datas.Company" :key="item.id" />
|
||||||
<el-table-column label="价格" prop="price"></el-table-column>
|
</el-select>
|
||||||
<el-table-column label="数量" prop="number">
|
<el-button type="primary" icon="Plus" style="margin-left: 14px;"
|
||||||
<template v-slot="scope">
|
@click="addUnitRef.open()">添加单位</el-button>
|
||||||
<el-input-number v-model="scope.row.number" :min="0" :disabled="isSyncStatus()" />
|
</el-form-item>
|
||||||
</template>
|
<el-form-item label="商品分类" required prop="categoryId">
|
||||||
</el-table-column>
|
<el-select v-model="ruleForm.categoryId" placeholder="请选择商品分类" :disabled="isSyncStatus()"
|
||||||
<el-table-column width="150">
|
style="width: 330px;">
|
||||||
<template #header>
|
<el-option :label="item.name" :value="item.id" v-for="item in datas.classification" :key="item.id" />
|
||||||
<el-button type="primary" @click="addgoods(index)" :disabled="isSyncStatus()">
|
</el-select>
|
||||||
添加商品
|
<el-button type="primary" icon="Plus" style="margin-left: 14px;"
|
||||||
</el-button>
|
@click="addCategoryRef.open()">添加分类</el-button>
|
||||||
</template>
|
</el-form-item>
|
||||||
<template v-slot="scope">
|
<el-form-item label="商品分组">
|
||||||
<el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
|
<el-select v-model="ruleForm.proGroupIds" multiple placeholder="请选择商品分组" style="width: 330px;">
|
||||||
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
|
<el-option :label="item.name" :value="item.id" v-for="item in goodsGroupList" :key="item.id" />
|
||||||
<el-button type="text" @click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)"
|
</el-select>
|
||||||
:disabled="isSyncStatus()">删除</el-button>
|
<el-button type="primary" icon="Plus" style="margin-left: 14px;"
|
||||||
</template>
|
@click="addGoodsGroupRef.open()">添加分组</el-button>
|
||||||
</el-table-column>
|
</el-form-item>
|
||||||
</el-table>
|
<!-- <el-form-item label="商品图片" required prop="images">
|
||||||
|
<MultiImageUpload v-model="ruleForm.images" />
|
||||||
|
</el-form-item> -->
|
||||||
|
<el-form-item label="商品图片" required prop="images">
|
||||||
|
<div style="display: flex; flex-wrap: wrap">
|
||||||
|
<div v-for="(item, index) in ruleForm.images" :key="index" style="position: relative" class="showStyle">
|
||||||
|
<el-icon class="buttonstyle" @click="deleteEvent(item)">
|
||||||
|
<DeleteFilled />
|
||||||
|
</el-icon>
|
||||||
|
<img style="width: 148px; height: 148px; margin-right: 6px" class="imgStyle" :src="item" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="upImgStyle" @click="addimgEvent">+</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</el-form-item>
|
||||||
<el-button type="primary" @click="addtaocan" :disabled="isSyncStatus()">
|
<el-form-item>
|
||||||
添加套餐组
|
<div class="tips">注:第一张图为商品封面图,图片尺寸为750×750</div>
|
||||||
</el-button>
|
</el-form-item>
|
||||||
</div>
|
<!-- 选择图片 -->
|
||||||
</div>
|
<AddImg ref="addImg" @successEvent="successEvent"></AddImg>
|
||||||
</el-form-item>
|
<el-form-item label="商品类型">
|
||||||
<el-form-item label="选择规格" v-if="ruleForm.type == 'sku'">
|
<el-radio-group v-model="ruleForm.type" @change="changeTypeEnum(ruleForm.type)"
|
||||||
<el-select v-model="ruleForm.specId" placeholder="请选择规格" style="width: 500px" @change="selectSpecHandle"
|
:disabled="isSyncStatus()">
|
||||||
:disabled="isSyncStatus()">
|
<el-radio value="single">单规格商品</el-radio>
|
||||||
<el-option :label="item.name" :value="item.id" v-for="item in datas.specificationsconfig"
|
<el-radio value="sku">多规格商品</el-radio>
|
||||||
:key="item.id"></el-option>
|
<el-radio value="package">套餐商品</el-radio>
|
||||||
</el-select>
|
<el-radio value="weight">称重商品</el-radio>
|
||||||
</el-form-item>
|
<!-- <el-radio label="coupon">团购券</el-radio> -->
|
||||||
<el-form-item :label="ele.name" v-if="datas.selectSpeclist.length" v-for="ele in datas.selectSpeclist"
|
</el-radio-group>
|
||||||
:key="ele.name">
|
</el-form-item>
|
||||||
<el-checkbox-group v-model="ele.selectSpecResult" @change="selectSpecResultChange">
|
<el-form-item label="套餐商品" v-if="ruleForm.type == 'package'">
|
||||||
<el-checkbox :value="element.name" :label="element.name" v-for="(element, index) in ele.children"
|
<div style="display: block; width: 100%">
|
||||||
:key="index"></el-checkbox>
|
<div class="head-container">
|
||||||
</el-checkbox-group>
|
<el-radio-group v-model="ruleForm.groupType" @change="typeChange">
|
||||||
</el-form-item>
|
<el-radio-button :label="0">固定套餐</el-radio-button>
|
||||||
<!-- 规格属性 -->
|
<el-radio-button :label="1">可选套餐</el-radio-button>
|
||||||
<!-- 单规格、称重 -->
|
</el-radio-group>
|
||||||
<SpecificationAttribute v-if="ruleForm.type != 'sku'" :info="ruleForm" :list="list"
|
</div>
|
||||||
ref="specificationAttributeRef">
|
<div v-if="ruleForm.groupType == 0">
|
||||||
</SpecificationAttribute>
|
<el-table border :data="item.goods" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
|
||||||
<SpecificationAttribute v-if="ruleForm.type == 'sku' && list.length" :specTableHeaders="datas.specTableHeaders"
|
<el-table-column label="名称" prop="proName"></el-table-column>
|
||||||
:info="ruleForm" :list="list" ref="specificationAttributeRef"></SpecificationAttribute>
|
<el-table-column label="规格" prop="skuName"></el-table-column>
|
||||||
<el-form-item label="重量">
|
<el-table-column label="价格" prop="price"></el-table-column>
|
||||||
<el-col :span="12">
|
<el-table-column label="数量" prop="number">
|
||||||
<div style="display: block">
|
<template v-slot="scope">
|
||||||
<el-input v-model="ruleForm.weight" placeholder="" :disabled="isSyncStatus()">
|
<el-input-number v-model="scope.row.number" :min="0" />
|
||||||
<template #append>千克</template>
|
</template>
|
||||||
</el-input>
|
</el-table-column>
|
||||||
<!-- <div style="color: #999;">用于快递或配送运费计重</div> -->
|
<el-table-column width="150">
|
||||||
</div>
|
<template #header>
|
||||||
</el-col>
|
<el-button type="primary" @click="addgoods(-1)" :disabled="isSyncStatus()">
|
||||||
</el-form-item>
|
添加商品
|
||||||
<el-form-item label="是否允许临时改价">
|
</el-button>
|
||||||
<el-radio-group v-model="ruleForm.isAllowTempModifyPrice" :disabled="isSyncStatus()">
|
</template>
|
||||||
<el-radio :value="1">允许</el-radio>
|
<template v-slot="scope">
|
||||||
<el-radio :value="0">不允许</el-radio>
|
<el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
|
||||||
</el-radio-group>
|
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
|
||||||
</el-form-item>
|
<el-button type="text"
|
||||||
<!-- <el-form-item label="每日销量上限">
|
@click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<div v-if="ruleForm.groupType == 1">
|
||||||
|
<div class="group_wrap" v-for="(item, index) in ruleForm.proGroupVo" :key="index">
|
||||||
|
<el-form inline :model="item">
|
||||||
|
<el-form-item label="规格组名">
|
||||||
|
<el-input v-model="item.title" :disabled="isSyncStatus()" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="`本组菜品${item.goods.length}选`">
|
||||||
|
<el-input v-model="item.number" :disabled="isSyncStatus()" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="ruleForm.proGroupVo.splice(index, 1)" :disabled="isSyncStatus()">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div style="margin-top: 20px">
|
||||||
|
<el-table border :data="item.goods">
|
||||||
|
<el-table-column label="名称" prop="proName"></el-table-column>
|
||||||
|
<el-table-column label="规格" prop="skuName"></el-table-column>
|
||||||
|
<el-table-column label="价格" prop="price"></el-table-column>
|
||||||
|
<el-table-column label="数量" prop="number">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-input-number v-model="scope.row.number" :min="0" :disabled="isSyncStatus()" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column width="150">
|
||||||
|
<template #header>
|
||||||
|
<el-button type="primary" @click="addgoods(index)" :disabled="isSyncStatus()">
|
||||||
|
添加商品
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button type="text" :disabled="scope.row.type != 'sku' && isSyncStatus()"
|
||||||
|
@click="showSelectSkuHandle(scope.row, scope.$index, index)">设置规格</el-button>
|
||||||
|
<el-button type="text" @click="ruleForm.proGroupVo[index].goods.splice(scope.$index, 1)"
|
||||||
|
:disabled="isSyncStatus()">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="addtaocan" :disabled="isSyncStatus()">
|
||||||
|
添加套餐组
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="选择规格" v-if="ruleForm.type == 'sku'">
|
||||||
|
<div class="center">
|
||||||
|
<el-select v-model="ruleForm.specId" placeholder="请选择规格" style="width: 500px" @change="selectSpecHandle"
|
||||||
|
:disabled="isSyncStatus()">
|
||||||
|
<el-option :label="item.name" :value="item.id" v-for="item in datas.specificationsconfig"
|
||||||
|
:key="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" icon="Plus" style="margin-left: 14px;"
|
||||||
|
@click="addSkuModalRef?.open()">添加规格</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="ele.name" v-if="datas.selectSpeclist.length" v-for="ele in datas.selectSpeclist"
|
||||||
|
:key="ele.name">
|
||||||
|
<el-checkbox-group v-model="ele.selectSpecResult" @change="selectSpecResultChange">
|
||||||
|
<el-checkbox :value="element.name" :label="element.name" v-for="(element, index) in ele.children"
|
||||||
|
:key="index"></el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 规格属性 -->
|
||||||
|
<!-- 单规格、称重 -->
|
||||||
|
<SpecificationAttribute v-if="ruleForm.type != 'sku'" :info="ruleForm" :list="list"
|
||||||
|
ref="specificationAttributeRef">
|
||||||
|
</SpecificationAttribute>
|
||||||
|
<SpecificationAttribute v-if="ruleForm.type == 'sku' && list.length"
|
||||||
|
:specTableHeaders="datas.specTableHeaders" :info="ruleForm" :list="list" ref="specificationAttributeRef">
|
||||||
|
</SpecificationAttribute>
|
||||||
|
<el-form-item label="重量" v-if="ruleForm.type == 'weight'">
|
||||||
|
<el-col :span="12">
|
||||||
|
<div style="display: block">
|
||||||
|
<el-input v-model="ruleForm.weight" placeholder="纯文本描述"></el-input>
|
||||||
|
<!-- <div style="color: #999;">用于快递或配送运费计重</div> -->
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否允许临时改价">
|
||||||
|
<el-radio-group v-model="ruleForm.isAllowTempModifyPrice" :disabled="isSyncStatus()">
|
||||||
|
<el-radio :value="1">允许</el-radio>
|
||||||
|
<el-radio :value="0">不允许</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="每日销量上限">
|
||||||
<el-input-number v-model="ruleForm.dayLimit" :min="0" />
|
<el-input-number v-model="ruleForm.dayLimit" :min="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="每单限购">
|
<el-form-item label="每单限购">
|
||||||
@@ -188,90 +204,182 @@
|
|||||||
<el-form-item label="每人限购">
|
<el-form-item label="每人限购">
|
||||||
<el-input-number v-model="ruleForm.dayLimit" :min="0" />
|
<el-input-number v-model="ruleForm.dayLimit" :min="0" />
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="定时上下架">
|
<el-form-item label="售卖时间">
|
||||||
<el-checkbox-group v-model="ruleForm.days">
|
<el-checkbox-group v-model="ruleForm.days">
|
||||||
<el-checkbox v-for="(item, index) in datas.cycle" :key="item.value" :value="item.value">
|
<el-checkbox v-for="(item, index) in datas.cycle" :key="item.value" :value="item.value">
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-col :span="20">
|
<el-col :span="20">
|
||||||
<!-- <el-time-picker v-model="ruleForm.useTime" is-range range-separator="至" start-placeholder="开始时间"
|
<!-- <el-time-picker v-model="ruleForm.useTime" is-range range-separator="至" start-placeholder="开始时间"
|
||||||
end-placeholder="结束时间" value-format="HH:mm:ss" format="HH:mm:ss" />
|
end-placeholder="结束时间" value-format="HH:mm:ss" format="HH:mm:ss" />
|
||||||
-->
|
-->
|
||||||
|
<el-time-picker v-model="ruleForm.startTime" value-format="HH:mm:ss" format="HH:mm:ss"
|
||||||
<el-time-picker v-model="ruleForm.startTime" value-format="HH:mm:ss" format="HH:mm:ss" placeholder="选择开始时间">
|
placeholder="选择开始时间">
|
||||||
</el-time-picker>-
|
</el-time-picker> <el-text type="info">-</el-text> <el-time-picker v-model="ruleForm.endTime"
|
||||||
<el-time-picker v-model="ruleForm.endTime" value-format="HH:mm:ss" format="HH:mm:ss" placeholder="选择结束时间">
|
value-format="HH:mm:ss" format="HH:mm:ss" placeholder="选择结束时间">
|
||||||
</el-time-picker>
|
</el-time-picker>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="上架">
|
<el-form-item label="上架">
|
||||||
<el-switch v-model="ruleForm.isSale" :active-value="1" :inactive-value="0" />
|
<el-switch v-model="ruleForm.isSale" :active-value="1" :inactive-value="0" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="库存开关">
|
<!-- <el-form-item label="库存开关">
|
||||||
<div style="display: block;">
|
<div style="display: block;">
|
||||||
<el-switch v-model="ruleForm.isStock" :active-value="1" :inactive-value="0" :disabled="isSyncStatus()" />
|
<el-switch v-model="ruleForm.isStock" :active-value="1" :inactive-value="0" :disabled="isSyncStatus()" />
|
||||||
<div style="color: #999;">注:关闭则不计算出库数据</div>
|
<div style="color: #999;">注:关闭则不计算出库数据</div>
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="设为推荐" prop="delivery">
|
|
||||||
<el-switch v-model="ruleForm.isHot" :active-value="1" :inactive-value="0" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="库存数量">
|
|
||||||
<el-input-number v-model="ruleForm.stockNumber" :min="0" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="打包费" prop="delivery">
|
|
||||||
<div style="display: block;">
|
|
||||||
<el-input-number v-model="ruleForm.packFee" controls-position="right"
|
|
||||||
:disabled="isSyncStatus()"></el-input-number>
|
|
||||||
<div style="color: #999;">单份商品打包费。注:店铺开启外卖模式下该数据才生效</div>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="关联推荐商品">
|
|
||||||
<div class="column">
|
|
||||||
<div class="row">
|
|
||||||
<div class="center">
|
|
||||||
<el-button type="primary" @click="selecProductDialogRef?.show()"
|
|
||||||
:disabled="ruleForm.relatedRecommendJson.length >= goodsListMax">添加商品</el-button>
|
|
||||||
<div class="tips">设置商品后,用户可以在商品详情页中看到推荐商品可拖动调整顺序,最多设置{{ goodsListMax }}个商品</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
</el-form-item> -->
|
||||||
<div id="goods_table_drag">
|
<el-form-item label="设为推荐" prop="delivery">
|
||||||
<el-table :data="ruleForm.relatedRecommendJson" border stripe style="width: 500px;" row-key="id">
|
<div class="center">
|
||||||
<!-- 拖拽列 -->
|
<el-switch v-model="ruleForm.isHot" :active-value="1" :inactive-value="0" />
|
||||||
<el-table-column label="排序" width="60">
|
<el-text>推荐后,商品会展示在用户小程序端热销模块内</el-text>
|
||||||
<template v-slot="scope">
|
</div>
|
||||||
<div class="drag-handle">☰</div>
|
</el-form-item>
|
||||||
</template>
|
<!-- <el-form-item label="库存数量">
|
||||||
</el-table-column>
|
<el-input-number v-model="ruleForm.stockNumber" :min="0" />
|
||||||
<el-table-column label="商品图片" prop="coverImg" width="90">
|
</el-form-item> -->
|
||||||
<template v-slot="scope">
|
<el-form-item label="打包费" prop="delivery">
|
||||||
<el-image :src="scope.row.coverImg" style="width: 50px;height: 50px;border-radius: 4px;"
|
<div style="display: block;">
|
||||||
fit="cover"></el-image>
|
<el-input-number v-model="ruleForm.packFee" controls-position="right"
|
||||||
</template>
|
:disabled="isSyncStatus()"></el-input-number>
|
||||||
</el-table-column>
|
<div style="color: #999;">单份商品打包费。注:店铺开启外卖模式下该数据才生效</div>
|
||||||
<el-table-column label="商品名称" prop="name"></el-table-column>
|
</div>
|
||||||
<el-table-column label="操作" width="100">
|
</el-form-item>
|
||||||
<template v-slot="scope">
|
</div>
|
||||||
<el-button link type="danger"
|
<!-- 耗材设置 -->
|
||||||
@click="ruleForm.relatedRecommendJson.splice(scope.$index, 1)">删除</el-button>
|
<div v-show="stepsActiveName == 1">
|
||||||
</template>
|
<el-tabs v-model="tabsActiveName">
|
||||||
</el-table-column>
|
<el-tab-pane label="耗材设置" :name="1">
|
||||||
</el-table>
|
<el-form-item label="耗材列表">
|
||||||
</div>
|
<el-table :data="ruleForm.consList" border>
|
||||||
|
<el-table-column label="序号" type="index" width="60"></el-table-column>
|
||||||
|
<el-table-column label="耗材名称" prop="consInfoId">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-select filterable v-model="scope.row.consInfoId" reserve-keyword placeholder="请输入关键词"
|
||||||
|
@change="selectionChange($event, scope.row)">
|
||||||
|
<el-option v-for="item in consOptions" :key="item.id" :label="item.conName"
|
||||||
|
:value="item.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<!-- <div class="tips" v-if="scope.row.stockNumber">库存:{{ scope.row.stockNumber }}</div> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="单位" prop="conUnit">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-input v-model="scope.row.conUnit" readonly disabled placeholder="请选择耗材"></el-input>
|
||||||
|
<!-- <el-select v-model="scope.row.conUnit" reserve-keyword placeholder="请输入关键词">
|
||||||
|
<el-option
|
||||||
|
v-for="item in returnConUnits(scope.row.consInfoId)"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"
|
||||||
|
></el-option>
|
||||||
|
</el-select> -->
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="使用数量" prop="surplusStock" min-width="150px">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-input-number v-model="scope.row.surplusStock" :min="0" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="100">
|
||||||
|
<template #header>
|
||||||
|
<el-button type="primary" size="small" @click="createItem">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template v-slot="scope">
|
||||||
|
<div class="table_btn_wrap">
|
||||||
|
<div class="btn sub" @click="ruleForm.consList.splice(scope.$index, 1)">
|
||||||
|
<el-icon>
|
||||||
|
<RemoveFilled />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="btn add" v-if="scope.$index == ruleForm.consList.length - 1"
|
||||||
|
@click="createItem(scope.row)">
|
||||||
|
<el-icon>
|
||||||
|
<CirclePlusFilled />
|
||||||
|
</el-icon>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="自动售罄">
|
||||||
|
<div class="center">
|
||||||
|
<el-switch v-model="ruleForm.isAutoSoldStock" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
<el-text type="info">当绑定的任何一种耗材库存不足时,商品自动售罄</el-text>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退菜是否退库存">
|
||||||
|
<div class="column">
|
||||||
|
<div>
|
||||||
|
<el-radio-group v-model="ruleForm.refundMode">
|
||||||
|
<el-radio label="退菜退库存" :value="1"></el-radio>
|
||||||
|
<el-radio label="仅退菜不退库存" :value="2"></el-radio>
|
||||||
|
<el-radio label="每次询问-退菜后弹窗提示,可手动选择" :value="3"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-text type="danger">当前店铺退菜退库存规则:{{ shopInfoTypeFilter(shopInfo.refundMode) }}</el-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="关联商品设置" :name="2">
|
||||||
|
<el-form-item label="关联商品设置">
|
||||||
|
<div class="column">
|
||||||
|
<div class="row">
|
||||||
|
<div class="center">
|
||||||
|
<el-button type="primary" @click="selecProductDialogRef?.show()"
|
||||||
|
:disabled="ruleForm.relatedRecommendJson.length >= goodsListMax">添加商品</el-button>
|
||||||
|
<div class="tips">设置商品后,用户可以在商品详情页中看到推荐商品可拖动调整顺序,最多设置{{ goodsListMax }}个商品</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div id="goods_table_drag">
|
||||||
|
<el-table :data="ruleForm.relatedRecommendJson" border stripe row-key="id">
|
||||||
|
<!-- 拖拽列 -->
|
||||||
|
<el-table-column label="排序" width="60">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<div class="drag-handle">☰</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品图片" prop="coverImg" width="90">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-image :src="scope.row.coverImg" style="width: 50px;height: 50px;border-radius: 4px;"
|
||||||
|
fit="cover"></el-image>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品名称" prop="name"></el-table-column>
|
||||||
|
<el-table-column label="操作" width="100">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button link type="danger"
|
||||||
|
@click="ruleForm.relatedRecommendJson.splice(scope.$index, 1)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
<el-form-item>
|
||||||
<el-form-item>
|
<el-button type="primary" @click="nextStep" v-if="stepsActiveName == 0">下一步</el-button>
|
||||||
<el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
|
<el-button type="primary" @click="submitForm(ruleFormRef)" v-if="stepsActiveName == 1">保存</el-button>
|
||||||
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
|
<el-button @click="resetForm(ruleFormRef)" v-if="stepsActiveName == 0">取消</el-button>
|
||||||
</el-form-item>
|
<el-button @click="stepsActiveName = 0" v-if="stepsActiveName != 0">上一步</el-button>
|
||||||
</el-form>
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
<!-- 选择商品 -->
|
<!-- 选择商品 -->
|
||||||
<shopList ref="shopListRef" @success="selectShopRes" />
|
<!-- <shopList ref="shopListRef" @success="selectShopRes" /> -->
|
||||||
|
<GoodsSelect ref="shopListRef" @success="selectShopRes" />
|
||||||
|
|
||||||
<el-dialog :title="datas.selectSkuItem.proName" v-model="datas.showSelectSku">
|
<el-dialog :title="datas.selectSkuItem.proName" v-model="datas.showSelectSku">
|
||||||
<div class="pro_sku">
|
<div class="pro_sku">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
@@ -293,6 +401,14 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 选择商品弹窗 -->
|
<!-- 选择商品弹窗 -->
|
||||||
<selecProductDialog ref="selecProductDialogRef" @success="selecProductSuccess" />
|
<selecProductDialog ref="selecProductDialogRef" @success="selecProductSuccess" />
|
||||||
|
<!-- 添加单位 -->
|
||||||
|
<addUnit ref="addUnitRef" @success="getList" />
|
||||||
|
<!-- 添加商品分类 -->
|
||||||
|
<addCategory ref="addCategoryRef" @success="getList" />
|
||||||
|
<!-- 添加商品分组 -->
|
||||||
|
<addGoodsGroup ref="addGoodsGroupRef" @success="getGoodsGroupList" />
|
||||||
|
<!-- 添加规格 -->
|
||||||
|
<addSkuModal ref="addSkuModalRef" @success="tbProductSpecGet" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -306,17 +422,108 @@ import UserAPI from "@/api/product/productclassification";
|
|||||||
import UserAPI2 from "@/api/product/commonUnits";
|
import UserAPI2 from "@/api/product/commonUnits";
|
||||||
import UserAPI3 from "@/api/product/index";
|
import UserAPI3 from "@/api/product/index";
|
||||||
import UserAPI4 from "@/api/product/specificationsconfig";
|
import UserAPI4 from "@/api/product/specificationsconfig";
|
||||||
|
import GoodsGroupAPI from "@/api/onlineShop/goodsGroupconfig";
|
||||||
import shopList from "@/components/mycomponents/shopList.vue";
|
import shopList from "@/components/mycomponents/shopList.vue";
|
||||||
import AddImg from "@/components/mycomponents/addImg.vue";
|
import AddImg from "@/components/mycomponents/addImg.vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import Sortable from "sortablejs";
|
import Sortable from "sortablejs";
|
||||||
import { useTagsViewStore } from "@/store";
|
import { useTagsViewStore } from "@/store";
|
||||||
import selecProductDialog from "@/views/marketing_center/group_booking/components/selecProductDialog.vue";
|
import selecProductDialog from "@/views/marketing_center/group_booking/components/selecProductDialog.vue";
|
||||||
|
import addUnit from "../components/addUnit.vue";
|
||||||
|
import addCategory from "../components/addCategory.vue";
|
||||||
|
import addGoodsGroup from "@/views/online-shop/components/addGoodsGroup.vue";
|
||||||
|
import GoodsSelect from '@/components/GoodsSelect/index.vue'
|
||||||
|
import addSkuModal from "../components/addSkuModal.vue";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const selecProductDialogRef = ref(null)
|
const selecProductDialogRef = ref(null)
|
||||||
const goodsListMax = ref(9)
|
const goodsListMax = ref(9)
|
||||||
|
const addUnitRef = ref(null)
|
||||||
|
const consOptions = ref([])
|
||||||
|
const addCategoryRef = ref(null)
|
||||||
|
const addGoodsGroupRef = ref(null)
|
||||||
|
const addSkuModalRef = ref(null)
|
||||||
|
|
||||||
|
// let haocaiData = ref({
|
||||||
|
// consList: [
|
||||||
|
// {
|
||||||
|
// productId: '',
|
||||||
|
// consInfoId: "",
|
||||||
|
// surplusStock: "0",
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// });
|
||||||
|
|
||||||
|
const stepsActiveName = ref(0);
|
||||||
|
const tabsActiveName = ref(1);
|
||||||
|
const stepRules = [
|
||||||
|
'name',
|
||||||
|
'unitId',
|
||||||
|
'categoryId',
|
||||||
|
'images',
|
||||||
|
]
|
||||||
|
|
||||||
|
const goodsGroupList = ref([])
|
||||||
|
async function getGoodsGroupList() {
|
||||||
|
try {
|
||||||
|
goodsGroupList.value = await GoodsGroupAPI.getList()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
getGoodsGroupList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 校验基础信息的表单是否通过
|
||||||
|
async function nextStep() {
|
||||||
|
try {
|
||||||
|
await ruleFormRef.value.validateField(stepRules)
|
||||||
|
stepsActiveName.value++
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成新商品绑定耗材关系项
|
||||||
|
function createItem(val) {
|
||||||
|
let item = {
|
||||||
|
productId: '',
|
||||||
|
consInfoId: "",
|
||||||
|
surplusStock: "",
|
||||||
|
};
|
||||||
|
ruleForm.consList.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品选择耗材
|
||||||
|
function selectionChange(e, row) {
|
||||||
|
let item = consOptions.value.find((item) => item.id == e);
|
||||||
|
row.name = item.conName;
|
||||||
|
row.conUnit = item.conUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取耗材列表
|
||||||
|
async function gethaocaiList() {
|
||||||
|
try {
|
||||||
|
let res = await UserAPI3.productconsList({ id: route.query.id });
|
||||||
|
console.log('获取耗材列表', res);
|
||||||
|
consOptions.value = res || [];
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shopInfo = ref('')
|
||||||
|
|
||||||
|
function shopInfoTypeFilter(t) {
|
||||||
|
if (t == 1) return '跟随商品分类'
|
||||||
|
if (t == 2) return '跟随单商品'
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
shopInfo.value = JSON.parse(localStorage.getItem('userInfo'))
|
||||||
|
gethaocaiList()
|
||||||
// Sortable 需要在 el-table 渲染 tbody 后初始化,尝试多次以确保 DOM 可用
|
// Sortable 需要在 el-table 渲染 tbody 后初始化,尝试多次以确保 DOM 可用
|
||||||
const initSortable = async () => {
|
const initSortable = async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@@ -475,6 +682,7 @@ const ruleForm = reactive<RuleForm>({
|
|||||||
unitId: "",
|
unitId: "",
|
||||||
// 分类id
|
// 分类id
|
||||||
categoryId: "",
|
categoryId: "",
|
||||||
|
proGroupIds: [], // 商品分组集合
|
||||||
// 封面图url
|
// 封面图url
|
||||||
coverImg: "",
|
coverImg: "",
|
||||||
// 详情图urls
|
// 详情图urls
|
||||||
@@ -497,16 +705,16 @@ const ruleForm = reactive<RuleForm>({
|
|||||||
// sku集合
|
// sku集合
|
||||||
skuList: [],
|
skuList: [],
|
||||||
// 重量
|
// 重量
|
||||||
weight: 0,
|
weight: '',
|
||||||
// 是否允许改价
|
// 是否允许改价
|
||||||
isAllowTempModifyPrice: 1,
|
isAllowTempModifyPrice: 1,
|
||||||
// 定时上下架周期
|
// 定时上下架周期
|
||||||
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||||||
useTime: ["00:00:00", "23:59:59"],
|
useTime: ["00:00:00", "23:59:59"],
|
||||||
// 开始时间
|
// 开始时间
|
||||||
startTime: "",
|
startTime: "00:00:00",
|
||||||
// 结束时间
|
// 结束时间
|
||||||
endTime: "",
|
endTime: "23:59:59",
|
||||||
// 是否上架
|
// 是否上架
|
||||||
isSale: "1",
|
isSale: "1",
|
||||||
// 是否开启库存
|
// 是否开启库存
|
||||||
@@ -520,7 +728,10 @@ const ruleForm = reactive<RuleForm>({
|
|||||||
// 排序值
|
// 排序值
|
||||||
sort: 1,
|
sort: 1,
|
||||||
selectSpecInfo: {},
|
selectSpecInfo: {},
|
||||||
relatedRecommendJson: [] // 关联推荐商品
|
relatedRecommendJson: [], // 关联推荐商品
|
||||||
|
consList: [], // 耗材列表
|
||||||
|
refundMode: 1, // 退菜是否退库存 1退菜退库存 2仅退菜不退库存 3每次询问-退菜后弹窗提示
|
||||||
|
isAutoSoldStock: 0, // 是否自动售罄
|
||||||
});
|
});
|
||||||
const rules = reactive<FormRules<RuleForm>>({
|
const rules = reactive<FormRules<RuleForm>>({
|
||||||
name: [{ required: true, message: "请输入商品名称", trigger: "blur" }],
|
name: [{ required: true, message: "请输入商品名称", trigger: "blur" }],
|
||||||
@@ -584,6 +795,14 @@ async function tbProductGetDetail(id: any) {
|
|||||||
} else {
|
} else {
|
||||||
list.value = ruleForm.skuList;
|
list.value = ruleForm.skuList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (res.consList.length == 0) {
|
||||||
|
// ruleForm.consList.push({
|
||||||
|
// productId: '',
|
||||||
|
// consInfoId: "",
|
||||||
|
// surplusStock: "0",
|
||||||
|
// })
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// 选择套餐商品sku
|
// 选择套餐商品sku
|
||||||
function selectSkuHandle(item: any, index: number) {
|
function selectSkuHandle(item: any, index: number) {
|
||||||
@@ -643,11 +862,17 @@ function showSelectSkuHandle(row: any, index: any, tabIndex: any) {
|
|||||||
|
|
||||||
datas.selectSkuItem = obj;
|
datas.selectSkuItem = obj;
|
||||||
}
|
}
|
||||||
// 添加商品
|
|
||||||
|
// 显示添加套餐商品弹窗
|
||||||
function addgoods(index: number = -1) {
|
function addgoods(index: number = -1) {
|
||||||
datas.addGroupIndex = index;
|
datas.addGroupIndex = index;
|
||||||
(shopListRef.value as any)?.opens();
|
if (ruleForm.groupType == 0) {
|
||||||
|
(shopListRef.value as any)?.show(ruleForm.proGroupVo[0].goods || []);
|
||||||
|
} else {
|
||||||
|
(shopListRef.value as any)?.show(ruleForm.proGroupVo[index].goods || []);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteEvent(d: any) {
|
function deleteEvent(d: any) {
|
||||||
if (isSyncStatus()) {
|
if (isSyncStatus()) {
|
||||||
ElMessage.error('当前同步启用状态下不可修改')
|
ElMessage.error('当前同步启用状态下不可修改')
|
||||||
@@ -723,7 +948,7 @@ function createSkuHeader() {
|
|||||||
// 可选套餐弹窗
|
// 可选套餐弹窗
|
||||||
function addtaocan() {
|
function addtaocan() {
|
||||||
datas.addGroupIndex = -1;
|
datas.addGroupIndex = -1;
|
||||||
(shopListRef.value as any)?.opens();
|
(shopListRef.value as any)?.show();
|
||||||
}
|
}
|
||||||
// 生成多规格表体
|
// 生成多规格表体
|
||||||
function createSkuBody() {
|
function createSkuBody() {
|
||||||
@@ -811,6 +1036,7 @@ function changeTypeEnum(item: string) {
|
|||||||
list.value = [datas.defaultSku];
|
list.value = [datas.defaultSku];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 笛卡尔积算法
|
// 笛卡尔积算法
|
||||||
function cartesian(arr) {
|
function cartesian(arr) {
|
||||||
if (arr.length < 2) return arr[0] || [];
|
if (arr.length < 2) return arr[0] || [];
|
||||||
@@ -826,6 +1052,7 @@ function cartesian(arr) {
|
|||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 套餐类型切换
|
// 套餐类型切换
|
||||||
function typeChange() {
|
function typeChange() {
|
||||||
// ruleForm.typeEnum = 'normal'
|
// ruleForm.typeEnum = 'normal'
|
||||||
@@ -974,8 +1201,13 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
|||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.addgoods {
|
.addgoods {
|
||||||
padding: 20px;
|
padding: 14px;
|
||||||
background-color: #fff;
|
|
||||||
|
.form_wrap {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 14px;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pro_sku {
|
.pro_sku {
|
||||||
@@ -1088,4 +1320,8 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-wrap {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -9,10 +9,12 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
table: {
|
table: {
|
||||||
border: true,
|
border: true,
|
||||||
highlightCurrentRow: true,
|
highlightCurrentRow: true,
|
||||||
|
expandRowKeys: [],
|
||||||
rowKey: 'id',
|
rowKey: 'id',
|
||||||
treeProps: {
|
treeProps: {
|
||||||
children: 'skuList' // 指定子节点存储的字段为 customChildren
|
children: 'skuList' // 指定子节点存储的字段为 customChildren
|
||||||
}
|
},
|
||||||
|
selectOnIndeterminate: false,
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: {
|
||||||
background: true,
|
background: true,
|
||||||
@@ -72,13 +74,13 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
name: "sync",
|
name: "sync",
|
||||||
auth: "import",
|
auth: "import",
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
icon: "edit",
|
// icon: "edit",
|
||||||
text: "库存预警",
|
// text: "库存预警",
|
||||||
type: "danger",
|
// type: "danger",
|
||||||
name: "custom1",
|
// name: "custom1",
|
||||||
auth: "import",
|
// auth: "import",
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
icon: "Download",
|
icon: "Download",
|
||||||
text: "导出",
|
text: "导出",
|
||||||
@@ -88,24 +90,27 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
cols: [
|
cols: [
|
||||||
// { type: "selection", width: 50, align: "center" },
|
{
|
||||||
|
type: "selection", width: 50, align: "center", selectable: (row) => !row.barCode,
|
||||||
|
},
|
||||||
{ label: "封面图", align: "center", prop: "coverImg", templet: "image" },
|
{ label: "封面图", align: "center", prop: "coverImg", templet: "image" },
|
||||||
{ label: "商品名称", align: "center", prop: "name", },
|
{ label: "商品名称", align: "center", prop: "name", },
|
||||||
|
{ label: "分类", align: "center", prop: "categoryName", },
|
||||||
{ label: "售价", align: "center", prop: "lowPrice" },
|
{ label: "售价", align: "center", prop: "lowPrice" },
|
||||||
{
|
{
|
||||||
label: "商品规格", align: "center", prop: "type", templet: "custom",
|
label: "商品规格", align: "center", prop: "type", templet: "custom",
|
||||||
slotName: "type",
|
slotName: "type",
|
||||||
},
|
},
|
||||||
// { label: "库存", align: "center", prop: "stockNumber" },
|
// { label: "库存", align: "center", prop: "stockNumber" },
|
||||||
{ label: "库存", align: "center", slotName: "kucunedit", templet: "custom", prop: "stockNumber" },
|
// { label: "库存", align: "center", slotName: "kucunedit", templet: "custom", prop: "stockNumber" },
|
||||||
{ label: "耗材信息", align: "center", prop: "consName", slotName: "consumables", templet: "custom", },
|
{ label: "耗材信息", align: "center", prop: "consName", slotName: "consumables", templet: "custom", },
|
||||||
{
|
// {
|
||||||
label: "库存开关",
|
// label: "库存开关",
|
||||||
align: "center",
|
// align: "center",
|
||||||
prop: "isStock",
|
// prop: "isStock",
|
||||||
templet: "custom",
|
// templet: "custom",
|
||||||
slotName: "isStock",
|
// slotName: "isStock",
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: "上架",
|
label: "上架",
|
||||||
align: "center",
|
align: "center",
|
||||||
@@ -121,9 +126,16 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
slotName: "sellOut",
|
slotName: "sellOut",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "退款退回库存",
|
label: "自动售罄",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "isRefundStock",
|
prop: "isAutoSoldStock",
|
||||||
|
templet: "custom",
|
||||||
|
slotName: "autoSellOut",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "退菜退库存",
|
||||||
|
align: "center",
|
||||||
|
prop: "refundMode",
|
||||||
templet: "custom",
|
templet: "custom",
|
||||||
slotName: "tuikuantuihui",
|
slotName: "tuikuantuihui",
|
||||||
},
|
},
|
||||||
@@ -133,7 +145,11 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 280,
|
width: 280,
|
||||||
templet: "tool",
|
templet: "tool",
|
||||||
operat: [{ text: "报损", name: '' }, { text: "编辑", icon: 'edit', name: "edit" }, { text: "删除", icon: 'delete', type: 'danger', name: "delete" }],
|
operat: [
|
||||||
|
{ text: "报损", icon: '', name: 'cons' },
|
||||||
|
{ text: "报损记录", name: 'consRecord' },
|
||||||
|
{ text: "编辑", icon: 'edit', name: "edit" },
|
||||||
|
{ text: "删除", icon: 'delete', type: 'danger', name: "delete" }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ const searchConfig: ISearchConfig = {
|
|||||||
label: "排序",
|
label: "排序",
|
||||||
prop: "orderBy",
|
prop: "orderBy",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择商品分类",
|
placeholder: "请选择排序方式",
|
||||||
clearable: true,
|
clearable: true,
|
||||||
style: {
|
style: {
|
||||||
width: "200px",
|
width: "200px",
|
||||||
|
|||||||
@@ -29,10 +29,12 @@
|
|||||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
</template>
|
</template>
|
||||||
<template #operates="scope">
|
<template #operates="scope">
|
||||||
<el-button type="text" size="small" v-if="scope.row.level < 3 && !isSyncStatus()"
|
<!-- <el-button type="text" size="small" v-if="scope.row.level < 3 && !isSyncStatus()"
|
||||||
@click="addlowerLevel(scope.row)">添加下一级</el-button>
|
@click="addlowerLevel(scope.row)">添加下一级</el-button> -->
|
||||||
<el-button type="text" size="small" v-if="!isSyncStatus()" @click="handleEditClick(scope.row)">编辑</el-button>
|
<el-button type="primary" link size="small" v-if="!isSyncStatus() && scope.row.pid == 0"
|
||||||
<el-button type="text" size="small" v-if="!isSyncStatus()" @click="deleteClick(scope.row)">删除</el-button>
|
@click="handleEditClick(scope.row)">编辑</el-button>
|
||||||
|
<el-button type="danger" link size="small" v-if="!isSyncStatus()"
|
||||||
|
@click="deleteClick(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
<!-- 添加下一级-编辑 -->
|
<!-- 添加下一级-编辑 -->
|
||||||
@@ -110,6 +112,7 @@
|
|||||||
</page-content>
|
</page-content>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
<addSkuModal ref="addSkuModalRef" @success="handleResetClick" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -124,6 +127,9 @@ import editModalConfig from "./specificationsconfig/edit";
|
|||||||
import searchConfig from "./specificationsconfig/search";
|
import searchConfig from "./specificationsconfig/search";
|
||||||
import { pid } from "process";
|
import { pid } from "process";
|
||||||
import { isSyncStatus } from "@/utils/index";
|
import { isSyncStatus } from "@/utils/index";
|
||||||
|
import addSkuModal from "./components/addSkuModal.vue";
|
||||||
|
|
||||||
|
const addSkuModalRef = ref(null)
|
||||||
|
|
||||||
const validateSku1 = (rule, value, callback) => {
|
const validateSku1 = (rule, value, callback) => {
|
||||||
if (!datas.skuForm.label) {
|
if (!datas.skuForm.label) {
|
||||||
@@ -300,36 +306,38 @@ function deleteClick(item: any) {
|
|||||||
}
|
}
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
myDialogRef.value?.open();
|
addSkuModalRef.value?.open()
|
||||||
addModalRef.value?.setModalVisible();
|
// myDialogRef.value?.open();
|
||||||
|
// addModalRef.value?.setModalVisible();
|
||||||
// 加载上级规格下拉数据源
|
// 加载上级规格下拉数据源
|
||||||
addModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
// addModalConfig.formItems[2]!.attrs!.data = await UserAPI.getPage({ name: "" });
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
addSkuModalRef.value?.open(row)
|
||||||
// 加载部门下拉数据源
|
// editModalRef.value?.handleDisabled(false);
|
||||||
editModalConfig.formItems[2]!.attrs!.data = [{
|
// // 加载部门下拉数据源
|
||||||
createTime: "",
|
// editModalConfig.formItems[2]!.attrs!.data = [{
|
||||||
fullName: "顶级",
|
// createTime: "",
|
||||||
id: "0", level: 1,
|
// fullName: "顶级",
|
||||||
name: "顶级",
|
// id: "0", level: 1,
|
||||||
pid: "0",
|
// name: "顶级",
|
||||||
pids: "0,",
|
// pid: "0",
|
||||||
shopId: "1",
|
// pids: "0,",
|
||||||
sort: 1,
|
// shopId: "1",
|
||||||
status: 1,
|
// sort: 1,
|
||||||
updateTime: "",
|
// status: 1,
|
||||||
children: await UserAPI.getPage({ name: "" })
|
// updateTime: "",
|
||||||
}]
|
// children: await UserAPI.getPage({ name: "" })
|
||||||
|
// }]
|
||||||
// 加载角色下拉数据源
|
// 加载角色下拉数据源
|
||||||
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
// 根据id获取数据进行填充
|
// 根据id获取数据进行填充
|
||||||
const data = await UserAPI.getunitinfo(row.id);
|
// const data = await UserAPI.getunitinfo(row.id);
|
||||||
editModalRef.value?.setFormData(data);
|
// editModalRef.value?.setFormData(data);
|
||||||
editModalRef.value?.setModalVisible();
|
// editModalRef.value?.setModalVisible();
|
||||||
|
|
||||||
}
|
}
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
|
|||||||
@@ -62,9 +62,10 @@ const contentConfig: IContentConfig<UserPageQuery> = {
|
|||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
label: "操作",
|
label: "操作",
|
||||||
|
width: '150',
|
||||||
slotName: "operates",
|
slotName: "operates",
|
||||||
templet: "custom",
|
templet: "custom",
|
||||||
align: "center",
|
align: "left",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,20 +23,8 @@
|
|||||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
</page-content>
|
||||||
|
<!-- 添加/编辑单位 -->
|
||||||
<!-- 新增 -->
|
<addUnit ref="addUnitRef" @success="handleQueryClick" />
|
||||||
<page-modal ref="addModalRef" :modal-config="addModalConfig" @submit-click="handleSubmitClick">
|
|
||||||
<template #gender="scope">
|
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" />
|
|
||||||
</template>
|
|
||||||
</page-modal>
|
|
||||||
|
|
||||||
<!-- 编辑 -->
|
|
||||||
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
|
||||||
<template #gender="scope">
|
|
||||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
|
||||||
</template>
|
|
||||||
</page-modal>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
|
<page-content ref="contentRef" :content-config="contentConfig2" @operat-click="handleOperatClick">
|
||||||
@@ -62,6 +50,9 @@ import contentConfig2 from "./unitconfig/content2";
|
|||||||
import editModalConfig from "./unitconfig/edit";
|
import editModalConfig from "./unitconfig/edit";
|
||||||
import searchConfig from "./unitconfig/search";
|
import searchConfig from "./unitconfig/search";
|
||||||
import { isSyncStatus, downloadFile } from "@/utils/index";
|
import { isSyncStatus, downloadFile } from "@/utils/index";
|
||||||
|
import addUnit from "./components/addUnit.vue";
|
||||||
|
|
||||||
|
const addUnitRef = ref(null)
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -101,23 +92,25 @@ async function handleExportClick() {
|
|||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
addModalRef.value?.setModalVisible();
|
addUnitRef.value.open()
|
||||||
// 加载部门下拉数据源
|
// addModalRef.value?.setModalVisible();
|
||||||
addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// // 加载部门下拉数据源
|
||||||
// 加载角色下拉数据源
|
// addModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// // 加载角色下拉数据源
|
||||||
|
// addModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
}
|
}
|
||||||
// 编辑
|
// 编辑
|
||||||
async function handleEditClick(row: IObject) {
|
async function handleEditClick(row: IObject) {
|
||||||
editModalRef.value?.handleDisabled(false);
|
addUnitRef.value.open(row)
|
||||||
// 加载部门下拉数据源
|
// editModalRef.value?.handleDisabled(false);
|
||||||
// editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
// // 加载部门下拉数据源
|
||||||
// 加载角色下拉数据源
|
// // editModalConfig.formItems[2]!.attrs!.data = await DeptAPI.getOptions();
|
||||||
// editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
// // 加载角色下拉数据源
|
||||||
// 根据id获取数据进行填充
|
// // editModalConfig.formItems[4]!.options = await RoleAPI.getOptions();
|
||||||
const data = await UserAPI.getunitinfo(row.id);
|
// // 根据id获取数据进行填充
|
||||||
editModalRef.value?.setFormData(data);
|
// const data = await UserAPI.getunitinfo(row.id);
|
||||||
editModalRef.value?.setModalVisible();
|
// editModalRef.value?.setFormData(data);
|
||||||
|
// editModalRef.value?.setModalVisible();
|
||||||
|
|
||||||
}
|
}
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<el-input v-model="state.query.name" clearable placeholder="请输入分店名称" style="width: 100%" class="filter-item"
|
<el-input v-model="state.query.name" clearable placeholder="请输入分店名称" style="width: 100%" class="filter-item"
|
||||||
@keyup.enter="getTableData" />
|
@keyup.enter="getTableData" />
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
<el-col :span="16">
|
<el-col :span="16">
|
||||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||||
@@ -22,35 +22,43 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="padding-bottom: 14px;">
|
||||||
|
<el-alert title="分店需由工作人员协助开通" type="warning" :closable="false" show-icon />
|
||||||
|
</div>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
|
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
|
||||||
<el-table-column prop="id" label="ID" width="80" />
|
<el-table-column prop="id" label="ID" width="80" />
|
||||||
<el-table-column label="店铺信息">
|
<el-table-column label="店铺信息">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div>{{ scope.row.shopName }}{{ scope.row.shopType == 'chain' ? '(连锁店)' : scope.row.shopType == 'join' ? '(加盟店)' : '' }}</div>
|
<div>{{ scope.row.shopName }}{{ scope.row.shopType == 'chain' ? '(连锁店)' : scope.row.shopType == 'join' ?
|
||||||
|
'(加盟店)' : '' }}</div>
|
||||||
<div>账号:{{ scope.row.account }}</div>
|
<div>账号:{{ scope.row.account }}</div>
|
||||||
<div>联系电话:{{ scope.row.phone }}</div>
|
<div>联系电话:{{ scope.row.phone }}</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isEnableProdSync" label="商品同步" width="120">
|
<el-table-column prop="isEnableProdSync" label="商品同步" width="120">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag :type="scope.row.isEnableProdSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableProdSync == 1 ? '启用' : '禁用' }} </el-tag>
|
<el-tag :type="scope.row.isEnableProdSync == 1 ? 'success' : 'error'" effect="dark"> {{
|
||||||
|
scope.row.isEnableProdSync == 1 ? '启用' : '禁用' }} </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isEnableVipSync" label="会员同步" width="120">
|
<el-table-column prop="isEnableVipSync" label="会员同步" width="120">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag :type="scope.row.isEnableVipSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableVipSync == 1 ? '启用' : '禁用' }} </el-tag>
|
<el-tag :type="scope.row.isEnableVipSync == 1 ? 'success' : 'error'" effect="dark"> {{
|
||||||
|
scope.row.isEnableVipSync == 1 ? '启用' : '禁用' }} </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isEnableConsSync" label="耗材同步" width="120">
|
<el-table-column prop="isEnableConsSync" label="耗材同步" width="120">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag :type="scope.row.isEnableConsSync == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isEnableConsSync == 1 ? '启用' : '禁用' }} </el-tag>
|
<el-tag :type="scope.row.isEnableConsSync == 1 ? 'success' : 'error'" effect="dark"> {{
|
||||||
|
scope.row.isEnableConsSync == 1 ? '启用' : '禁用' }} </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="isAllowAccountLogin" label="账号状态" width="120">
|
<el-table-column prop="isAllowAccountLogin" label="账号状态" width="120">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-tag :type="scope.row.isAllowAccountLogin == 1 ? 'success' : 'error'" effect="dark"> {{ scope.row.isAllowAccountLogin == 1 ? '启用' : '禁用' }} </el-tag>
|
<el-tag :type="scope.row.isAllowAccountLogin == 1 ? 'success' : 'error'" effect="dark"> {{
|
||||||
|
scope.row.isAllowAccountLogin == 1 ? '启用' : '禁用' }} </el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="createdAt" label="备注" />
|
<el-table-column prop="createdAt" label="备注" />
|
||||||
@@ -105,7 +113,7 @@ onMounted(() => {
|
|||||||
getTableData();
|
getTableData();
|
||||||
getDataSync()
|
getDataSync()
|
||||||
});
|
});
|
||||||
async function getDataSync () {
|
async function getDataSync() {
|
||||||
let res = await ShopBranchApi.getDataSync()
|
let res = await ShopBranchApi.getDataSync()
|
||||||
state.par.dataSyncMethod = res
|
state.par.dataSyncMethod = res
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,8 @@
|
|||||||
<el-table-column label="头像">
|
<el-table-column label="头像">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="shop_info">
|
<div class="shop_info">
|
||||||
<el-image
|
<el-image :src="scope.row.avatar"
|
||||||
:src="scope.row.avatar"
|
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef">
|
||||||
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef"
|
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="img_error">
|
<div class="img_error">
|
||||||
<i class="icon el-icon-document-delete"></i>
|
<i class="icon el-icon-document-delete"></i>
|
||||||
@@ -35,12 +33,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="昵称" prop="nickname"></el-table-column>
|
<el-table-column label="昵称" prop="nickname"></el-table-column>
|
||||||
|
<el-table-column label="描述提示" prop="content"></el-table-column>
|
||||||
<el-table-column label="订阅类型">
|
<el-table-column label="订阅类型">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-checkbox-group
|
<el-checkbox-group :model-value="scope.row.typeInfo" @change="typeInfoChange($event, scope.row)">
|
||||||
:model-value="scope.row.typeInfo"
|
|
||||||
@change="typeInfoChange($event, scope.row)"
|
|
||||||
>
|
|
||||||
<el-checkbox label="耗材推送" value="con"></el-checkbox>
|
<el-checkbox label="耗材推送" value="con"></el-checkbox>
|
||||||
<el-checkbox label="商品推送" value="pro"></el-checkbox>
|
<el-checkbox label="商品推送" value="pro"></el-checkbox>
|
||||||
<el-checkbox label="操作预警" value="ope"></el-checkbox>
|
<el-checkbox label="操作预警" value="ope"></el-checkbox>
|
||||||
@@ -59,14 +55,9 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-pagination
|
<el-pagination :total="tableData.total" @size-change="handleSizeChange" :current-page="tableData.page"
|
||||||
:total="tableData.total"
|
:page-size="tableData.size" @current-change="paginationChange"
|
||||||
@size-change="handleSizeChange"
|
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
|
||||||
:current-page="tableData.page"
|
|
||||||
:page-size="tableData.size"
|
|
||||||
@current-change="paginationChange"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
></el-pagination>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,25 +2,15 @@
|
|||||||
<div>
|
<div>
|
||||||
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||||
<el-form-item label="操作密码">
|
<el-form-item label="操作密码">
|
||||||
<el-input
|
<el-input v-model="form.password" type="number" @input="jiantingshuru" :disabled="disabled"
|
||||||
v-model="form.password"
|
:placeholder="disabled ? '******' : '请输入操作密码'" style="width: 200px"></el-input>
|
||||||
type="number"
|
|
||||||
@input="jiantingshuru"
|
|
||||||
:disabled="disabled"
|
|
||||||
:placeholder="disabled ? '******' : '请输入操作密码'"
|
|
||||||
style="width: 200px"
|
|
||||||
></el-input>
|
|
||||||
<el-button type="primary" @click="resetting">重置</el-button>
|
<el-button type="primary" @click="resetting">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="安全手机号">
|
<el-form-item label="安全手机号">
|
||||||
{{ phoneFilter(form.phone) }}
|
{{ phoneFilter(form.phone) }}
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="验证码">
|
<el-form-item label="验证码">
|
||||||
<el-input
|
<el-input v-model="form.prepareAmount" placeholder="点击发送" style="width: 200px"></el-input>
|
||||||
v-model="form.prepareAmount"
|
|
||||||
placeholder="点击发送"
|
|
||||||
style="width: 200px"
|
|
||||||
></el-input>
|
|
||||||
<el-button type="primary" @click="onSubmit">发送</el-button>
|
<el-button type="primary" @click="onSubmit">发送</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -31,8 +21,8 @@
|
|||||||
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||||
<el-form-item label="校验安全密码">
|
<el-form-item label="校验安全密码">
|
||||||
<el-checkbox v-model="form.isReturnPwd">退款</el-checkbox>
|
<el-checkbox v-model="form.isReturnPwd">退款</el-checkbox>
|
||||||
<el-checkbox v-model="form.isMemberInPwd">会员充值</el-checkbox>
|
<el-checkbox v-model="form.isMemberInPwd">余额充值</el-checkbox>
|
||||||
<el-checkbox v-model="form.isMemberReturnPwd">会员退款</el-checkbox>
|
<el-checkbox v-model="form.isMemberReturnPwd">余额退款</el-checkbox>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="submitHandles">保存</el-button>
|
<el-button type="primary" @click="submitHandles">保存</el-button>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<el-form ref="form" :model="form" :rules="rules" label-width="160px" label-position="left">
|
||||||
<div>
|
<el-tabs v-model="activeName">
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="160px" label-position="left">
|
<el-tab-pane label="基础设置" name="first">
|
||||||
<el-form-item label="门店名称" prop="shopName">
|
<el-form-item label="门店名称" prop="shopName">
|
||||||
<el-input v-model.trim="form.shopName" placeholder="请输入门店名称" style="width: 500px"></el-input>
|
<el-input v-model.trim="form.shopName" placeholder="请输入门店名称" style="width: 500px"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -46,31 +46,12 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="经营模式「单选」">
|
|
||||||
<el-radio-group v-model="form.registerType">
|
|
||||||
<el-radio value="before">快餐版(先支付后下单)</el-radio>
|
|
||||||
<el-radio value="after">餐饮版(先下单后支付)</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="就餐模式「多选」" prop="eatModel">
|
|
||||||
<el-checkbox-group v-model="form.eatModel">
|
|
||||||
<el-checkbox value="dine-in">堂食自取</el-checkbox>
|
|
||||||
<el-checkbox value="take-out">允许打包</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- <el-form-item label="积分群体">
|
|
||||||
<el-radio-group v-model="form.consumeColony">
|
|
||||||
<el-radio label="all">所有</el-radio>
|
|
||||||
<el-radio label="vip">仅针对会员</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="联系电话" prop="phone">
|
<el-form-item label="联系电话" prop="phone">
|
||||||
<el-input v-model.trim="form.phone" placeholder="请输入联系电话" style="width: 500px"></el-input>
|
<el-input v-model.trim="form.phone" placeholder="请输入联系电话" style="width: 500px"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="外卖起送金额">
|
<el-form-item label="店铺简介">
|
||||||
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
<el-input type="textarea" v-model.trim="form.detail" placeholder="请输入店铺简介" style="width: 500px"></el-input>
|
||||||
:min="0"></el-input-number>
|
</el-form-item>
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="店铺经度" prop="provinces">
|
<el-form-item label="店铺经度" prop="provinces">
|
||||||
<el-row :gutter="6">
|
<el-row :gutter="6">
|
||||||
<el-col :span="9" v-if="form.provinces">
|
<el-col :span="9" v-if="form.provinces">
|
||||||
@@ -93,6 +74,50 @@
|
|||||||
<el-form-item label="门店详细地址">
|
<el-form-item label="门店详细地址">
|
||||||
<el-input type="textarea" v-model.trim="form.address" placeholder="请输入门店详细地址" style="width: 500px"></el-input>
|
<el-input type="textarea" v-model.trim="form.address" placeholder="请输入门店详细地址" style="width: 500px"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="经营设置" name="third">
|
||||||
|
<el-form-item label="经营模式「单选」">
|
||||||
|
<el-radio-group v-model="form.registerType">
|
||||||
|
<el-radio value="before">快餐版(先支付后下单)</el-radio>
|
||||||
|
<el-radio value="after">餐饮版(先下单后支付)</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="是否允许用户自行支付" prop="isUserPay" v-if="form.registerType === 'after'">
|
||||||
|
<div class="column">
|
||||||
|
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
||||||
|
<el-switch v-model="form.isUserPay" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
<div class="tips" style="font-size: 14px; color: #999">
|
||||||
|
关闭后,用户将不能自行支付
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="就餐模式「多选」" prop="eatModel">
|
||||||
|
<el-checkbox-group v-model="form.eatModel">
|
||||||
|
<el-checkbox value="dine-in">堂食自取</el-checkbox>
|
||||||
|
<el-checkbox value="take-out">允许打包</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="退菜退库存模式">
|
||||||
|
<el-radio-group :model-value="form.refundMode" @change="refundModeChange">
|
||||||
|
<el-radio label="跟随商品分类" :value="1"></el-radio>
|
||||||
|
<el-radio label="跟随单商品" :value="2"></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="后厨单菜二维码">
|
||||||
|
<el-switch v-model="form.isKitchenCode" :active-value="1" :inactive-value="0"></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="积分群体">
|
||||||
|
<el-radio-group v-model="form.consumeColony">
|
||||||
|
<el-radio label="all">所有</el-radio>
|
||||||
|
<el-radio label="vip">仅针对会员</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item> -->
|
||||||
|
<!-- <el-form-item label="外卖起送金额">
|
||||||
|
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||||
|
:min="0"></el-input-number>
|
||||||
|
</el-form-item> -->
|
||||||
<el-form-item label="营业时间">
|
<el-form-item label="营业时间">
|
||||||
<div class="u-flex gap-2" style="width: 50%">
|
<div class="u-flex gap-2" style="width: 50%">
|
||||||
<el-select v-model="form.businessStartDay" placeholder="周几开始">
|
<el-select v-model="form.businessStartDay" placeholder="周几开始">
|
||||||
@@ -147,13 +172,10 @@
|
|||||||
>
|
>
|
||||||
</el-time-picker>
|
</el-time-picker>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="店铺简介">
|
<!-- <el-form-item label="台桌预订短信">
|
||||||
<el-input type="textarea" v-model.trim="form.detail" placeholder="请输入店铺简介" style="width: 500px"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="台桌预订短信">
|
|
||||||
<el-input type="textarea" v-model.trim="form.bookingSms" placeholder="请输入台桌预订短信"
|
<el-input type="textarea" v-model.trim="form.bookingSms" placeholder="请输入台桌预订短信"
|
||||||
style="width: 500px"></el-input>
|
style="width: 500px"></el-input>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item label="电子围栏" prop="isOrderFence">
|
<el-form-item label="电子围栏" prop="isOrderFence">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
||||||
@@ -172,6 +194,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="上菜时间(分钟)" prop="isServeTimeControl">
|
<el-form-item label="上菜时间(分钟)" prop="isServeTimeControl">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
||||||
@@ -199,32 +222,32 @@
|
|||||||
<el-radio :value="2">休息中</el-radio>
|
<el-radio :value="2">休息中</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
</el-tab-pane>
|
||||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
<el-form-item>
|
||||||
<span v-if="!formLoading">保存</span>
|
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||||
<span v-else>保存中...</span>
|
<span v-if="!formLoading">保存</span>
|
||||||
</el-button>
|
<span v-else>保存中...</span>
|
||||||
</el-form-item>
|
</el-button>
|
||||||
</el-form>
|
</el-form-item>
|
||||||
</div>
|
</el-tabs>
|
||||||
<ChooseAddress ref="refChooseAddress" @choose="chooseAddressConfirm"></ChooseAddress>
|
</el-form>
|
||||||
<el-dialog v-model="showUpload" :close-on-click-modal="false" append-to-body width="500px"
|
<ChooseAddress ref="refChooseAddress" @choose="chooseAddressConfirm"></ChooseAddress>
|
||||||
@close="showUpload = false">
|
<el-dialog v-model="showUpload" :close-on-click-modal="false" append-to-body width="500px"
|
||||||
<el-upload :before-remove="handleBeforeRemove" :on-success="handleSuccess" :on-error="handleError"
|
@close="showUpload = false">
|
||||||
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" :limit="1" list-type="picture"
|
<el-upload :before-remove="handleBeforeRemove" :on-success="handleSuccess" :on-error="handleError"
|
||||||
class="upload-demo">
|
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" :limit="1" list-type="picture"
|
||||||
<el-button size="small" type="primary">点击上传</el-button>
|
class="upload-demo">
|
||||||
<template #tip>
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
<div style="display: block" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
<template #tip>
|
||||||
</template>
|
<div style="display: block" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||||
</el-upload>
|
|
||||||
<template #footer>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<el-button type="primary" @click="doSubmit">确认</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-upload>
|
||||||
</div>
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="doSubmit">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -238,6 +261,7 @@ import { filterNumberInput } from "@/utils/index";
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
activeName: "first",
|
||||||
filterNumberInput,
|
filterNumberInput,
|
||||||
img_download_error,
|
img_download_error,
|
||||||
showUpload: false,
|
showUpload: false,
|
||||||
@@ -341,7 +365,33 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.tbShopInfo();
|
this.tbShopInfo();
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
"form.registerType"(val) {
|
||||||
|
console.log(val);
|
||||||
|
if (val === "before") {
|
||||||
|
this.form.isUserPay = 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 切换退菜退库存模式
|
||||||
|
refundModeChange(value) {
|
||||||
|
console.log('refundModeChange===', value);
|
||||||
|
const m = {
|
||||||
|
1: {
|
||||||
|
1: '跟随商品分类',
|
||||||
|
2: '商品分类'
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
1: '跟随单商品模式',
|
||||||
|
2: '商品列表'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ElMessageBox.confirm(`当前操作:将《退菜退库存》模式切换为「${m[value][1]}」本操作将会影响耗材库存数量的统计请谨慎操作修改后,可前往「商品管理-${m[value][2]}」中编辑/查看配置`, '提示', { showClose: false, showCancelButton: false }).then(() => {
|
||||||
|
this.form.refundMode = value
|
||||||
|
}).catch(() => { })
|
||||||
|
},
|
||||||
chooseAddressConfirm(e) {
|
chooseAddressConfirm(e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
this.$refs.refChooseAddress.close();
|
this.$refs.refChooseAddress.close();
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog title="激活码" width="500px" v-model="show" @close="reset">
|
<el-dialog title="激活" width="550px" v-model="show" @close="reset">
|
||||||
<el-form :model="form" ref="refForm" :rules="rules">
|
<el-form :model="form" ref="refForm" :rules="rules">
|
||||||
<el-form-item label="激活码" prop="activateCode">
|
<el-form-item label="激活时长" prop="activateDuration">
|
||||||
<el-input v-model="form.activateCode" placeholder="请输入激活码"></el-input>
|
<activeDate v-model="form.activateDuration" v-model:activeCost="form.activateAmount" />
|
||||||
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
<!-- <el-input v-model="form.activateDuration" placeholder="请输入激活码"></el-input>
|
||||||
|
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -15,18 +16,20 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import ShopApi from "@/api/account/shop";
|
import ShopApi from "@/api/account/shop";
|
||||||
|
import activeDate from "./activeDate.vue";
|
||||||
|
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
activateCode: "",
|
activateDuration: "",
|
||||||
|
activateAmount: '',
|
||||||
id: "",
|
id: "",
|
||||||
});
|
});
|
||||||
const rules = {
|
const rules = {
|
||||||
activateCode: [{ required: true, message: "请输入激活码", trigger: "blur" }],
|
activateDuration: [{ required: true, message: "请选择激活时长", trigger: "blur" }],
|
||||||
};
|
};
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
form.activateCode = "";
|
form.activateDuration = "";
|
||||||
form.id = "";
|
form.id = "";
|
||||||
}
|
}
|
||||||
const emit = defineEmits(["submit"]);
|
const emit = defineEmits(["submit"]);
|
||||||
|
|||||||
32
src/views/shop/list/components/activeDate.vue
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<el-select v-model="modelValue" style="width: 200px;" placeholder="请选择激活时长">
|
||||||
|
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-model="activeCost" placeholder="请输入激活费用(选填)" style="width: 200px; margin-left: 14px;" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
|
||||||
|
const modelValue = defineModel({
|
||||||
|
type: [String, Number],
|
||||||
|
default: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
// 激活费用
|
||||||
|
const activeCost = defineModel('activeCost', {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
})
|
||||||
|
|
||||||
|
const options = ref([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
for (let i = 1; i <= 12; i++) {
|
||||||
|
options.value.push({
|
||||||
|
label: `${i}个月`,
|
||||||
|
value: i,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
61
src/views/shop/list/components/activeteRecord.vue
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 激活记录 -->
|
||||||
|
<el-dialog v-model="show" title="激活记录" width="500px">
|
||||||
|
<el-table :data="tableData.records" style="width: 100%">
|
||||||
|
<el-table-column prop="periodMonth" label="激活时长(月)"></el-table-column>
|
||||||
|
<el-table-column prop="amount" label="店铺签约金额">
|
||||||
|
<template v-slot="scope">
|
||||||
|
{{ formatMoney(scope.row.amount) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="操作时间"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||||
|
:page-sizes="[10, 20, 50, 100]" :total="tableData.total" @current-change="getData" @size-change="getData"
|
||||||
|
style="margin-top: 16px; text-align: right;" />
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from "vue";
|
||||||
|
import ShopApi from "@/api/account/shop";
|
||||||
|
import { formatMoney } from "@/utils";
|
||||||
|
|
||||||
|
const shopInfo = ref({ id: '' })
|
||||||
|
|
||||||
|
const show = ref(false);
|
||||||
|
const tableData = reactive({
|
||||||
|
loading: false,
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
records: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getData() {
|
||||||
|
try {
|
||||||
|
tableData.loading = true;
|
||||||
|
const res = await ShopApi.registerRecord({
|
||||||
|
page: tableData.page,
|
||||||
|
size: tableData.size,
|
||||||
|
shopId: shopInfo.value.id
|
||||||
|
});
|
||||||
|
tableData.records = res.records;
|
||||||
|
tableData.total = res.totalRow;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
} finally {
|
||||||
|
tableData.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(data) {
|
||||||
|
shopInfo.value = data;
|
||||||
|
show.value = true;
|
||||||
|
getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,72 +1,35 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<el-dialog
|
<el-dialog :title="state.form.id ? '编辑店铺' : '添加店铺'" v-model="state.dialogVisible" @close="reset">
|
||||||
:title="state.form.id ? '编辑店铺' : '添加店铺'"
|
|
||||||
v-model="state.dialogVisible"
|
|
||||||
@close="reset"
|
|
||||||
>
|
|
||||||
<div style="height: 50vh; overflow-y: auto">
|
<div style="height: 50vh; overflow-y: auto">
|
||||||
<el-form
|
<el-form ref="refForm" :model="state.form" :rules="state.rules" label-width="120px" label-position="left">
|
||||||
ref="refForm"
|
|
||||||
:model="state.form"
|
|
||||||
:rules="state.rules"
|
|
||||||
label-width="120px"
|
|
||||||
label-position="left"
|
|
||||||
>
|
|
||||||
<el-form-item label="店铺名称" prop="shopName">
|
<el-form-item label="店铺名称" prop="shopName">
|
||||||
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
|
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="店铺类型">
|
<el-form-item label="店铺类型">
|
||||||
<el-radio-group
|
<el-radio-group v-model="state.form.shopType" :disabled="state.isEdit || state.type == 'addBranch'">
|
||||||
v-model="state.form.shopType"
|
|
||||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
|
||||||
>
|
|
||||||
<el-radio-button value="only">单店</el-radio-button>
|
<el-radio-button value="only">单店</el-radio-button>
|
||||||
<el-radio-button value="chain">连锁店</el-radio-button>
|
<el-radio-button value="chain">连锁店</el-radio-button>
|
||||||
<el-radio-button value="join">加盟店</el-radio-button>
|
<el-radio-button value="join">加盟店</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<el-alert
|
<el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false" />
|
||||||
title="请谨慎修改"
|
|
||||||
type="warning"
|
|
||||||
size="7"
|
|
||||||
effect="dark"
|
|
||||||
show-icon
|
|
||||||
:closable="false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="是否为主店" prop="isHeadShop" v-if="state.form.shopType != 'only'">
|
<el-form-item label="是否为主店" prop="isHeadShop" v-if="state.form.shopType != 'only'">
|
||||||
<el-radio-group
|
<el-radio-group v-model="state.form.isHeadShop" @change="state.form.mainId = ''"
|
||||||
v-model="state.form.isHeadShop"
|
:disabled="state.isEdit || state.type == 'addBranch'">
|
||||||
@change="state.form.mainId = ''"
|
|
||||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
|
||||||
>
|
|
||||||
<el-radio :value="1">是</el-radio>
|
<el-radio :value="1">是</el-radio>
|
||||||
<el-radio :value="0">否</el-radio>
|
<el-radio :value="0">否</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item
|
<el-form-item label="选择主店" prop="mainId" v-if="state.form.isHeadShop == '0' && state.form.shopType != 'only'">
|
||||||
label="选择主店"
|
|
||||||
prop="mainId"
|
|
||||||
v-if="state.form.isHeadShop == '0' && state.form.shopType != 'only'"
|
|
||||||
>
|
|
||||||
<!-- <el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> -->
|
<!-- <el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> -->
|
||||||
<el-select
|
<el-select v-model="state.form.mainId" placeholder="请选择主店铺" filterable reserve-keyword
|
||||||
v-model="state.form.mainId"
|
:remote-method="getTableData" :loading="state.shopListLoading"
|
||||||
placeholder="请选择主店铺"
|
:disabled="state.isEdit || state.type == 'addBranch'">
|
||||||
filterable
|
<el-option v-for="item in state.shopList" :label="`${item.shopName}`" :value="item.id"
|
||||||
reserve-keyword
|
:key="item.id"></el-option>
|
||||||
:remote-method="getTableData"
|
|
||||||
:loading="state.shopListLoading"
|
|
||||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in state.shopList"
|
|
||||||
:label="`${item.shopName}`"
|
|
||||||
:value="item.id"
|
|
||||||
:key="item.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="连锁店扩展店名">
|
<el-form-item label="连锁店扩展店名">
|
||||||
@@ -84,14 +47,7 @@
|
|||||||
<el-radio-button value="after">后付费</el-radio-button>
|
<el-radio-button value="after">后付费</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<el-alert
|
<el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false" />
|
||||||
title="请谨慎修改"
|
|
||||||
type="warning"
|
|
||||||
size="7"
|
|
||||||
effect="dark"
|
|
||||||
show-icon
|
|
||||||
:closable="false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="管理方式" v-if="state.form.shopType != 'only'">
|
<el-form-item label="管理方式" v-if="state.form.shopType != 'only'">
|
||||||
@@ -100,14 +56,7 @@
|
|||||||
<el-radio-button :value="1">直接管理</el-radio-button>
|
<el-radio-button :value="1">直接管理</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<el-alert
|
<el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false" />
|
||||||
title="请谨慎修改"
|
|
||||||
type="warning"
|
|
||||||
size="7"
|
|
||||||
effect="dark"
|
|
||||||
show-icon
|
|
||||||
:closable="false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="商户版本">
|
<el-form-item label="商户版本">
|
||||||
@@ -116,53 +65,34 @@
|
|||||||
<el-radio-button value="release">正式</el-radio-button>
|
<el-radio-button value="release">正式</el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
<el-alert
|
<el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false" />
|
||||||
title="请谨慎修改"
|
|
||||||
type="warning"
|
|
||||||
size="7"
|
|
||||||
effect="dark"
|
|
||||||
show-icon
|
|
||||||
:closable="false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="激活码">
|
<el-form-item label="激活时长" prop="activateDuration">
|
||||||
<el-input v-model="state.form.activateCode" placeholder="请输入激活码"></el-input>
|
<activeDate v-model="state.form.activateDuration" v-model:activeCost="state.form.activateAmount" />
|
||||||
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
<!-- <el-input v-model="state.form.activateDuration" placeholder="请输入激活码"></el-input>
|
||||||
|
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="登录账号" prop="accountName">
|
<el-form-item label="登录账号" prop="accountName">
|
||||||
<el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input>
|
<el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="登录密码" prop="password" v-if="!state.form.id">
|
<el-form-item label="登录密码" prop="accountPwd" v-if="!state.form.id">
|
||||||
<el-input
|
<el-input type="password" show-password v-model="state.form.accountPwd" placeholder="请输入登录密码"></el-input>
|
||||||
type="password"
|
|
||||||
show-password
|
|
||||||
v-model="state.form.accountPwd"
|
|
||||||
placeholder="请输入登录密码"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="联系电话" prop="phone">
|
<el-form-item label="联系电话" prop="phone">
|
||||||
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
|
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="设备数量">
|
<el-form-item label="设备数量">
|
||||||
<el-input-number
|
<el-input-number v-model="state.form.supportDeviceNumber" controls-position="right" :min="1" :step="1"
|
||||||
v-model="state.form.supportDeviceNumber"
|
step-strictly></el-input-number>
|
||||||
controls-position="right"
|
|
||||||
:min="1"
|
|
||||||
:step="1"
|
|
||||||
step-strictly
|
|
||||||
></el-input-number>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="外卖起送金额">
|
<!-- <el-form-item label="外卖起送金额">
|
||||||
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||||
:min="0"></el-input-number>
|
:min="0"></el-input-number>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="店铺地址" prop="districts">
|
<el-form-item label="店铺地址" prop="districts">
|
||||||
<AddressSelect
|
<AddressSelect v-model:prov="state.form.provinces" v-model:city="state.form.cities"
|
||||||
v-model:prov="state.form.provinces"
|
v-model:area="state.form.districts"></AddressSelect>
|
||||||
v-model:city="state.form.cities"
|
|
||||||
v-model:area="state.form.districts"
|
|
||||||
></AddressSelect>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@@ -204,18 +134,10 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form-item> -->
|
</el-form-item> -->
|
||||||
<el-form-item label="店铺详细地址">
|
<el-form-item label="店铺详细地址">
|
||||||
<el-input
|
<el-input type="textarea" v-model="state.form.address" placeholder="请输入门店详细地址"></el-input>
|
||||||
type="textarea"
|
|
||||||
v-model="state.form.address"
|
|
||||||
placeholder="请输入门店详细地址"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="店铺简介">
|
<el-form-item label="店铺简介">
|
||||||
<el-input
|
<el-input type="textarea" v-model="state.form.detail" placeholder="请输入店铺简介"></el-input>
|
||||||
type="textarea"
|
|
||||||
v-model="state.form.detail"
|
|
||||||
placeholder="请输入店铺简介"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="状态">
|
<el-form-item label="状态">
|
||||||
<el-radio-group v-model="state.form.status">
|
<el-radio-group v-model="state.form.status">
|
||||||
@@ -225,12 +147,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<el-dialog
|
<el-dialog title="选择地址" v-model="state.showLocation" :modal="false" :modal-append-to-body="false">
|
||||||
title="选择地址"
|
|
||||||
v-model="state.showLocation"
|
|
||||||
:modal="false"
|
|
||||||
:modal-append-to-body="false"
|
|
||||||
>
|
|
||||||
<div class="map_box">
|
<div class="map_box">
|
||||||
<div class="map">
|
<div class="map">
|
||||||
<el-amap ref="map" :center="state.amapOptions.center" @init="mapInit">
|
<el-amap ref="map" :center="state.amapOptions.center" @init="mapInit">
|
||||||
@@ -238,13 +155,8 @@
|
|||||||
</el-amap>
|
</el-amap>
|
||||||
</div>
|
</div>
|
||||||
<div class="search_box">
|
<div class="search_box">
|
||||||
<el-input
|
<el-input v-model="state.searchOption.keyword" placeholder="请输入关键字" @focus="state.searchOption.focus = true"
|
||||||
v-model="state.searchOption.keyword"
|
@blur="autoCompleteSearchBlur" @input="autoCompleteSearch(state.searchOption.keyword)">
|
||||||
placeholder="请输入关键字"
|
|
||||||
@focus="state.searchOption.focus = true"
|
|
||||||
@blur="autoCompleteSearchBlur"
|
|
||||||
@input="autoCompleteSearch(state.searchOption.keyword)"
|
|
||||||
>
|
|
||||||
<template #append>
|
<template #append>
|
||||||
<el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)">
|
<el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)">
|
||||||
搜索
|
搜索
|
||||||
@@ -252,12 +164,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<div class="list" v-if="state.searchOption.focus && state.searchOption.show">
|
<div class="list" v-if="state.searchOption.focus && state.searchOption.show">
|
||||||
<div
|
<div class="item" @click="autoCompleteListClick(item)" v-for="item in state.autoCompleteList"
|
||||||
class="item"
|
:key="item.id">
|
||||||
@click="autoCompleteListClick(item)"
|
|
||||||
v-for="item in state.autoCompleteList"
|
|
||||||
:key="item.id"
|
|
||||||
>
|
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -288,11 +196,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<el-dialog title="坐标搜索" v-model="latShow" width="60vw">
|
<el-dialog title="坐标搜索" v-model="latShow" width="60vw">
|
||||||
<iframe
|
<iframe style="width: 100%; height: 60vh" src="https://lbs.baidu.com/maptool/getpoint" frameborder="0"></iframe>
|
||||||
style="width: 100%; height: 60vh"
|
|
||||||
src="https://lbs.baidu.com/maptool/getpoint"
|
|
||||||
frameborder="0"
|
|
||||||
></iframe>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="latShow = false">取消</el-button>
|
<el-button @click="latShow = false">取消</el-button>
|
||||||
@@ -311,6 +215,7 @@ import { initMapLoad } from "@/utils/mapLoadUtil";
|
|||||||
import { ElNotification } from "element-plus";
|
import { ElNotification } from "element-plus";
|
||||||
// { geocode, ShopApi.getList }
|
// { geocode, ShopApi.getList }
|
||||||
import ShopApi from "@/api/account/shop";
|
import ShopApi from "@/api/account/shop";
|
||||||
|
import activeDate from "./activeDate.vue";
|
||||||
|
|
||||||
const latShow = ref(false);
|
const latShow = ref(false);
|
||||||
const validateLogo = (rule, value, callback) => {
|
const validateLogo = (rule, value, callback) => {
|
||||||
@@ -333,7 +238,7 @@ async function latConfirm() {
|
|||||||
state.form.lat = latLng[1];
|
state.form.lat = latLng[1];
|
||||||
state.form.lng = latLng[0];
|
state.form.lng = latLng[0];
|
||||||
latShow.value = false;
|
latShow.value = false;
|
||||||
} else [ElMessage.error("请搜索地址后复制经纬度")];
|
} else[ElMessage.error("请搜索地址后复制经纬度")];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// 捕获异常(用户拒绝权限、浏览器不支持、非交互上下文等)
|
// 捕获异常(用户拒绝权限、浏览器不支持、非交互上下文等)
|
||||||
console.error("获取剪贴板失败:", err);
|
console.error("获取剪贴板失败:", err);
|
||||||
@@ -360,7 +265,8 @@ const state = reactive({
|
|||||||
tubeType: 0,
|
tubeType: 0,
|
||||||
registerType: "before",
|
registerType: "before",
|
||||||
profiles: "release",
|
profiles: "release",
|
||||||
activateCode: "",
|
activateDuration: "", // 激活时长
|
||||||
|
activateAmount: "", // 激活费用
|
||||||
accountName: "",
|
accountName: "",
|
||||||
accountPwd: "",
|
accountPwd: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
@@ -381,11 +287,11 @@ const state = reactive({
|
|||||||
type: "",
|
type: "",
|
||||||
resetForm: "",
|
resetForm: "",
|
||||||
rules: {
|
rules: {
|
||||||
activateCode: [
|
activateDuration: [
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: "请输入激活码",
|
message: "请选择激活时长",
|
||||||
trigger: "blur",
|
trigger: "change",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
shopName: [
|
shopName: [
|
||||||
@@ -458,6 +364,25 @@ const state = reactive({
|
|||||||
trigger: "change",
|
trigger: "change",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
// 密码长度6-18位,需包含字母、数字、特殊符号中至少两种
|
||||||
|
accountPwd: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请输入登录密码",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
min: 6,
|
||||||
|
max: 18,
|
||||||
|
message: "密码长度应为6-18位",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^(?![0-9]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,}$/,
|
||||||
|
message: "密码需包含字母、数字、特殊符号中至少两种",
|
||||||
|
trigger: "blur",
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
files: [],
|
files: [],
|
||||||
@@ -561,6 +486,7 @@ function show(obj, type) {
|
|||||||
if (obj && obj.id) {
|
if (obj && obj.id) {
|
||||||
console.log(obj);
|
console.log(obj);
|
||||||
state.form = { ...obj };
|
state.form = { ...obj };
|
||||||
|
state.form.accountName = obj.account ? obj.account : "";
|
||||||
}
|
}
|
||||||
if (obj && obj.mainId) {
|
if (obj && obj.mainId) {
|
||||||
Object.assign(state.form, obj);
|
Object.assign(state.form, obj);
|
||||||
@@ -730,6 +656,7 @@ defineExpose({
|
|||||||
.amap-sug-result {
|
.amap-sug-result {
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tips {
|
.tips {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="24">
|
||||||
<el-col :span="3">
|
<el-col :span="4">
|
||||||
<el-input
|
<el-input v-model="state.query.name" clearable placeholder="请输入店铺名称" style="width: 100%" class="filter-item"
|
||||||
v-model="state.query.name"
|
@keyup.enter="getTableData" />
|
||||||
clearable
|
|
||||||
placeholder="请输入店铺名称"
|
|
||||||
style="width: 100%"
|
|
||||||
class="filter-item"
|
|
||||||
@keyup.enter="getTableData"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="4">
|
||||||
<el-input
|
<el-input v-model="state.query.phone" clearable placeholder="请输入手机号" style="width: 100%" class="filter-item"
|
||||||
v-model="state.query.phone"
|
@keyup.enter="getTableData" />
|
||||||
clearable
|
|
||||||
placeholder="请输入手机号"
|
|
||||||
style="width: 100%"
|
|
||||||
class="filter-item"
|
|
||||||
@keyup.enter="getTableData"
|
|
||||||
/>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="4">
|
||||||
<el-select v-model="state.query.status" placeholder="请选择店铺状态" style="width: 100%">
|
<el-select v-model="state.query.status" placeholder="请选择店铺状态" style="width: 100%">
|
||||||
<el-option
|
<el-option v-for="item in state.status" :key="item.type" :label="item.label" :value="item.type" />
|
||||||
v-for="item in state.status"
|
|
||||||
:key="item.type"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.type"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="4">
|
||||||
<el-select
|
<el-select v-model="state.query.profiles" placeholder="请选择商户版本" style="width: 100%">
|
||||||
v-model="state.query.profiles"
|
<el-option v-for="item in state.profiles" :key="item.type" :label="item.label" :value="item.type" />
|
||||||
placeholder="请选择商户版本"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in state.profiles"
|
|
||||||
:key="item.type"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.type"
|
|
||||||
/>
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="3">
|
<el-col :span="4">
|
||||||
<el-button type="primary" @click="getTableData">查询</el-button>
|
<el-button type="primary" @click="getTableData">查询</el-button>
|
||||||
<el-button @click="resetHandle">重置</el-button>
|
<el-button @click="resetHandle">重置</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -60,10 +34,8 @@
|
|||||||
<el-table-column label="店铺信息" width="200">
|
<el-table-column label="店铺信息" width="200">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="shop_info">
|
<div class="shop_info">
|
||||||
<el-image
|
<el-image :src="scope.row.logo"
|
||||||
:src="scope.row.logo"
|
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef">
|
||||||
style="width: 50px; height: 50px; border-radius: 4px; background-color: #efefef"
|
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="img_error">
|
<div class="img_error">
|
||||||
<i class="icon el-icon-document-delete" />
|
<i class="icon el-icon-document-delete" />
|
||||||
@@ -73,16 +45,16 @@
|
|||||||
<div class="info">
|
<div class="info">
|
||||||
<span>{{ scope.row.shopName }}</span>
|
<span>{{ scope.row.shopName }}</span>
|
||||||
<div class="tag_wrap">
|
<div class="tag_wrap">
|
||||||
<el-tag v-if="scope.row.profiles == 'no'" type="info" effect="dark">
|
<el-tag v-if="scope.row.profiles == 'no'" type="info" disable-transitions effect="dark">
|
||||||
未激活
|
未激活
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="scope.row.profiles == 'probation'" type="warning" effect="dark">
|
<el-tag v-if="scope.row.profiles == 'probation'" type="warning" disable-transitions effect="dark">
|
||||||
试用
|
试用
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="scope.row.profiles == 'release'" type="success" effect="dark">
|
<el-tag v-if="scope.row.profiles == 'release'" type="success" disable-transitions effect="dark">
|
||||||
正式
|
正式
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="scope.row.isWxMaIndependent" type="primary" effect="dark">
|
<el-tag v-if="scope.row.isWxMaIndependent" type="primary" disable-transitions effect="dark">
|
||||||
独立小程序
|
独立小程序
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -154,7 +126,7 @@
|
|||||||
支付配置
|
支付配置
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
<el-dropdown-item :command="2">续费记录</el-dropdown-item>
|
<el-dropdown-item :command="2">续费记录</el-dropdown-item>
|
||||||
<el-dropdown-item :command="3">前往店铺</el-dropdown-item>
|
<!-- <el-dropdown-item :command="3">前往店铺</el-dropdown-item> -->
|
||||||
<el-dropdown-item :command="4">重置密码</el-dropdown-item>
|
<el-dropdown-item :command="4">重置密码</el-dropdown-item>
|
||||||
<el-dropdown-item divided :command="5">删除</el-dropdown-item>
|
<el-dropdown-item divided :command="5">删除</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
@@ -165,19 +137,18 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="head-container">
|
<div class="head-container">
|
||||||
<el-pagination
|
<el-pagination v-model:current-page="state.tableData.page" v-model:page-size="state.tableData.size"
|
||||||
v-model:current-page="state.tableData.page"
|
:total="state.tableData.total" :page-sizes="[10, 20, 30, 50, 100]"
|
||||||
v-model:page-size="state.tableData.size"
|
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
|
||||||
:total="state.tableData.total"
|
|
||||||
:page-sizes="[10, 20, 30, 50, 100]"
|
|
||||||
layout="total, sizes , prev, pager ,next, jumper "
|
|
||||||
@current-change="paginationChange"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<addShop ref="refAddShop" @success="getTableData" />
|
<addShop ref="refAddShop" @success="getTableData" />
|
||||||
<!-- <detailModal ref="refDetailModal" /> -->
|
<!-- <detailModal ref="refDetailModal" /> -->
|
||||||
<!-- 激活码 -->
|
<!-- 激活码 -->
|
||||||
<activateCode ref="refActivateCode" @success="getTableData" />
|
<activateCode ref="refActivateCode" @success="getTableData" />
|
||||||
|
<!-- 重置密码 -->
|
||||||
|
<resetPassword ref="refResetPasswordRef" @success="getTableData" />
|
||||||
|
<!-- 激活记录 -->
|
||||||
|
<activateRecord ref="refActivateRecordRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -189,6 +160,12 @@ import { ElNotification, ElMessageBox } from "element-plus";
|
|||||||
import addShop from "./components/addShop.vue";
|
import addShop from "./components/addShop.vue";
|
||||||
import detailModal from "./components/detailModal.vue";
|
import detailModal from "./components/detailModal.vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import resetPassword from "@/components/resetPassword/index.vue";
|
||||||
|
import activateRecord from "./components/activeteRecord.vue";
|
||||||
|
|
||||||
|
const refActivateRecordRef = ref(null);
|
||||||
|
|
||||||
|
const refResetPasswordRef = ref(null);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -242,7 +219,7 @@ onMounted(() => {
|
|||||||
const refDetailModal = ref(null);
|
const refDetailModal = ref(null);
|
||||||
function dropdownClick(e, row) {
|
function dropdownClick(e, row) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
console.log(row);
|
// console.log(row);
|
||||||
if (e == 0) {
|
if (e == 0) {
|
||||||
refAddShop.value.show({ mainId: row.id, shopType: row.shopType, isHeadShop: 0 }, "addBranch");
|
refAddShop.value.show({ mainId: row.id, shopType: row.shopType, isHeadShop: 0 }, "addBranch");
|
||||||
|
|
||||||
@@ -264,6 +241,15 @@ function dropdownClick(e, row) {
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (e == 2) {
|
||||||
|
// 续费记录
|
||||||
|
refActivateRecordRef.value.open(row);
|
||||||
|
}
|
||||||
|
if (e == 4) {
|
||||||
|
// 重置密码
|
||||||
|
// console.log('重置密码', row);
|
||||||
|
refResetPasswordRef.value.show(row);
|
||||||
|
}
|
||||||
if (e == 5) {
|
if (e == 5) {
|
||||||
ElMessageBox.confirm("是否确认删除该店铺?", "提示", {
|
ElMessageBox.confirm("是否确认删除该店铺?", "提示", {
|
||||||
confirmButtonText: "确认",
|
confirmButtonText: "确认",
|
||||||
@@ -278,7 +264,7 @@ function dropdownClick(e, row) {
|
|||||||
});
|
});
|
||||||
getTableData();
|
getTableData();
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => { });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,12 @@
|
|||||||
<div class="t">{{ route.query.shopName }} | 支付配置</div>
|
<div class="t">{{ route.query.shopName }} | 支付配置</div>
|
||||||
<div class="intro">管理您的支付渠道和进件信息</div>
|
<div class="intro">管理您的支付渠道和进件信息</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<!-- <div class="center">
|
||||||
<el-text size="large">当前模式:</el-text>
|
<el-text size="large">当前模式:</el-text>
|
||||||
<el-radio-group size="large" :model-value="payModel" @change="handleRadioChange">
|
<el-radio-group size="large" :model-value="payModel" @change="handleRadioChange">
|
||||||
<el-radio :label="item.label" :value="item.value" v-for="item in tabList" :key="item.value"></el-radio>
|
<el-radio :label="item.label" :value="item.value" v-for="item in tabList" :key="item.value"></el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="gyq_content row mt14">
|
<div class="gyq_content row mt14">
|
||||||
<tabHeader v-model="tabActiveIndex" :list="tabList" />
|
<tabHeader v-model="tabActiveIndex" :list="tabList" />
|
||||||
@@ -39,10 +39,10 @@ const router = useRouter()
|
|||||||
const payModel = ref('')
|
const payModel = ref('')
|
||||||
const tabActiveIndex = ref(0)
|
const tabActiveIndex = ref(0)
|
||||||
const tabList = ref([
|
const tabList = ref([
|
||||||
{
|
// {
|
||||||
label: '支付进件',
|
// label: '支付进件',
|
||||||
value: 'native'
|
// value: 'native'
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
label: '聚合支付',
|
label: '聚合支付',
|
||||||
value: 'poly'
|
value: 'poly'
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ const contentConfig: IContentConfig = {
|
|||||||
align: "center",
|
align: "center",
|
||||||
prop: "code",
|
prop: "code",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "员工角色",
|
||||||
|
align: "center",
|
||||||
|
prop: "roleName",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "最大优惠金额",
|
label: "最大优惠金额",
|
||||||
align: "center",
|
align: "center",
|
||||||
@@ -55,6 +60,7 @@ const contentConfig: IContentConfig = {
|
|||||||
label: "操作",
|
label: "操作",
|
||||||
align: "center",
|
align: "center",
|
||||||
templet: "tool",
|
templet: "tool",
|
||||||
|
width: 240,
|
||||||
operat: ["edit", "delete",
|
operat: ["edit", "delete",
|
||||||
{
|
{
|
||||||
name: "change_pwd",
|
name: "change_pwd",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type { IModalConfig } from "@/components/CURD/types";
|
|||||||
const modalConfig: IModalConfig<payType> = {
|
const modalConfig: IModalConfig<payType> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
dialog: {
|
dialog: {
|
||||||
title: "添加支付方式",
|
title: "添加收银方式",
|
||||||
width: 800,
|
width: 800,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
},
|
},
|
||||||
@@ -23,12 +23,12 @@ const modalConfig: IModalConfig<payType> = {
|
|||||||
formItems: [
|
formItems: [
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "支付类型",
|
label: "收银类型",
|
||||||
prop: "payType",
|
prop: "payType",
|
||||||
rules: [{ required: true, message: "请选择支付类型", trigger: "blur" }],
|
rules: [{ required: true, message: "请选择收银类型", trigger: "blur" }],
|
||||||
type: "select",
|
type: "select",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择支付类型",
|
placeholder: "请选择收银类型",
|
||||||
},
|
},
|
||||||
options: returnOptions("payType"),
|
options: returnOptions("payType"),
|
||||||
col: {
|
col: {
|
||||||
@@ -38,11 +38,11 @@ const modalConfig: IModalConfig<payType> = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "input",
|
type: "input",
|
||||||
label: "支付名称",
|
label: "收银名称",
|
||||||
prop: "payName",
|
prop: "payName",
|
||||||
rules: [{ required: true, message: "请输入支付名称", trigger: "blur" }],
|
rules: [{ required: true, message: "请输入收银名称", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入支付名称",
|
placeholder: "请输入收银名称",
|
||||||
},
|
},
|
||||||
col: {
|
col: {
|
||||||
xs: 24,
|
xs: 24,
|
||||||
|
|||||||
@@ -1,64 +1,72 @@
|
|||||||
import Api from "@/api/account/payType";
|
import Api from "@/api/account/payType";
|
||||||
import type { IContentConfig } from "@/components/CURD/types";
|
import type { IContentConfig } from "@/components/CURD/types";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
const contentConfig: IContentConfig = {
|
const contentConfig: IContentConfig = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
|
// ✅ 开启拖动排序
|
||||||
|
rowDraggable: true,
|
||||||
table: {
|
table: {
|
||||||
border: true,
|
border: true,
|
||||||
highlightCurrentRow: true,
|
highlightCurrentRow: true,
|
||||||
|
|
||||||
|
// ✅ 拖动完成后调用接口
|
||||||
|
onRowDrop: async ({ row, oldIndex, newIndex }) => {
|
||||||
|
try {
|
||||||
|
await Api.sort({
|
||||||
|
id: row.id,
|
||||||
|
oldIndex,
|
||||||
|
newIndex,
|
||||||
|
});
|
||||||
|
ElMessage.success("排序成功");
|
||||||
|
} catch (e) {
|
||||||
|
ElMessage.error("排序失败");
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
pagination: {
|
pagination: false,
|
||||||
background: true,
|
|
||||||
layout: "prev,pager,next,jumper,total,sizes",
|
|
||||||
pageSize: 20,
|
|
||||||
pageSizes: [10, 20, 30, 50],
|
|
||||||
},
|
|
||||||
indexAction: function (params) {
|
indexAction: function (params) {
|
||||||
return Api.getList();
|
return Api.getList();
|
||||||
},
|
},
|
||||||
modifyAction: async function (data) {
|
modifyAction: async function (data) {
|
||||||
const res = await Api.edit(data);
|
const res = await Api.edit(data);
|
||||||
ElMessage.success(res ? '修改成功' : '修改失败');
|
ElMessage.success(res ? "修改成功" : "修改失败");
|
||||||
return res
|
return res;
|
||||||
},
|
},
|
||||||
pk: "id",
|
pk: "id",
|
||||||
toolbar: ["add"],
|
toolbar: [],
|
||||||
defaultToolbar: ["refresh", "filter", "search"],
|
defaultToolbar: ["refresh", "filter", "search"],
|
||||||
cols: [
|
cols: [
|
||||||
// { type: "selection", width: 50, align: "center" },
|
// ✅ 拖动图标列
|
||||||
|
{
|
||||||
|
label: "排序",
|
||||||
|
align: "center",
|
||||||
|
width: 60,
|
||||||
|
templet: "custom", // 拖动把手
|
||||||
|
prop: "sort",
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "图标",
|
label: "图标",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "icon",
|
prop: "icon",
|
||||||
templet: 'image'
|
templet: "image",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "支付方式",
|
label: "收银方式",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "payName",
|
prop: "payName",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "支付类型",
|
label: "收银类型",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "payType",
|
prop: "payType",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
label: "开钱箱权限",
|
|
||||||
align: "center",
|
|
||||||
prop: "isOpenCashDrawer",
|
|
||||||
templet: 'switch',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: "是否显示",
|
label: "是否显示",
|
||||||
align: "center",
|
align: "center",
|
||||||
prop: "isDisplay",
|
prop: "isDisplay",
|
||||||
templet: 'switch',
|
templet: "switch",
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "条件排序",
|
|
||||||
align: "center",
|
|
||||||
prop: "sorts",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "操作",
|
label: "操作",
|
||||||
@@ -66,9 +74,9 @@ const contentConfig: IContentConfig = {
|
|||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 280,
|
width: 280,
|
||||||
templet: "tool",
|
templet: "tool",
|
||||||
operat: ["edit"],
|
operat: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default contentConfig;
|
export default contentConfig;
|
||||||
@@ -7,7 +7,7 @@ import type { IModalConfig } from "@/components/CURD/types";
|
|||||||
const modalConfig: IModalConfig<payType> = {
|
const modalConfig: IModalConfig<payType> = {
|
||||||
pageName: "sys:user",
|
pageName: "sys:user",
|
||||||
dialog: {
|
dialog: {
|
||||||
title: "编辑支付方式",
|
title: "编辑收银方式",
|
||||||
width: 800,
|
width: 800,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
},
|
},
|
||||||
@@ -23,12 +23,12 @@ const modalConfig: IModalConfig<payType> = {
|
|||||||
formItems: [
|
formItems: [
|
||||||
|
|
||||||
{
|
{
|
||||||
label: "支付类型",
|
label: "收银类型",
|
||||||
prop: "payType",
|
prop: "payType",
|
||||||
rules: [{ required: true, message: "请选择支付类型", trigger: "blur" }],
|
rules: [{ required: true, message: "请选择收银类型", trigger: "blur" }],
|
||||||
type: "select",
|
type: "select",
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请选择支付类型",
|
placeholder: "请选择收银类型",
|
||||||
},
|
},
|
||||||
options: returnOptions("payType"),
|
options: returnOptions("payType"),
|
||||||
col: {
|
col: {
|
||||||
@@ -38,11 +38,11 @@ const modalConfig: IModalConfig<payType> = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "input",
|
type: "input",
|
||||||
label: "支付名称",
|
label: "收银名称",
|
||||||
prop: "payName",
|
prop: "payName",
|
||||||
rules: [{ required: true, message: "请输入支付名称", trigger: "blur" }],
|
rules: [{ required: true, message: "请输入收银名称", trigger: "blur" }],
|
||||||
attrs: {
|
attrs: {
|
||||||
placeholder: "请输入支付名称",
|
placeholder: "请输入收银名称",
|
||||||
},
|
},
|
||||||
col: {
|
col: {
|
||||||
xs: 24,
|
xs: 24,
|
||||||
|
|||||||
123
src/views/system-setting/pay-types/index copy.vue
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<!-- 列表 -->
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<!-- <page-search
|
||||||
|
ref="searchRef"
|
||||||
|
:search-config="searchConfig"
|
||||||
|
@query-click="handleQueryClick"
|
||||||
|
@reset-click="handleResetClick"
|
||||||
|
/> -->
|
||||||
|
<!-- 列表 -->
|
||||||
|
<page-content
|
||||||
|
ref="contentRef"
|
||||||
|
:content-config="contentConfig"
|
||||||
|
@add-click="handleAddClick"
|
||||||
|
@edit-click="handleEditClick"
|
||||||
|
@export-click="handleExportClick"
|
||||||
|
@search-click="handleSearchClick"
|
||||||
|
@toolbar-click="handleToolbarClick"
|
||||||
|
@operat-click="handleOperatClick"
|
||||||
|
@filter-change="handleFilterChange"
|
||||||
|
>
|
||||||
|
<template #status="scope">
|
||||||
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
<template #options="scope">
|
||||||
|
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
|
</template>
|
||||||
|
<template #switch="scope">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row[scope.prop]"
|
||||||
|
disabled
|
||||||
|
:inactive-value="0"
|
||||||
|
:active-value="1"
|
||||||
|
></el-switch>
|
||||||
|
</template>
|
||||||
|
<template #mobile="scope">
|
||||||
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
|
<copy-button
|
||||||
|
v-if="scope.row[scope.prop]"
|
||||||
|
:text="scope.row[scope.prop]"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</page-content>
|
||||||
|
|
||||||
|
<!-- 新增 -->
|
||||||
|
<page-modal
|
||||||
|
ref="addModalRef"
|
||||||
|
:modal-config="addModalConfig"
|
||||||
|
@submit-click="handleSubmitClick"
|
||||||
|
></page-modal>
|
||||||
|
|
||||||
|
<!-- 编辑 -->
|
||||||
|
<page-modal
|
||||||
|
ref="editModalRef"
|
||||||
|
:modal-config="editModalConfig"
|
||||||
|
@submit-click="handleSubmitClick"
|
||||||
|
></page-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import VersionApi from "@/api/system/version";
|
||||||
|
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||||
|
import usePage from "@/components/CURD/usePage";
|
||||||
|
import addModalConfig from "./config/add";
|
||||||
|
import contentConfig from "./config/content";
|
||||||
|
import editModalConfig from "./config/edit";
|
||||||
|
import searchConfig from "./config/search";
|
||||||
|
import { returnOptionsLabel } from "./config/config";
|
||||||
|
|
||||||
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
|
const shopUser = useUserStoreHook();
|
||||||
|
console.log(shopUser.isAdmin);
|
||||||
|
if (shopUser.isAdmin) {
|
||||||
|
contentConfig.toolbar = ["add"];
|
||||||
|
contentConfig.cols[contentConfig.cols.length - 1].operat = ["edit"];
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
searchRef,
|
||||||
|
contentRef,
|
||||||
|
addModalRef,
|
||||||
|
editModalRef,
|
||||||
|
handleQueryClick,
|
||||||
|
handleResetClick,
|
||||||
|
// handleAddClick,
|
||||||
|
// handleEditClick,
|
||||||
|
handleSubmitClick,
|
||||||
|
handleExportClick,
|
||||||
|
handleSearchClick,
|
||||||
|
handleFilterChange,
|
||||||
|
} = usePage();
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
async function handleAddClick() {
|
||||||
|
addModalRef.value?.setModalVisible();
|
||||||
|
// addModalConfig.formItems[2]!.attrs!.data =
|
||||||
|
}
|
||||||
|
// 编辑
|
||||||
|
async function handleEditClick(row: IObject) {
|
||||||
|
editModalRef.value?.handleDisabled(false);
|
||||||
|
editModalRef.value?.setModalVisible();
|
||||||
|
// 根据id获取数据进行填充
|
||||||
|
console.log(row);
|
||||||
|
editModalRef.value?.setFormData({ ...row });
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
// 其他工具栏
|
||||||
|
function handleToolbarClick(name: string) {
|
||||||
|
console.log(name);
|
||||||
|
if (name === "custom1") {
|
||||||
|
ElMessage.success("点击了自定义1按钮");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 其他操作列
|
||||||
|
async function handleOperatClick(data: IOperatData) {
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -9,42 +9,56 @@
|
|||||||
@reset-click="handleResetClick"
|
@reset-click="handleResetClick"
|
||||||
/> -->
|
/> -->
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<page-content
|
<VueDraggable
|
||||||
ref="contentRef"
|
v-model="list"
|
||||||
:content-config="contentConfig"
|
target="tbody"
|
||||||
@add-click="handleAddClick"
|
handle=".sort-span"
|
||||||
@edit-click="handleEditClick"
|
:animation="150"
|
||||||
@export-click="handleExportClick"
|
ghost-class="draggable-ghost"
|
||||||
@search-click="handleSearchClick"
|
@end="onDragEnd"
|
||||||
@toolbar-click="handleToolbarClick"
|
|
||||||
@operat-click="handleOperatClick"
|
|
||||||
@filter-change="handleFilterChange"
|
|
||||||
>
|
>
|
||||||
<template #status="scope">
|
<page-content
|
||||||
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
ref="contentRef"
|
||||||
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
:content-config="contentConfig"
|
||||||
</el-tag>
|
@add-click="handleAddClick"
|
||||||
</template>
|
@edit-click="handleEditClick"
|
||||||
<template #options="scope">
|
@export-click="handleExportClick"
|
||||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
@search-click="handleSearchClick"
|
||||||
</template>
|
@toolbar-click="handleToolbarClick"
|
||||||
<template #switch="scope">
|
@operat-click="handleOperatClick"
|
||||||
<el-switch
|
@filter-change="handleFilterChange"
|
||||||
v-model="scope.row[scope.prop]"
|
>
|
||||||
disabled
|
<template #status="scope">
|
||||||
:inactive-value="0"
|
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
|
||||||
:active-value="1"
|
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
|
||||||
></el-switch>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
<template #mobile="scope">
|
<template #options="scope">
|
||||||
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||||
<copy-button
|
</template>
|
||||||
v-if="scope.row[scope.prop]"
|
<template #sort="scope">
|
||||||
:text="scope.row[scope.prop]"
|
<span class="sort-span">
|
||||||
style="margin-left: 2px"
|
<el-icon><Rank /></el-icon>
|
||||||
/>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</page-content>
|
<template #switch="scope">
|
||||||
|
<el-switch
|
||||||
|
v-model="scope.row[scope.prop]"
|
||||||
|
disabled
|
||||||
|
:inactive-value="0"
|
||||||
|
:active-value="1"
|
||||||
|
></el-switch>
|
||||||
|
</template>
|
||||||
|
<template #mobile="scope">
|
||||||
|
<el-text>{{ scope.row[scope.prop] }}</el-text>
|
||||||
|
<copy-button
|
||||||
|
v-if="scope.row[scope.prop]"
|
||||||
|
:text="scope.row[scope.prop]"
|
||||||
|
style="margin-left: 2px"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</page-content>
|
||||||
|
</VueDraggable>
|
||||||
|
|
||||||
<!-- 新增 -->
|
<!-- 新增 -->
|
||||||
<page-modal
|
<page-modal
|
||||||
@@ -63,7 +77,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import VersionApi from "@/api/system/version";
|
import PayTypeApi, { sortRequest } from "@/api/account/payType";
|
||||||
import type { IObject, IOperatData } from "@/components/CURD/types";
|
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||||
import usePage from "@/components/CURD/usePage";
|
import usePage from "@/components/CURD/usePage";
|
||||||
import addModalConfig from "./config/add";
|
import addModalConfig from "./config/add";
|
||||||
@@ -71,6 +85,15 @@ import contentConfig from "./config/content";
|
|||||||
import editModalConfig from "./config/edit";
|
import editModalConfig from "./config/edit";
|
||||||
import searchConfig from "./config/search";
|
import searchConfig from "./config/search";
|
||||||
import { returnOptionsLabel } from "./config/config";
|
import { returnOptionsLabel } from "./config/config";
|
||||||
|
import { VueDraggable } from "vue-draggable-plus";
|
||||||
|
|
||||||
|
import { useUserStoreHook } from "@/store/modules/user";
|
||||||
|
const shopUser = useUserStoreHook();
|
||||||
|
console.log(shopUser.isAdmin);
|
||||||
|
if (shopUser.isAdmin) {
|
||||||
|
contentConfig.toolbar = ["add"];
|
||||||
|
contentConfig.cols[contentConfig.cols.length - 1].operat = ["edit"];
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
searchRef,
|
searchRef,
|
||||||
@@ -86,6 +109,50 @@ const {
|
|||||||
handleSearchClick,
|
handleSearchClick,
|
||||||
handleFilterChange,
|
handleFilterChange,
|
||||||
} = usePage();
|
} = usePage();
|
||||||
|
// ✅ 拖拽只用这个 list
|
||||||
|
const list = ref([]);
|
||||||
|
|
||||||
|
// ✅ 监听表格数据,同步到拖拽列表
|
||||||
|
watch(
|
||||||
|
() => contentRef.value?.pageData,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
list.value = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// ✅ 拖拽结束 → 调用排序接口
|
||||||
|
// ==========================================
|
||||||
|
async function onDragEnd(e) {
|
||||||
|
console.log("拖拽结束===", e);
|
||||||
|
|
||||||
|
const { oldIndex, newIndex } = e;
|
||||||
|
if (oldIndex === newIndex) return;
|
||||||
|
console.log(oldIndex, newIndex);
|
||||||
|
|
||||||
|
// 当前拖动的行
|
||||||
|
const row = contentRef.value?.pageData[oldIndex];
|
||||||
|
const newRow = contentRef.value?.pageData[newIndex];
|
||||||
|
console.log(row, newRow);
|
||||||
|
// 目标排序号(newIndex + 1)
|
||||||
|
const targetSort = newRow.sorts;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await PayTypeApi.sort({
|
||||||
|
shopId: row.shopId, // 店铺ID
|
||||||
|
id: row.id, // 支付类型ID
|
||||||
|
targetSort: targetSort, // 目标位置排序
|
||||||
|
});
|
||||||
|
ElMessage.success("排序成功");
|
||||||
|
// 刷新列表
|
||||||
|
contentRef.value?.fetchPageData();
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage.error("排序失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
async function handleAddClick() {
|
async function handleAddClick() {
|
||||||
@@ -100,7 +167,6 @@ async function handleEditClick(row: IObject) {
|
|||||||
console.log(row);
|
console.log(row);
|
||||||
editModalRef.value?.setFormData({ ...row });
|
editModalRef.value?.setFormData({ ...row });
|
||||||
}
|
}
|
||||||
1;
|
|
||||||
// 其他工具栏
|
// 其他工具栏
|
||||||
function handleToolbarClick(name: string) {
|
function handleToolbarClick(name: string) {
|
||||||
console.log(name);
|
console.log(name);
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
<el-table-column label="挂账人" prop="debtor" />
|
<el-table-column label="挂账人" prop="debtor" />
|
||||||
<el-table-column label="手机号" prop="mobile" />
|
<el-table-column label="手机号" prop="mobile" />
|
||||||
<el-table-column label="已挂账金额(元)" prop="owedAmount" />
|
<el-table-column label="账户余额(元)" prop="accountBalance" />
|
||||||
<el-table-column label="可用挂账额度(元)" prop="remainingAmount" />
|
<el-table-column label="可用挂账额度(元)" prop="creditAmount" />
|
||||||
<el-table-column label="操作">
|
<el-table-column label="操作">
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<el-button type="text" @click="cellClick(scope.row)">选择</el-button>
|
<el-button type="text" @click="cellClick(scope.row)">选择</el-button>
|
||||||
@@ -52,8 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import creditApi from "@/api/order/credit";
|
import creditApi from "@/api/order/credit";
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="status" v-if="
|
<div class="status" v-if="
|
||||||
item.isSoldStock ||
|
item.isSoldStock ||
|
||||||
|
item.isSoldOut ||
|
||||||
!item.isSale ||
|
!item.isSale ||
|
||||||
!item.isSaleTime ||
|
!item.isSaleTime ||
|
||||||
(item.isStock && item.stockNumber * 1 <= 0)
|
(item.isStock && item.stockNumber * 1 <= 0)
|
||||||
@@ -37,8 +38,8 @@
|
|||||||
ElMessage.error('该商品不在可售时间内') ||
|
ElMessage.error('该商品不在可售时间内') ||
|
||||||
isProductAvailable(item.days, item.startTime, item.endTime)
|
isProductAvailable(item.days, item.startTime, item.endTime)
|
||||||
" v-else-if="!item.isSaleTime" iconClass="no-sale" color="#fff" size="60"></svg-icon>
|
" v-else-if="!item.isSaleTime" iconClass="no-sale" color="#fff" size="60"></svg-icon>
|
||||||
<svg-icon @click="ElMessage.error('该商品已售罄')" v-else-if="item.isSoldStock" iconClass="shouqing" color="#fff"
|
<svg-icon @click="ElMessage.error('该商品已售罄')" v-else-if="item.isSoldStock || item.isSoldOut" iconClass="shouqing"
|
||||||
size="60"></svg-icon>
|
color="#fff" size="60"></svg-icon>
|
||||||
<svg-icon @click="ElMessage.error('库存不足')" v-else-if="item.isStock && item.stockNumber * 1 <= 0"
|
<svg-icon @click="ElMessage.error('库存不足')" v-else-if="item.isStock && item.stockNumber * 1 <= 0"
|
||||||
iconClass="stock_null" color="#fff" size="60"></svg-icon>
|
iconClass="stock_null" color="#fff" size="60"></svg-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||