管理端细节修改
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
26
src/api/order/fince.ts
Normal file
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;
|
||||||
@@ -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>
|
||||||
@@ -861,10 +1007,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 +1075,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 +1110,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;
|
||||||
|
|||||||
305
src/components/importData/index copy.vue
Normal file
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() {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
1942
src/lib/goods.ts
1942
src/lib/goods.ts
File diff suppressed because it is too large
Load Diff
@@ -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
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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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' },
|
||||||
|
|||||||
98
src/views/order/index/components/GoodsListCollapse.vue
Normal file
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>
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,7 +74,7 @@ const contentConfig: IContentConfig = {
|
|||||||
fixed: "right",
|
fixed: "right",
|
||||||
width: 280,
|
width: 280,
|
||||||
templet: "tool",
|
templet: "tool",
|
||||||
operat: ["edit"],
|
operat: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
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>
|
||||||
@@ -53,7 +53,6 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import creditApi from "@/api/order/credit";
|
import creditApi from "@/api/order/credit";
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@@ -44,12 +44,23 @@
|
|||||||
<span class="u-font-14">部分抵扣</span>
|
<span class="u-font-14">部分抵扣</span>
|
||||||
</el-radio> -->
|
</el-radio> -->
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-input-number class="u-m-l-10" v-if="score.sel != -1" v-model="usePointsNumber" step-strictly
|
<el-input-number
|
||||||
:step="pointsRes.equivalentPoints" placeholder="请输入积分抵扣数量" :min="pointsRes.minDeductionPoints"
|
class="u-m-l-10"
|
||||||
:max="pointsRes.maxUsablePoints" :disabled="!pointsRes.usable"
|
v-if="score.sel != -1"
|
||||||
@change="pointsToMoney"></el-input-number>
|
v-model="usePointsNumber"
|
||||||
|
step-strictly
|
||||||
|
:step="pointsRes.equivalentPoints"
|
||||||
|
placeholder="请输入积分抵扣数量"
|
||||||
|
:min="pointsRes.minDeductionPoints"
|
||||||
|
:max="pointsRes.maxUsablePoints"
|
||||||
|
:disabled="!pointsRes.usable"
|
||||||
|
@change="pointsToMoney"
|
||||||
|
></el-input-number>
|
||||||
</div>
|
</div>
|
||||||
<p class="u-font-14 color-666 u-m-t-10" v-if="pointsRes.unusableReason && !pointsRes.usable">
|
<p
|
||||||
|
class="u-font-14 color-666 u-m-t-10"
|
||||||
|
v-if="pointsRes.unusableReason && !pointsRes.usable"
|
||||||
|
>
|
||||||
<span class="color-red">*</span>
|
<span class="color-red">*</span>
|
||||||
<span>{{ pointsRes.unusableReason }}</span>
|
<span>{{ pointsRes.unusableReason }}</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -70,10 +81,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="u-flex u-col-center u-m-t-20 no-wrap">
|
<div class="u-flex u-col-center u-m-t-20 no-wrap">
|
||||||
<span class="u-font-14 font-bold u-m-r-20">优惠券</span>
|
<span class="u-font-14 font-bold u-m-r-20">优惠券</span>
|
||||||
<div v-if="
|
<div
|
||||||
carts.orderCostSummary.fullReduction !== undefined &&
|
v-if="
|
||||||
carts.orderCostSummary.fullReduction.actualAmount > 0
|
carts.orderCostSummary.fullReduction !== undefined &&
|
||||||
" style="font-size: 14px; color: #555">
|
carts.orderCostSummary.fullReduction.actualAmount > 0
|
||||||
|
"
|
||||||
|
style="font-size: 14px; color: #555"
|
||||||
|
>
|
||||||
参与满减活动不可用优惠券!
|
参与满减活动不可用优惠券!
|
||||||
</div>
|
</div>
|
||||||
<div class="u-flex my-select" @click="openCoupon" v-else>
|
<div class="u-flex my-select" @click="openCoupon" v-else>
|
||||||
@@ -124,9 +138,14 @@
|
|||||||
<p class="u-font-16 font-bold u-m-r-20 font-bold u-flex">选择支付方式</p>
|
<p class="u-font-16 font-bold u-m-r-20 font-bold u-flex">选择支付方式</p>
|
||||||
<div class="u-m-t-20">
|
<div class="u-m-t-20">
|
||||||
<div>
|
<div>
|
||||||
<el-button v-for="(item, index) in payTypes.list" :key="index" size="large"
|
<el-button
|
||||||
:type="index == payTypes.sel ? 'primary' : ''" :disabled="canUsePayType(item)"
|
v-for="(item, index) in payTypes.list"
|
||||||
@click="changePayType(index)">
|
:key="index"
|
||||||
|
size="large"
|
||||||
|
:type="index == payTypes.sel ? 'primary' : ''"
|
||||||
|
:disabled="canUsePayType(item)"
|
||||||
|
@click="changePayType(index)"
|
||||||
|
>
|
||||||
{{ item.payName }}
|
{{ item.payName }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -213,20 +232,43 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 扫码 -->
|
<!-- 扫码 -->
|
||||||
<scanPay ref="refScanPay" :order="orderInfo" @confirm="refScanPayConfirm" @paysuccess="paysuccess"></scanPay>
|
<scanPay
|
||||||
|
ref="refScanPay"
|
||||||
|
:order="orderInfo"
|
||||||
|
@confirm="refScanPayConfirm"
|
||||||
|
@paysuccess="paysuccess"
|
||||||
|
></scanPay>
|
||||||
<!-- 打折 -->
|
<!-- 打折 -->
|
||||||
<discount ref="refDiscount" @confirm="discountConfirm"></discount>
|
<discount ref="refDiscount" @confirm="discountConfirm"></discount>
|
||||||
<!-- 优惠券 -->
|
<!-- 优惠券 -->
|
||||||
<popup-coupon ref="refCoupon" :user="carts.vipUser" @confirm="refCouponConfirm"></popup-coupon>
|
<popup-coupon ref="refCoupon" :user="carts.vipUser" @confirm="refCouponConfirm"></popup-coupon>
|
||||||
<!-- 挂账 -->
|
<!-- 挂账 -->
|
||||||
<chooseGuaZahng ref="refGuaZhang" :payMoney="currentpayMoney" @confirm="refGuaZhangConfirm"></chooseGuaZahng>
|
<chooseGuaZahng
|
||||||
|
ref="refGuaZhang"
|
||||||
|
:payMoney="currentpayMoney"
|
||||||
|
@confirm="refGuaZhangConfirm"
|
||||||
|
></chooseGuaZahng>
|
||||||
<!-- 扫码等待用户支付转台查询 -->
|
<!-- 扫码等待用户支付转台查询 -->
|
||||||
<el-dialog v-model="showCheckPayStauts" width="400" title="订单支付状态查询中..." :close-on-click-modal="false"
|
<el-dialog
|
||||||
:show-close="false">
|
v-model="showCheckPayStauts"
|
||||||
|
width="400"
|
||||||
|
title="订单支付状态查询中..."
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:show-close="false"
|
||||||
|
>
|
||||||
<div class="pay_status_content">
|
<div class="pay_status_content">
|
||||||
<div class="loading" v-loading="checkPayStautsLoading" element-loading-text="用户支付中..."></div>
|
<div
|
||||||
|
class="loading"
|
||||||
|
v-loading="checkPayStautsLoading"
|
||||||
|
element-loading-text="用户支付中..."
|
||||||
|
></div>
|
||||||
<div class="btn">
|
<div class="btn">
|
||||||
<el-button style="width: 100%" :disabled="!closeState" type="primary" @click="resetScanCode">
|
<el-button
|
||||||
|
style="width: 100%"
|
||||||
|
:disabled="!closeState"
|
||||||
|
type="primary"
|
||||||
|
@click="resetScanCode"
|
||||||
|
>
|
||||||
<span v-if="!closeState">{{ closeStateTime }}秒后可重新扫码</span>
|
<span v-if="!closeState">{{ closeStateTime }}秒后可重新扫码</span>
|
||||||
<span v-else>重新扫码</span>
|
<span v-else>重新扫码</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -262,7 +304,7 @@ import discount from "./discount.vue";
|
|||||||
import { ElLoading } from "element-plus";
|
import { ElLoading } from "element-plus";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
import { BigNumber } from "bignumber.js";
|
import { BigNumber } from "bignumber.js";
|
||||||
import { onUnmounted } from 'vue'
|
import { onUnmounted } from "vue";
|
||||||
|
|
||||||
// 配置BigNumber精度
|
// 配置BigNumber精度
|
||||||
BigNumber.set({
|
BigNumber.set({
|
||||||
@@ -272,7 +314,7 @@ BigNumber.set({
|
|||||||
//挂账
|
//挂账
|
||||||
const refGuaZhang = ref();
|
const refGuaZhang = ref();
|
||||||
function refGuaZhangConfirm(guazhangRen) {
|
function refGuaZhangConfirm(guazhangRen) {
|
||||||
payOrder("arrears", true, guazhangRen);
|
payOrder("virtual", true, guazhangRen);
|
||||||
}
|
}
|
||||||
function refGuaZhangShow() {
|
function refGuaZhangShow() {
|
||||||
refGuaZhang.value.open();
|
refGuaZhang.value.open();
|
||||||
@@ -377,7 +419,7 @@ function discountShow(e) {
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
table: {
|
table: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { },
|
default: () => {},
|
||||||
},
|
},
|
||||||
user: {
|
user: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@@ -391,7 +433,7 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
orderInfo: {
|
orderInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => { },
|
default: () => {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -506,7 +548,16 @@ async function pointsInit() {
|
|||||||
computedMax = Math.floor(computedMax / eq) * eq;
|
computedMax = Math.floor(computedMax / eq) * eq;
|
||||||
}
|
}
|
||||||
res.maxUsablePoints = computedMax;
|
res.maxUsablePoints = computedMax;
|
||||||
console.debug("pointsInit debug:", { finalPay: finalPay, basePay: basePay, eq, rawMaxRatio, maxRatio, maxByMoney, userPoints, computedMax });
|
console.debug("pointsInit debug:", {
|
||||||
|
finalPay: finalPay,
|
||||||
|
basePay: basePay,
|
||||||
|
eq,
|
||||||
|
rawMaxRatio,
|
||||||
|
maxRatio,
|
||||||
|
maxByMoney,
|
||||||
|
userPoints,
|
||||||
|
computedMax,
|
||||||
|
});
|
||||||
// 最小抵扣积分为配置值或等于换算比
|
// 最小抵扣积分为配置值或等于换算比
|
||||||
res.minDeductionPoints = pointsConfig?.minDeductionPoints || eq;
|
res.minDeductionPoints = pointsConfig?.minDeductionPoints || eq;
|
||||||
if (res.maxUsablePoints < res.minDeductionPoints) {
|
if (res.maxUsablePoints < res.minDeductionPoints) {
|
||||||
@@ -565,7 +616,10 @@ function pointsToMoney(val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 计算抵扣金额(元),向下保留两位
|
// 计算抵扣金额(元),向下保留两位
|
||||||
const money = new BigNumber(pts).div(cfg.equivalentPoints).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
const money = new BigNumber(pts)
|
||||||
|
.div(cfg.equivalentPoints)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_DOWN)
|
||||||
|
.toNumber();
|
||||||
|
|
||||||
// 再次校验不超过允许的最大抵扣金额(基于比例或门槛)
|
// 再次校验不超过允许的最大抵扣金额(基于比例或门槛)
|
||||||
let finalPay = Number(carts.orderCostSummary.finalPayAmount) || 0;
|
let finalPay = Number(carts.orderCostSummary.finalPayAmount) || 0;
|
||||||
@@ -577,7 +631,9 @@ function pointsToMoney(val) {
|
|||||||
carts.orderCostSummary.pointDeductionAmount = 0;
|
carts.orderCostSummary.pointDeductionAmount = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const maxAllowedMoney = new BigNumber(maxByRatio).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
const maxAllowedMoney = new BigNumber(maxByRatio)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_DOWN)
|
||||||
|
.toNumber();
|
||||||
console.debug("pointsToMoney debug:", { finalPay, cfg, pts, money, maxByRatio, maxAllowedMoney });
|
console.debug("pointsToMoney debug:", { finalPay, cfg, pts, money, maxByRatio, maxAllowedMoney });
|
||||||
if (money > maxAllowedMoney) {
|
if (money > maxAllowedMoney) {
|
||||||
// 调整积分到允许的最大金额对应的积分
|
// 调整积分到允许的最大金额对应的积分
|
||||||
@@ -586,12 +642,15 @@ function pointsToMoney(val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
usePointsNumber.value = pts;
|
usePointsNumber.value = pts;
|
||||||
const finalMoney = new BigNumber(pts).div(cfg.equivalentPoints).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
const finalMoney = new BigNumber(pts)
|
||||||
|
.div(cfg.equivalentPoints)
|
||||||
|
.decimalPlaces(2, BigNumber.ROUND_DOWN)
|
||||||
|
.toNumber();
|
||||||
carts.orderCostSummary.pointUsed = pts;
|
carts.orderCostSummary.pointUsed = pts;
|
||||||
carts.orderCostSummary.pointDeductionAmount = finalMoney;
|
carts.orderCostSummary.pointDeductionAmount = finalMoney;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emits = defineEmits(["chooseUser", "paysuccess", 'createOrder']);
|
const emits = defineEmits(["chooseUser", "paysuccess", "createOrder"]);
|
||||||
function chooseUser() {
|
function chooseUser() {
|
||||||
emits("chooseUser");
|
emits("chooseUser");
|
||||||
}
|
}
|
||||||
@@ -669,8 +728,7 @@ function returnPayParams() {
|
|||||||
allPack: carts.dinnerType == "take-out" ? 1 : 0,
|
allPack: carts.dinnerType == "take-out" ? 1 : 0,
|
||||||
limitRate: carts.limitDiscountRes,
|
limitRate: carts.limitDiscountRes,
|
||||||
newCustomerDiscountId: carts.newUserDiscount !== null ? carts.newUserDiscount.id : "", // 新客立减Id
|
newCustomerDiscountId: carts.newUserDiscount !== null ? carts.newUserDiscount.id : "", // 新客立减Id
|
||||||
newCustomerDiscountAmount:
|
newCustomerDiscountAmount: carts.newUserDiscount !== null ? carts.newUserDiscount.amount : 0, // 新客立减金额
|
||||||
carts.newUserDiscount !== null ? carts.newUserDiscount.amount : 0, // 新客立减金额
|
|
||||||
vipDiscountAmount: carts.orderCostSummary.vipDiscountAmount, // 超级会员折扣
|
vipDiscountAmount: carts.orderCostSummary.vipDiscountAmount, // 超级会员折扣
|
||||||
remark: cashRemark.value, // 现金支付备注
|
remark: cashRemark.value, // 现金支付备注
|
||||||
},
|
},
|
||||||
@@ -688,7 +746,8 @@ function refScanPayOpen(payType) {
|
|||||||
if (payType == "scanCode") {
|
if (payType == "scanCode") {
|
||||||
return refScanPay.value.open(returnPayParams(), "scanCode");
|
return refScanPay.value.open(returnPayParams(), "scanCode");
|
||||||
}
|
}
|
||||||
if (payType == "arrears") {
|
console.log("payType", payType);
|
||||||
|
if (payType == "virtual") {
|
||||||
refGuaZhangShow();
|
refGuaZhangShow();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -705,9 +764,8 @@ async function getPaytype() {
|
|||||||
const cashRemark = ref("");
|
const cashRemark = ref("");
|
||||||
async function nowPayClick(payType) {
|
async function nowPayClick(payType) {
|
||||||
if (carts.list.length) {
|
if (carts.list.length) {
|
||||||
await emits('createOrder', 'only-create')
|
await emits("createOrder", "only-create");
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
payType = payType || payTypes.list[payTypes.sel].payType;
|
payType = payType || payTypes.list[payTypes.sel].payType;
|
||||||
if (payType === "cash") {
|
if (payType === "cash") {
|
||||||
@@ -715,13 +773,13 @@ async function nowPayClick(payType) {
|
|||||||
confirmButtonText: "确定",
|
confirmButtonText: "确定",
|
||||||
cancelButtonText: "取消",
|
cancelButtonText: "取消",
|
||||||
type: "warning",
|
type: "warning",
|
||||||
inputPlaceholder: '请输入现金支付备注(选填)',
|
inputPlaceholder: "请输入现金支付备注(选填)",
|
||||||
})
|
})
|
||||||
.then(({ value }) => {
|
.then(({ value }) => {
|
||||||
cashRemark.value = value || "";
|
cashRemark.value = value || "";
|
||||||
payOrder("cash");
|
payOrder("cash");
|
||||||
})
|
})
|
||||||
.catch(() => { });
|
.catch(() => {});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (payType == "member-account") {
|
if (payType == "member-account") {
|
||||||
@@ -777,16 +835,16 @@ async function payOrder(payType, isScan, guazhangren) {
|
|||||||
shopUserId: carts.vipUser.id,
|
shopUserId: carts.vipUser.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (payType == "arrears") {
|
if (payType == "virtual") {
|
||||||
res = await payApi.creditPay({ ...returnPayParams(), creditBuyerId: guazhangren.id });
|
res = await payApi.creditPay({ ...returnPayParams(), creditBuyerId: guazhangren.id });
|
||||||
}
|
}
|
||||||
carts.clear();
|
carts.clear();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('payOrder===', error);
|
console.log("payOrder===", error);
|
||||||
// 启动状态查询
|
// 启动状态查询
|
||||||
if (error.code == 211) {
|
if (error.code == 211) {
|
||||||
showCheckPayStauts.value = true
|
showCheckPayStauts.value = true;
|
||||||
autoCheckOrder()
|
autoCheckOrder();
|
||||||
}
|
}
|
||||||
clearTimeout(payTimer);
|
clearTimeout(payTimer);
|
||||||
loading.close();
|
loading.close();
|
||||||
@@ -799,68 +857,68 @@ async function payOrder(payType, isScan, guazhangren) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearAutoCheckOrder() {
|
function clearAutoCheckOrder() {
|
||||||
clearInterval(timer.value)
|
clearInterval(timer.value);
|
||||||
timer.value = null
|
timer.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭查询
|
// 关闭查询
|
||||||
function closeScanCode() {
|
function closeScanCode() {
|
||||||
showCheckPayStauts.value = false;
|
showCheckPayStauts.value = false;
|
||||||
reset()
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重新扫码
|
// 重新扫码
|
||||||
function resetScanCode() {
|
function resetScanCode() {
|
||||||
reset()
|
reset();
|
||||||
showCheckPayStauts.value = false;
|
showCheckPayStauts.value = false;
|
||||||
clearInterval(timer.value)
|
clearInterval(timer.value);
|
||||||
timer.value = null
|
timer.value = null;
|
||||||
|
|
||||||
clearInterval(closeStateTimer.value)
|
clearInterval(closeStateTimer.value);
|
||||||
closeStateTimer.value = null
|
closeStateTimer.value = null;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
refScanPay.value.open(returnPayParams(), "scanCode")
|
refScanPay.value.open(returnPayParams(), "scanCode");
|
||||||
}, 500)
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
const closeState = ref(false)
|
const closeState = ref(false);
|
||||||
const closeStateTime = ref(5);
|
const closeStateTime = ref(5);
|
||||||
const closeStateTimer = ref(null)
|
const closeStateTimer = ref(null);
|
||||||
|
|
||||||
function closeStateTimerFuc() {
|
function closeStateTimerFuc() {
|
||||||
closeStateTimer.value = setInterval(() => {
|
closeStateTimer.value = setInterval(() => {
|
||||||
closeStateTime.value--
|
closeStateTime.value--;
|
||||||
if (closeStateTime.value <= 0) {
|
if (closeStateTime.value <= 0) {
|
||||||
clearInterval(closeStateTimer.value)
|
clearInterval(closeStateTimer.value);
|
||||||
closeStateTimer.value = null
|
closeStateTimer.value = null;
|
||||||
closeState.value = true
|
closeState.value = true;
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动查询订单状态
|
// 自动查询订单状态
|
||||||
const timer = ref(null)
|
const timer = ref(null);
|
||||||
function autoCheckOrder() {
|
function autoCheckOrder() {
|
||||||
closeStateTimerFuc()
|
closeStateTimerFuc();
|
||||||
timer.value = setInterval(() => {
|
timer.value = setInterval(() => {
|
||||||
// 开始锁单
|
// 开始锁单
|
||||||
// goodsStore.isOrderLock({
|
// goodsStore.isOrderLock({
|
||||||
// table_code: table_code.value
|
// table_code: table_code.value
|
||||||
// }, 'pay_lock')
|
// }, 'pay_lock')
|
||||||
checkPayStauts(false)
|
checkPayStauts(false);
|
||||||
}, 2000)
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
checkPayStautsLoading.value = true;
|
checkPayStautsLoading.value = true;
|
||||||
closeState.value = false
|
closeState.value = false;
|
||||||
closeStateTime.value = 5
|
closeStateTime.value = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询订单支付状态
|
// 查询订单支付状态
|
||||||
const showCheckPayStauts = ref(false)
|
const showCheckPayStauts = ref(false);
|
||||||
const checkPayStautsLoading = ref(true)
|
const checkPayStautsLoading = ref(true);
|
||||||
async function checkPayStauts(tips = true) {
|
async function checkPayStauts(tips = true) {
|
||||||
try {
|
try {
|
||||||
// 扫码下单
|
// 扫码下单
|
||||||
@@ -875,7 +933,7 @@ async function checkPayStauts(tips = true) {
|
|||||||
checkPayStautsLoading.value = false;
|
checkPayStautsLoading.value = false;
|
||||||
// scanCode.value = "";
|
// scanCode.value = "";
|
||||||
showCheckPayStauts.value = false;
|
showCheckPayStauts.value = false;
|
||||||
clearAutoCheckOrder()
|
clearAutoCheckOrder();
|
||||||
paysuccess();
|
paysuccess();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -885,8 +943,8 @@ async function checkPayStauts(tips = true) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
clearAutoCheckOrder()
|
clearAutoCheckOrder();
|
||||||
ElMessage.warning(res.msg || '');
|
ElMessage.warning(res.msg || "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -955,8 +1013,8 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearAutoCheckOrder()
|
clearAutoCheckOrder();
|
||||||
})
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
carts.payParamsInit();
|
carts.payParamsInit();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="">可用额度</div>
|
<div class="">可用额度</div>
|
||||||
<div class="u-m-t-6">{{ guazhangRen.remainingAmount }}</div>
|
<div class="u-m-t-6">{{ guazhangRen.creditAmount + guazhangRen.accountBalance }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import keyBoard from "./keyboard.vue";
|
import keyBoard from "./keyboard.vue";
|
||||||
import chooseGuazhang from "./choose-guazhang.vue";
|
import chooseGuazhang from "./choose-guazhang.vue";
|
||||||
@@ -145,7 +145,7 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-button) {
|
:deep(.el-button) {
|
||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,8 +29,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import { BigNumber } from "bignumber.js";
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -60,6 +61,7 @@ export default {
|
|||||||
open(opt) {
|
open(opt) {
|
||||||
this.show = true;
|
this.show = true;
|
||||||
this.option = opt;
|
this.option = opt;
|
||||||
|
console.log(new BigNumber("0.00"));
|
||||||
},
|
},
|
||||||
close() {
|
close() {
|
||||||
this.show = false;
|
this.show = false;
|
||||||
@@ -73,7 +75,7 @@ export default {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
console.log(valid);
|
console.log(valid);
|
||||||
if (this.form.discount_sale_amount * 1 <= 0 || this.form.discount_sale_amount * 1 <= 0) {
|
if (this.form.discount_sale_amount * 1 <= 0 || this.form.discount_sale_amount * 1 <= 0) {
|
||||||
return ElMessage.error("价格和数量必须大于0");
|
// return ElMessage.error("价格和数量必须大于0");
|
||||||
}
|
}
|
||||||
this.submit();
|
this.submit();
|
||||||
} else {
|
} else {
|
||||||
@@ -87,7 +89,7 @@ export default {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
:deep(.el-dialog__body) {
|
:deep(.el-dialog__body) {
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="box" v-loading="!carts.isLinkFinshed" element-loading-text="购物车连接初始化中,请稍等……">
|
<div class="box">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="top">
|
<div class="top">
|
||||||
<div class="left u-flex u-col-center">
|
<div class="left u-flex u-col-center">
|
||||||
@@ -9,8 +9,12 @@
|
|||||||
<el-button type="primary" v-if="!carts.vipUser.id">选择用户</el-button>
|
<el-button type="primary" v-if="!carts.vipUser.id">选择用户</el-button>
|
||||||
|
|
||||||
<div v-else class="flex cur-pointer">
|
<div v-else class="flex cur-pointer">
|
||||||
<img v-if="carts.vipUser.headImg && carts.vipUser.headImg != 'null'" class="headimg"
|
<img
|
||||||
:src="carts.vipUser.headImg" alt="" />
|
v-if="carts.vipUser.headImg && carts.vipUser.headImg != 'null'"
|
||||||
|
class="headimg"
|
||||||
|
:src="carts.vipUser.headImg"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
<div v-else class="headimg flex flex-x-y-center">
|
<div v-else class="headimg flex flex-x-y-center">
|
||||||
<i class="el-icon-user"></i>
|
<i class="el-icon-user"></i>
|
||||||
</div>
|
</div>
|
||||||
@@ -28,11 +32,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-popover placement="right" width="333" trigger="click" ref="refTable">
|
<el-popover placement="right" width="333" trigger="click" ref="refTable">
|
||||||
<el-input placeholder="请输入内容" prefix-icon="search" v-model="tableSearchText"
|
<el-input
|
||||||
@input="tablesearchInput"></el-input>
|
placeholder="请输入内容"
|
||||||
|
prefix-icon="search"
|
||||||
|
v-model="tableSearchText"
|
||||||
|
@input="tablesearchInput"
|
||||||
|
></el-input>
|
||||||
<div style="max-height: 398px; overflow-y: scroll" class="u-m-t-12">
|
<div style="max-height: 398px; overflow-y: scroll" class="u-m-t-12">
|
||||||
<div class="u-flex u-row-between u-p-t-8 table-item u-p-b-8 u-p-r-30" v-for="(item, index) in tableList"
|
<div
|
||||||
:key="index" @click="tableClick(item, index)">
|
class="u-flex u-row-between u-p-t-8 table-item u-p-b-8 u-p-r-30"
|
||||||
|
v-for="(item, index) in tableList"
|
||||||
|
:key="index"
|
||||||
|
@click="tableClick(item, index)"
|
||||||
|
>
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
<span :style="{ color: returnTableColor(item.status) }">
|
<span :style="{ color: returnTableColor(item.status) }">
|
||||||
{{ returnTableLabel(item.status) }}
|
{{ returnTableLabel(item.status) }}
|
||||||
@@ -52,7 +64,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<el-input placeholder="请输入商品名称" v-model="goods.query.name" clearable @change="getGoods">
|
<el-input
|
||||||
|
placeholder="请输入商品名称"
|
||||||
|
v-model="goods.query.name"
|
||||||
|
clearable
|
||||||
|
@change="getGoods"
|
||||||
|
>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<el-icon class="el-input__icon">
|
<el-icon class="el-input__icon">
|
||||||
<search />
|
<search />
|
||||||
@@ -66,16 +83,24 @@
|
|||||||
<div class="diners">
|
<div class="diners">
|
||||||
<!-- 就餐类型 -->
|
<!-- 就餐类型 -->
|
||||||
<el-button-group v-model="diners.sel" style="width: 100%; display: flex">
|
<el-button-group v-model="diners.sel" style="width: 100%; display: flex">
|
||||||
<el-button :class="{ active: index == diners.sel }" v-for="(item, index) in diners.list"
|
<el-button
|
||||||
:disabled="dinerDisabled(item, index)" @click="changeDinersSel(index)" :key="index">
|
:class="{ active: index == diners.sel }"
|
||||||
|
v-for="(item, index) in diners.list"
|
||||||
|
:disabled="dinerDisabled(item, index)"
|
||||||
|
@click="changeDinersSel(index)"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="u-flex u-font-14 clear u-m-t-10 perpoles">
|
<div class="u-flex u-font-14 clear u-m-t-10 perpoles">
|
||||||
<div @click="showDinerNumber" class="u-flex u-p-r-14 u-m-r-14"
|
<div
|
||||||
style="border-right: 1px solid #ebebeb; line-height: 1">
|
@click="showDinerNumber"
|
||||||
|
class="u-flex u-p-r-14 u-m-r-14"
|
||||||
|
style="border-right: 1px solid #ebebeb; line-height: 1"
|
||||||
|
>
|
||||||
<span>就餐人数:{{ perpole || "-" }} 位</span>
|
<span>就餐人数:{{ perpole || "-" }} 位</span>
|
||||||
<el-icon>
|
<el-icon>
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
@@ -86,19 +111,39 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- 购物车 -->
|
<!-- 购物车 -->
|
||||||
<cartsList @editNote="showNote(true)" @createOrder="createOrder" @hideOrder="hideOrder"
|
<cartsList
|
||||||
@clearOldOrder="clearOldOrder" :showOrder="showOrder" :goodsList="carts.goods" :dinerType="diners.sel"
|
@editNote="showNote(true)"
|
||||||
:perpole="perpole" :remark="remark" :table="carts.tableInfo" ref="refCart"></cartsList>
|
@createOrder="createOrder"
|
||||||
|
@hideOrder="hideOrder"
|
||||||
|
@clearOldOrder="clearOldOrder"
|
||||||
|
:showOrder="showOrder"
|
||||||
|
:goodsList="carts.goods"
|
||||||
|
:dinerType="diners.sel"
|
||||||
|
:perpole="perpole"
|
||||||
|
:remark="remark"
|
||||||
|
:table="carts.tableInfo"
|
||||||
|
ref="refCart"
|
||||||
|
></cartsList>
|
||||||
</div>
|
</div>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
<!-- 购物车控制操作按钮 -->
|
<!-- 购物车控制操作按钮 -->
|
||||||
<Controls @noteClick="showNote" @packClick="showPack" @changePriceClick="showChangePrice"
|
<Controls
|
||||||
@return="refReturnCartShow" @rottable="rottableShow" @changeCartNumberShow="refChangeNumberShow" />
|
@noteClick="showNote"
|
||||||
|
@packClick="showPack"
|
||||||
|
@changePriceClick="showChangePrice"
|
||||||
|
@return="refReturnCartShow"
|
||||||
|
@rottable="rottableShow"
|
||||||
|
@changeCartNumberShow="refChangeNumberShow"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<template v-if="!showOrder">
|
<template v-if="!showOrder">
|
||||||
<div class="flex categoty u-col-center">
|
<div class="flex categoty u-col-center">
|
||||||
<div class="show_more_btn" :class="{ showAll: category.showAll }" @click="toggleShowAll">
|
<div
|
||||||
|
class="show_more_btn"
|
||||||
|
:class="{ showAll: category.showAll }"
|
||||||
|
@click="toggleShowAll"
|
||||||
|
>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="flex showmore">
|
<div class="flex showmore">
|
||||||
<el-icon color="#fff">
|
<el-icon color="#fff">
|
||||||
@@ -109,8 +154,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex categorys" :class="{ 'flex-wrap': category.showAll }">
|
<div class="flex categorys" :class="{ 'flex-wrap': category.showAll }">
|
||||||
<div v-for="(item, index) in category.list" :key="index" @click="changeCategoryId(item)">
|
<div
|
||||||
<el-tag size="large" :type="goods.query.categoryId === item.id ? 'primary' : 'info'" effect="dark">
|
v-for="(item, index) in category.list"
|
||||||
|
:key="index"
|
||||||
|
@click="changeCategoryId(item)"
|
||||||
|
>
|
||||||
|
<el-tag
|
||||||
|
size="large"
|
||||||
|
:type="goods.query.categoryId === item.id ? 'primary' : 'info'"
|
||||||
|
effect="dark"
|
||||||
|
>
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,13 +177,26 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<div class="u-m-t-10">临时菜</div>
|
<div class="u-m-t-10">临时菜</div>
|
||||||
</div>
|
</div>
|
||||||
<GoodsItem :item="item" @itemClick="goodsClick(item)" v-for="item in carts.goods" :key="item.id">
|
<GoodsItem
|
||||||
</GoodsItem>
|
:item="item"
|
||||||
|
@itemClick="goodsClick(item)"
|
||||||
|
v-for="item in carts.goods"
|
||||||
|
:key="item.id"
|
||||||
|
></GoodsItem>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 订单信息展示 -->
|
<!-- 订单信息展示 -->
|
||||||
<Order ref="refOrder" :orderInfo="carts.oldOrder" @chooseUser="showChooseUser" @paysuccess="refresh"
|
<Order
|
||||||
:table="carts.tableInfo" :perpole="perpole" v-else :user="user" @create-order="createOrder"></Order>
|
ref="refOrder"
|
||||||
|
:orderInfo="carts.oldOrder"
|
||||||
|
@chooseUser="showChooseUser"
|
||||||
|
@paysuccess="refresh"
|
||||||
|
:table="carts.tableInfo"
|
||||||
|
:perpole="perpole"
|
||||||
|
v-else
|
||||||
|
:user="user"
|
||||||
|
@create-order="createOrder"
|
||||||
|
></Order>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -145,7 +211,11 @@
|
|||||||
<!-- 临时菜 -->
|
<!-- 临时菜 -->
|
||||||
<addLingShiCai ref="refAddLingShiCai" @confirm="addLingShiCaiConfirm"></addLingShiCai>
|
<addLingShiCai ref="refAddLingShiCai" @confirm="addLingShiCaiConfirm"></addLingShiCai>
|
||||||
<!-- 改价 -->
|
<!-- 改价 -->
|
||||||
<changePrice ref="refChangePrice" :useVipPrice="carts.useVipPrice" @confirm="changePriceConfirm"></changePrice>
|
<changePrice
|
||||||
|
ref="refChangePrice"
|
||||||
|
:useVipPrice="carts.useVipPrice"
|
||||||
|
@confirm="changePriceConfirm"
|
||||||
|
></changePrice>
|
||||||
<!-- 称重商品 -->
|
<!-- 称重商品 -->
|
||||||
<change-weight ref="refChangeWeight" @confirm="changeWeightConfirm"></change-weight>
|
<change-weight ref="refChangeWeight" @confirm="changeWeightConfirm"></change-weight>
|
||||||
<!-- 可选套餐 -->
|
<!-- 可选套餐 -->
|
||||||
@@ -518,7 +588,7 @@ async function getTableDetail(params) {
|
|||||||
const res = await tableApi.get(params);
|
const res = await tableApi.get(params);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
function tablesearchInput() { }
|
function tablesearchInput() {}
|
||||||
//返回桌台状态颜色
|
//返回桌台状态颜色
|
||||||
function returnTableColor(key) {
|
function returnTableColor(key) {
|
||||||
const item = $status[key];
|
const item = $status[key];
|
||||||
@@ -665,7 +735,7 @@ function getCategoryList() {
|
|||||||
size: 200,
|
size: 200,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
localStorage.setItem('categorys', JSON.stringify(res))
|
localStorage.setItem("categorys", JSON.stringify(res));
|
||||||
res.unshift({ name: "全部", id: "" });
|
res.unshift({ name: "全部", id: "" });
|
||||||
category.list = res;
|
category.list = res;
|
||||||
});
|
});
|
||||||
@@ -803,14 +873,14 @@ onMounted(async () => {
|
|||||||
// : await orderApi.getHistoryList({
|
// : await orderApi.getHistoryList({
|
||||||
// tableCode,
|
// tableCode,
|
||||||
// });
|
// });
|
||||||
let res = ''
|
let res = "";
|
||||||
if (id) {
|
if (id) {
|
||||||
res = await orderApi.getHistoryList({
|
res = await orderApi.getHistoryList({
|
||||||
orderId: id,
|
orderId: id,
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
res = await orderApi.getHistoryList({
|
res = await orderApi.getHistoryList({
|
||||||
tableCode: carts.table_code,
|
tableCode: carts.table_code || tableCode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -181,16 +181,16 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.status != 'idle' && item.status != 'subscribe'">
|
<template v-else-if="item.status != 'idle' && item.status != 'subscribe'">
|
||||||
<template v-if="item.status == 'using'">
|
<template v-if="item.status == 'unsettled'">
|
||||||
<el-button
|
<el-button
|
||||||
:disabled="!item.tableId || item.status === 'closed'"
|
:disabled="!item.orderId || item.status === 'closed'"
|
||||||
@click="diancanShow(item, 'isAddGoods')"
|
@click="diancanShow(item, 'isAddGoods')"
|
||||||
>
|
>
|
||||||
加菜
|
加菜
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
:disabled="!item.tableId || item.status === 'closed'"
|
:disabled="!item.orderId || item.status === 'closed'"
|
||||||
@click="diancanShow(item, 'isPayOrder')"
|
@click="diancanShow(item, 'isPayOrder')"
|
||||||
>
|
>
|
||||||
结账
|
结账
|
||||||
@@ -539,7 +539,7 @@ onMounted(() => {});
|
|||||||
max-width: 210px;
|
max-width: 210px;
|
||||||
min-width: 190px;
|
min-width: 190px;
|
||||||
|
|
||||||
&.using {
|
&.unsettled {
|
||||||
background-color: rgb(250, 85, 85);
|
background-color: rgb(250, 85, 85);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user