Compare commits
35 Commits
18d3d2a428
...
test
| Author | SHA1 | Date | |
|---|---|---|---|
| 527cfcdcf8 | |||
| 5d28477db9 | |||
| 92c3a45049 | |||
| 042dacec98 | |||
| ed8be8a16a | |||
| 3b19d58f27 | |||
| c95ab6fda5 | |||
| 084084c008 | |||
| db467815dd | |||
| e61a297d9a | |||
| 348ecdfc54 | |||
| 4c06f07ac6 | |||
| b28fdeaf11 | |||
| 8b3a802092 | |||
| ce0878c23f | |||
| fb13b0a502 | |||
| 8f235ffd91 | |||
| cc44bdc9b1 | |||
| 01c2cbcfb4 | |||
| c4066a3b45 | |||
| a9751fa565 | |||
| d96009bf6f | |||
| 2325b89093 | |||
| bee51d6d1a | |||
| 98bccfd2ac | |||
| 6151fbf2ee | |||
| 9b73715c5a | |||
| 469a5a99ca | |||
| 7527a55066 | |||
| 936832f7ba | |||
| 5c775bd293 | |||
| bf35a1b35b | |||
| 33bc14de31 | |||
| 1d7ba844f6 | |||
| 15dbd79c7d |
@@ -9,7 +9,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// test
|
||||
// test 11
|
||||
import { useAppStore, useSettingsStore } from "@/store";
|
||||
import defaultSettings from "@/settings";
|
||||
import { ThemeEnum } from "@/enums/ThemeEnum";
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import request from "@/utils/request";
|
||||
import { Account_BaseUrl } from "@/api/config";
|
||||
import { Account_BaseUrl, Market_BaseUrl } from "@/api/config";
|
||||
const baseURL = Account_BaseUrl + "/admin/points";
|
||||
const Api = {
|
||||
// 002-获取订单可用积分及抵扣金额(支付页面使用)
|
||||
|
||||
// calcOrderUsablePoints(params: any) {
|
||||
// return request<any>({
|
||||
// url: `${baseURL}/memberPoints/calcUsablePoints`,
|
||||
// method: "get",
|
||||
// params
|
||||
// });
|
||||
// },
|
||||
calcOrderUsablePoints(params: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/memberPoints/calcUsablePoints`,
|
||||
url: `${Market_BaseUrl}/admin/points/userPoints`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
|
||||
68
src/api/account/quick.ts
Normal file
68
src/api/account/quick.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import request from "@/utils/request";
|
||||
import { Account_BaseUrl } from "@/api/config";
|
||||
const baseURL = Account_BaseUrl + "/admin/quick";
|
||||
const API = {
|
||||
getList(data: any) {
|
||||
return request<any, QuickMenu[]>({
|
||||
url: `${baseURL}`,
|
||||
method: "get",
|
||||
params: data
|
||||
});
|
||||
},
|
||||
add(data: any) {
|
||||
return request({
|
||||
url: `${baseURL}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
delete(ids: [string | number]) {
|
||||
return request({
|
||||
url: `${baseURL}`,
|
||||
method: "delete",
|
||||
data: ids,
|
||||
});
|
||||
},
|
||||
edit(data: any) {
|
||||
return request({
|
||||
url: `${baseURL}`,
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
}
|
||||
export default API;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 悬浮窗配置 实体类。
|
||||
*
|
||||
* QuickMenu
|
||||
*/
|
||||
export interface QuickMenu {
|
||||
createTime?: string;
|
||||
id?: number;
|
||||
/**
|
||||
* 菜单Id
|
||||
*/
|
||||
menuId: number;
|
||||
/**
|
||||
* 店铺Id
|
||||
*/
|
||||
shopId?: number;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
sort?: number;
|
||||
/**
|
||||
* 状态 1-启用 0-禁用
|
||||
*/
|
||||
status?: number;
|
||||
updateTime?: string;
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
url?: string;
|
||||
[property: string]: any;
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import request from "@/utils/request";
|
||||
import { Account_BaseUrl } from "@/api/config";
|
||||
import { Account_BaseUrl, Order_BaseUrl } from "@/api/config";
|
||||
const baseURL = Account_BaseUrl + "/admin/shopMerchant";
|
||||
const orderURL = Order_BaseUrl + "/admin/shopMerchant";
|
||||
const API = {
|
||||
get(shopId: string | number) {
|
||||
return request({
|
||||
url: `${baseURL}`,
|
||||
url: `${orderURL}`,
|
||||
method: "get",
|
||||
params: {
|
||||
shopId: shopId
|
||||
@@ -14,7 +15,7 @@ const API = {
|
||||
edit(shopId: string | number, data: shopMerchantType) {
|
||||
delete data.id
|
||||
return request({
|
||||
url: `${baseURL}`,
|
||||
url: `${orderURL}`,
|
||||
method: "put",
|
||||
data: { ...data, shopId },
|
||||
});
|
||||
|
||||
166
src/api/common/index.ts
Normal file
166
src/api/common/index.ts
Normal file
@@ -0,0 +1,166 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
/**
|
||||
* 获取所有地域
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export const getRegion = () => {
|
||||
return request<any, any[]>({
|
||||
url: `/system/admin/common/region`,
|
||||
method: "get"
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有银行
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
export const getBankInfo = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/system/admin/common/bankInfo`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 类目信息表
|
||||
* @returns
|
||||
*/
|
||||
export const getCategory = () => {
|
||||
return request<any, any[]>({
|
||||
url: `/system/admin/common/category`,
|
||||
method: "get"
|
||||
});
|
||||
}
|
||||
|
||||
interface getBankBranchListParams {
|
||||
bankAliceCode?: string;
|
||||
cityCode?: string;
|
||||
}
|
||||
/**
|
||||
* 获取所有支行
|
||||
* @params
|
||||
* bankAliceCode 银行别名code bankAliasCode 从 /system/admin/common/bankInfo 获取
|
||||
* cityCode 市编码 wxProvinceCode 从 /system/admin/common/region 获取
|
||||
* @returns
|
||||
*/
|
||||
export const getBankBranchList = (params: getBankBranchListParams) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager/bankBranchList`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请进件
|
||||
* @data Object
|
||||
* @returns
|
||||
*/
|
||||
export const entryManagerPost = (data: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请进件
|
||||
* @data {
|
||||
* url string 图片地址
|
||||
* type string 可选
|
||||
* IdCard 身份证
|
||||
* BankCard 银行卡
|
||||
* BusinessLicense 营业执照
|
||||
* }
|
||||
* @returns
|
||||
*/
|
||||
export const getInfoByImg = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager/getInfoByImg`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取进件信息详情
|
||||
* @data { shopId }
|
||||
* @returns
|
||||
*/
|
||||
export const entryManagerDetail = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取进件列表
|
||||
* @data { params }
|
||||
* @returns
|
||||
*/
|
||||
export const entryManagerList = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager/list`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动查询进件信息状态
|
||||
* @data { params }
|
||||
* @returns
|
||||
*/
|
||||
export const queryEntry = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/data/entryManager/queryEntry`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户支付信息获取
|
||||
* @data { params }
|
||||
* @returns
|
||||
*/
|
||||
export const shopMerchantGet = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/shopMerchant`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 商户支付信息修改 修改聚合支付信息
|
||||
* @data { params }
|
||||
* @returns
|
||||
*/
|
||||
export const shopMerchantPut = (data: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/shopMerchant`,
|
||||
method: "put",
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前店铺的主店进件信息
|
||||
* @data { params }
|
||||
* @returns
|
||||
*/
|
||||
export const getMainMerchant = (params: Object) => {
|
||||
return request<any, any[]>({
|
||||
url: `/order/admin/shopMerchant/getMainMerchant`,
|
||||
method: "get",
|
||||
params
|
||||
});
|
||||
}
|
||||
@@ -10,7 +10,7 @@ export function searchstorestatus(type) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
headers: {
|
||||
clint_type: type
|
||||
'ClintType': type
|
||||
},
|
||||
url: "/meituan/searchstorestatus"
|
||||
});
|
||||
@@ -79,7 +79,7 @@ export function getuisdk(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
headers: {
|
||||
clint_type: 2
|
||||
'ClintType': 2
|
||||
},
|
||||
url: "/douyin/getuisdk",
|
||||
data,
|
||||
@@ -214,7 +214,7 @@ export function thirdPartyCoupon_bindUrl(data) {
|
||||
return request_php({
|
||||
method: "post",
|
||||
headers: {
|
||||
clint_type: 1
|
||||
'ClintType': 1
|
||||
},
|
||||
url: "/meituan/getuisdkurl",
|
||||
data,
|
||||
|
||||
@@ -64,6 +64,14 @@ const OrderApi = {
|
||||
data
|
||||
});
|
||||
},
|
||||
// 订单打印
|
||||
printOrder(data: any) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/print`,
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default OrderApi;
|
||||
|
||||
@@ -3,7 +3,6 @@ import { Order_BaseUrl } from "@/api/config";
|
||||
const baseURL = Order_BaseUrl + "/pay";
|
||||
const Api = {
|
||||
// h5支付
|
||||
|
||||
h5Pay(data: h5PayRequest) {
|
||||
return request<any>({
|
||||
url: `${baseURL}/h5Pay`,
|
||||
@@ -67,7 +66,6 @@ const Api = {
|
||||
params
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
export default Api;
|
||||
|
||||
BIN
src/assets/images/close.png
Normal file
BIN
src/assets/images/close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
BIN
src/assets/images/plus.png
Normal file
BIN
src/assets/images/plus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.0 KiB |
161
src/components/AddressSelect/index.vue
Normal file
161
src/components/AddressSelect/index.vue
Normal file
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div class="center">
|
||||
<el-select placeholder="请选择省" style="width: 100px" v-model="prov" @change="provChange">
|
||||
<el-option
|
||||
v-for="item in provList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionName"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
placeholder="请选择市"
|
||||
style="width: 100px"
|
||||
:disabled="!prov"
|
||||
v-model="city"
|
||||
@change="cityChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in cityList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionName"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
placeholder="请选择区"
|
||||
style="width: 100px"
|
||||
:disabled="!city"
|
||||
v-model="area"
|
||||
@change="areaChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in areaList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionName"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { getRegion } from "@/api/common";
|
||||
|
||||
const provList = ref<any[]>([]);
|
||||
const cityList = ref<any[]>([]);
|
||||
const areaList = ref<any[]>([]);
|
||||
|
||||
const provCode = defineModel("provCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
// 监听省份code变化
|
||||
watch(
|
||||
provCode,
|
||||
async (n, o) => {
|
||||
await getRegionAjax();
|
||||
if (n && n !== undefined) {
|
||||
provChange(n, true);
|
||||
|
||||
// 监听市区code变化
|
||||
watch(
|
||||
cityCode,
|
||||
async (n, o) => {
|
||||
if (n !== undefined && n) {
|
||||
cityChange(n, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true, // 可选:初始化立即执行,验证是否监听到初始值
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true, // 可选:初始化立即执行,验证是否监听到初始值
|
||||
}
|
||||
);
|
||||
|
||||
const cityCode = defineModel("cityCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const areaCode = defineModel("areaCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const prov = defineModel("prov", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const city = defineModel("city", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const area = defineModel("area", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const wxProvinceCode = defineModel("wxProvinceCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
// 省份变化 e code isEcho是否回显
|
||||
function provChange(e: string, isEcho: boolean = false) {
|
||||
console.log("provChange", e);
|
||||
if (!isEcho) {
|
||||
city.value = "";
|
||||
area.value = "";
|
||||
cityList.value = [];
|
||||
areaList.value = [];
|
||||
}
|
||||
const provObj = provList.value.find((item) => item.regionName == e);
|
||||
if (provObj && provObj.children) {
|
||||
cityList.value = provObj.children;
|
||||
}
|
||||
}
|
||||
|
||||
// 市区变化
|
||||
function cityChange(e: string, isEcho: boolean = false) {
|
||||
if (!isEcho) {
|
||||
area.value = "";
|
||||
areaList.value = [];
|
||||
}
|
||||
const cityObj = cityList.value.find((item) => item.regionName == e);
|
||||
|
||||
if (cityObj && cityObj.children) {
|
||||
areaList.value = cityObj.children;
|
||||
wxProvinceCode.value = cityObj.wxProvinceCode;
|
||||
}
|
||||
}
|
||||
|
||||
// 区变化
|
||||
function areaChange(e: string) {}
|
||||
|
||||
// 获取省市区数据
|
||||
async function getRegionAjax() {
|
||||
try {
|
||||
const res = await getRegion();
|
||||
provList.value = res;
|
||||
} catch (error) {
|
||||
console.error("获取省市区数据失败:", error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
</style>
|
||||
266
src/components/FastMenuConfig/dialog-add.vue
Normal file
266
src/components/FastMenuConfig/dialog-add.vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<el-dialog :title="form.id ? '编辑' : '添加'" width="400px" v-model="visible" @closed="resetForm">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px" label-position="left">
|
||||
<el-form-item label="菜单" prop="menuId">
|
||||
<el-tree-select
|
||||
:check-strictly="true"
|
||||
v-model="form.menuId"
|
||||
:data="menus"
|
||||
:render-after-expand="false"
|
||||
style="width: 240px"
|
||||
node-key="menuId"
|
||||
:disabled-key="disabled"
|
||||
></el-tree-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序值">
|
||||
<el-input-number v-model="form.sort" :step="1" step-strictly />
|
||||
</el-form-item>
|
||||
<el-form-item label="启用状态">
|
||||
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog_footer">
|
||||
<div class="btn">
|
||||
<el-button size="large" style="width: 100%" @click="visible = false">取 消</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button
|
||||
size="large"
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
style="width: 100%"
|
||||
@click="submitHandle"
|
||||
>
|
||||
确 定
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// 补充缺失的导入
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ElNotification, ElMessage } from "element-plus"; // 导入提示组件
|
||||
import { filterNumberInput } from "@/utils";
|
||||
import { roleTemplateAdd } from "@/api/account/roleTemplate";
|
||||
import MenuAPI from "@/api/account/menu";
|
||||
import quickApi from "@/api/account/quick";
|
||||
|
||||
const props = defineProps({
|
||||
isGetMenu: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false, // 补充默认值
|
||||
},
|
||||
parMenus: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [], // 补充默认值
|
||||
},
|
||||
item: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => null,
|
||||
},
|
||||
});
|
||||
|
||||
const menus = ref([]);
|
||||
|
||||
/**
|
||||
* 格式化菜单数据:核心逻辑 - 禁用有子菜单的父节点,仅允许选叶子节点
|
||||
* @param arr 原始菜单数组
|
||||
* @returns 格式化后带禁用标记的菜单数组
|
||||
*/
|
||||
function returnMenu(arr) {
|
||||
let result = [];
|
||||
for (let menu of arr) {
|
||||
// 过滤掉"默认接口目录"
|
||||
if (menu.title === "默认接口目录") continue;
|
||||
|
||||
// 筛选有效子菜单:非隐藏 + 类型为0
|
||||
const children = menu.children ? menu.children.filter((v) => !v.hidden && v.type === 0) : [];
|
||||
// 递归处理子菜单
|
||||
const formattedChildren = returnMenu(children);
|
||||
|
||||
// 核心:判断是否为叶子节点(无有效子菜单)
|
||||
const isLeaf = formattedChildren.length === 0;
|
||||
|
||||
// 组装节点:有子菜单则禁用(disabled: true),无则允许选择
|
||||
const menuNode = {
|
||||
...menu,
|
||||
label: menu.title,
|
||||
value: menu.menuId,
|
||||
menuId: menu.menuId, // 保持node-key一致
|
||||
disabled: !isLeaf, // 有子菜单 → 禁用,无 → 启用
|
||||
children: formattedChildren,
|
||||
};
|
||||
|
||||
// 特殊处理:如果子菜单只有1个,直接扁平化(保持原有逻辑)
|
||||
if (formattedChildren.length === 1) {
|
||||
result.push({
|
||||
...formattedChildren[0],
|
||||
disabled: formattedChildren[0].children.length > 0, // 子节点仍判断是否有后代
|
||||
});
|
||||
} else {
|
||||
result.push(menuNode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (!props.isGetMenu) return;
|
||||
try {
|
||||
const res = await MenuAPI.getRoutes();
|
||||
menus.value = returnMenu(res);
|
||||
} catch (error) {
|
||||
ElMessage.error("菜单数据加载失败");
|
||||
console.error("getRoutes error:", error);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听父组件传入的菜单变化
|
||||
watch(
|
||||
() => props.parMenus,
|
||||
(newVal) => {
|
||||
if (newVal.length) {
|
||||
menus.value = returnMenu(newVal);
|
||||
}
|
||||
},
|
||||
{ deep: true } // 监听数组内部变化
|
||||
);
|
||||
|
||||
// 对话框显隐绑定
|
||||
const visible = defineModel({
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
});
|
||||
|
||||
const formRef = ref(null);
|
||||
const loading = ref(false);
|
||||
// 表单初始化
|
||||
const form = ref({
|
||||
menuId: "",
|
||||
sort: 0,
|
||||
url: "",
|
||||
status: 1,
|
||||
});
|
||||
|
||||
/**
|
||||
* 自定义校验规则:确保选中的是叶子节点(兜底验证)
|
||||
* @param rule 校验规则
|
||||
* @param value 选中的menuId
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
function validateLeafMenu(rule, value, callback) {
|
||||
if (!value) {
|
||||
return callback(new Error("请选择菜单"));
|
||||
}
|
||||
// 递归查找节点,判断是否为叶子节点
|
||||
const findNode = (nodes, menuId) => {
|
||||
for (let node of nodes) {
|
||||
if (node.menuId === menuId) return node;
|
||||
if (node.children) {
|
||||
const res = findNode(node.children, menuId);
|
||||
if (res) return res;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
const selectedNode = findNode(menus.value, value);
|
||||
|
||||
if (!selectedNode) {
|
||||
callback(new Error("选择的菜单不存在"));
|
||||
} else if (selectedNode.disabled) {
|
||||
callback(new Error("有子菜单的父节点不可选,请选择子菜单"));
|
||||
} else {
|
||||
callback(); // 校验通过
|
||||
}
|
||||
}
|
||||
|
||||
// 表单校验规则:修复拼写错误 + 新增自定义叶子节点校验
|
||||
const rules = ref({
|
||||
menuId: [
|
||||
{
|
||||
required: true,
|
||||
validator: validateLeafMenu, // 替换原有规则为自定义校验
|
||||
trigger: "change", // 选择变化时校验(原triiger拼写错误)
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 重置表单
|
||||
function resetForm() {
|
||||
form.value = {
|
||||
menuId: "",
|
||||
sort: 0,
|
||||
url: "",
|
||||
status: 1,
|
||||
};
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields(); // 避免null调用
|
||||
}
|
||||
}
|
||||
|
||||
// 提交事件
|
||||
const emits = defineEmits(["success"]);
|
||||
async function submitHandle() {
|
||||
try {
|
||||
// 修复vaild拼写错误
|
||||
const valid = await formRef.value.validate();
|
||||
if (!valid) return;
|
||||
|
||||
loading.value = true;
|
||||
// 排序值兜底
|
||||
form.value.sort = form.value.sort === "" ? 0 : form.value.sort;
|
||||
|
||||
// 区分新增/编辑
|
||||
if (form.value.id) {
|
||||
await quickApi.edit(form.value);
|
||||
ElNotification({ title: "成功", message: "编辑成功", type: "success" });
|
||||
} else {
|
||||
await quickApi.add(form.value);
|
||||
ElNotification({ title: "成功", message: "添加成功", type: "success" });
|
||||
}
|
||||
|
||||
emits("success");
|
||||
visible.value = false;
|
||||
} catch (error) {
|
||||
ElMessage.error(form.value.id ? "编辑失败" : "添加失败");
|
||||
console.error("submit error:", error);
|
||||
} finally {
|
||||
loading.value = false; // 无论成败都关闭loading
|
||||
}
|
||||
}
|
||||
|
||||
// 监听props.item初始化表单
|
||||
watch(
|
||||
() => props.item,
|
||||
(newval) => {
|
||||
if (newval) {
|
||||
form.value = { ...newval }; // 深拷贝,避免修改原对象
|
||||
}
|
||||
},
|
||||
{ deep: true, immediate: true } // 初始化触发
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dialog_footer {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
.btn {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
// 可选:美化禁用节点的样式
|
||||
.el-select-dropdown__item.is-disabled {
|
||||
color: var(--el-text-color-regular);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
183
src/components/FastMenuConfig/index.vue
Normal file
183
src/components/FastMenuConfig/index.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<div class="table-box">
|
||||
<div class="row mb-sm">
|
||||
<el-button type="primary" @click="showAdd = true">添加</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
:data="tableData.list"
|
||||
v-loading="tableData.loading"
|
||||
stripe
|
||||
border
|
||||
row-key="id"
|
||||
:tree-props="{ children: 'children' }"
|
||||
default-expand-all
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="ID" prop="id"></el-table-column>
|
||||
<el-table-column label="菜单名称" prop="isEnable">
|
||||
<template #default="scope">
|
||||
{{ returnMenuName(scope.row) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="启用状态" prop="isEnable">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.status"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@change="isEnableChange($event, scope.row)"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序值" prop="sort"></el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime"></el-table-column>
|
||||
<el-table-column label="操作" width="250">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="editMenu(scope.row)">编辑</el-button>
|
||||
<el-popconfirm title="确认要删除吗?" @confirm="deleteHandle(scope.row)">
|
||||
<template #reference>
|
||||
<el-button type="danger" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<dialogAdd
|
||||
v-model="showAdd"
|
||||
:parMenus="menus"
|
||||
@success="Refresh()"
|
||||
:item="nowEditMenu"
|
||||
></dialogAdd>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useQuickStore, usePermissionStore } from "@/store";
|
||||
const quickStore = useQuickStore();
|
||||
|
||||
import { ref, reactive, onMounted, toRaw } from "vue";
|
||||
import MenuAPI from "@/api/account/menu";
|
||||
|
||||
import quickApi from "@/api/account/quick";
|
||||
|
||||
import dialogAdd from "./dialog-add.vue";
|
||||
|
||||
const showAdd = ref(false);
|
||||
|
||||
const nowEditMenu = ref(null);
|
||||
function editMenu(item) {
|
||||
nowEditMenu.value = { ...item };
|
||||
showAdd.value = true;
|
||||
}
|
||||
const tableData = reactive({
|
||||
loading: false,
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: [],
|
||||
});
|
||||
|
||||
function Refresh() {
|
||||
quickStore.getQuickMenus();
|
||||
getList();
|
||||
}
|
||||
function getList() {
|
||||
tableData.loading = true;
|
||||
quickApi
|
||||
.getList({
|
||||
page: tableData.page,
|
||||
size: tableData.size,
|
||||
isEdit: 1,
|
||||
})
|
||||
.then((res) => {
|
||||
tableData.list = res;
|
||||
tableData.total = res.length;
|
||||
})
|
||||
.finally(() => {
|
||||
tableData.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
const menus = ref([]);
|
||||
async function getMenus() {
|
||||
const res = await MenuAPI.getRoutes();
|
||||
menus.value = res;
|
||||
console.log("menus", res);
|
||||
}
|
||||
const menusIdMap = computed(() => {
|
||||
const map = getMenuMap();
|
||||
console.log("map", map);
|
||||
|
||||
return map;
|
||||
});
|
||||
function returnMenuName(item) {
|
||||
const menu = menusIdMap.value.get(`${item.menuId}`);
|
||||
console.log("menuId", item.menuId);
|
||||
console.log("menu", menu);
|
||||
|
||||
return menu ? menu.title : "";
|
||||
}
|
||||
function getMenuMap() {
|
||||
// 初始化Map
|
||||
const map = new Map();
|
||||
|
||||
// 定义递归函数处理菜单节点
|
||||
function processMenuNode(menuNode) {
|
||||
// 将当前节点存入Map
|
||||
map.set(menuNode.menuId, menuNode);
|
||||
|
||||
// 如果有子节点且子节点数组不为空,则递归处理每个子节点
|
||||
if (menuNode.children && Array.isArray(menuNode.children) && menuNode.children.length > 0) {
|
||||
menuNode.children.forEach((childNode) => {
|
||||
processMenuNode(childNode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历根级菜单,逐个处理
|
||||
if (menus.value && Array.isArray(menus.value)) {
|
||||
menus.value.forEach((rootMenu) => {
|
||||
processMenuNode(rootMenu);
|
||||
});
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
function isEnableChange(value, item) {
|
||||
quickApi
|
||||
.edit({
|
||||
...item,
|
||||
status: value,
|
||||
})
|
||||
.then((res) => {
|
||||
ElMessage({
|
||||
message: "修改成功",
|
||||
type: "success",
|
||||
});
|
||||
Refresh();
|
||||
});
|
||||
}
|
||||
function deleteHandle(item) {
|
||||
quickApi.delete([item.id]).then(() => {
|
||||
Refresh();
|
||||
});
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getMenus();
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
padding: 14px;
|
||||
width: 100%;
|
||||
.table-box {
|
||||
border-radius: 8px;
|
||||
background-color: #fff;
|
||||
padding: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -172,12 +172,12 @@ const onError = (error: any) => {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border: 1px var(--el-border-color) solid;
|
||||
border-radius: 5px;
|
||||
// border: 1px var(--el-border-color) solid;
|
||||
// border-radius: 5px;
|
||||
|
||||
&:hover {
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
// &:hover {
|
||||
// border-color: var(--el-color-primary);
|
||||
// }
|
||||
|
||||
&__delete-btn {
|
||||
position: absolute;
|
||||
|
||||
95
src/layout/components/FastMenu/index.vue
Normal file
95
src/layout/components/FastMenu/index.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="fast-menu">
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
@command="menuClick"
|
||||
placement="top-end"
|
||||
@visible-change="handleVisibleChange"
|
||||
append-to-body="true"
|
||||
>
|
||||
<img class="img" :src="imgsrc" alt="" />
|
||||
<!-- <el-icon color="#fff" size="24px">
|
||||
<Plus v-if="!showMenu" />
|
||||
<Close v-else />
|
||||
</el-icon> -->
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="(item, index) in quickStore.quickMenus"
|
||||
:key="index"
|
||||
:command="item.menuId"
|
||||
>
|
||||
{{ returnMenuName(item.menuId) }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="-1">
|
||||
<el-icon>
|
||||
<Edit color="#4080FF" />
|
||||
</el-icon>
|
||||
<span style="color: #4080ff">编辑</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from "vue";
|
||||
import { useQuickStore, usePermissionStore, useUserStore } from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const quickStore = useQuickStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
console.log("permissionStore", permissionStore.menus);
|
||||
|
||||
function menuClick(menuId: number) {
|
||||
console.log("menuId", menuId);
|
||||
if (menuId == -1) {
|
||||
if (userStore.userInfo.id == 1) {
|
||||
return router.push("/system/commonlyUsedMenu");
|
||||
} else {
|
||||
return router.push("/commonlyUsedMenu");
|
||||
}
|
||||
}
|
||||
permissionStore.menuJump(menuId);
|
||||
}
|
||||
|
||||
function returnMenuName(menuId: number) {
|
||||
return permissionStore.returnMenuName(menuId);
|
||||
}
|
||||
|
||||
const imgsrc = computed(() => {
|
||||
return showMenu.value
|
||||
? new URL("/src/assets/images/close.png", import.meta.url).href
|
||||
: new URL("/src/assets/images/plus.png", import.meta.url).href;
|
||||
});
|
||||
const showMenu = ref(false);
|
||||
function handleVisibleChange(visible: boolean) {
|
||||
showMenu.value = visible;
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.fast-menu {
|
||||
position: fixed;
|
||||
$size: 40px;
|
||||
right: 40px;
|
||||
bottom: 40px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
.img {
|
||||
width: $size;
|
||||
height: $size;
|
||||
}
|
||||
// box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
|
||||
// background: linear-gradient(135deg, #409eff, #3a84ff);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
.svg-icon {
|
||||
margin-right: 0;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -27,10 +27,11 @@
|
||||
<TagsView v-if="showTagsView" />
|
||||
<AppMain />
|
||||
<Settings v-if="defaultSettings.showSettings" />
|
||||
|
||||
<!-- 返回顶部 -->
|
||||
<el-backtop target=".app-main">
|
||||
<!-- <el-backtop target=".app-main">
|
||||
<svg-icon icon-class="backtop" size="24px" />
|
||||
</el-backtop>
|
||||
</el-backtop> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -42,11 +43,15 @@
|
||||
</div>
|
||||
<AppMain />
|
||||
<Settings v-if="defaultSettings.showSettings" />
|
||||
|
||||
<!-- 返回顶部 -->
|
||||
<el-backtop target=".app-main">
|
||||
<!-- <el-backtop target=".app-main">
|
||||
<svg-icon icon-class="backtop" size="24px" />
|
||||
</el-backtop>
|
||||
</el-backtop> -->
|
||||
</div>
|
||||
|
||||
<!-- 悬浮球 -->
|
||||
<FastMenu></FastMenu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -105,6 +110,7 @@ function handleOutsideClick() {
|
||||
function toggleSidebar() {
|
||||
appStore.toggleSidebar();
|
||||
}
|
||||
function showFastMenu() {}
|
||||
|
||||
const route = useRoute();
|
||||
watch(route, () => {
|
||||
|
||||
@@ -14,5 +14,6 @@ export * from "./modules/settings";
|
||||
export * from "./modules/tags-view";
|
||||
export * from "./modules/user";
|
||||
export * from "./modules/dict";
|
||||
export * from "./modules/quick";
|
||||
|
||||
export { store };
|
||||
|
||||
@@ -16,6 +16,7 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
// 路由是否加载完成
|
||||
const isRoutesLoaded = ref(false);
|
||||
|
||||
const menus = ref<RouteVO[]>([])
|
||||
|
||||
|
||||
/**
|
||||
@@ -31,10 +32,9 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
}
|
||||
MenuAPI.getRoutes()
|
||||
.then((data) => {
|
||||
menus.value = data
|
||||
if (!isTest) {
|
||||
const dynamicRoutes = parseDynamicRoutes(data.filter(v => v.type == 0));
|
||||
console.log('dynamicRoutes')
|
||||
console.log(dynamicRoutes)
|
||||
dynamicRoutes.forEach((route) => {
|
||||
//过滤出可见子节点
|
||||
let onlyOneChild = null
|
||||
@@ -95,8 +95,60 @@ export const usePermissionStore = defineStore("permission", () => {
|
||||
});
|
||||
isRoutesLoaded.value = false;
|
||||
};
|
||||
function getMenuMap() {
|
||||
// 初始化Map
|
||||
const map = new Map();
|
||||
|
||||
// 定义递归函数处理菜单节点
|
||||
function processMenuNode(menuNode) {
|
||||
// 将当前节点存入Map
|
||||
map.set(menuNode.menuId, menuNode);
|
||||
|
||||
// 如果有子节点且子节点数组不为空,则递归处理每个子节点
|
||||
if (menuNode.children && Array.isArray(menuNode.children) && menuNode.children.length > 0) {
|
||||
menuNode.children.forEach((childNode) => {
|
||||
processMenuNode(childNode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历根级菜单,逐个处理
|
||||
if (menus.value && Array.isArray(menus.value)) {
|
||||
menus.value.forEach((rootMenu) => {
|
||||
processMenuNode(rootMenu);
|
||||
});
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
function returnMenuName(menuId: number | string) {
|
||||
const menu = menusIdMap.value.get(`${menuId}`);
|
||||
return menu ? menu.title : '';
|
||||
}
|
||||
const menusIdMap = computed(() => {
|
||||
const map = getMenuMap();
|
||||
return map;
|
||||
});
|
||||
|
||||
function menuJump(menuId: number | string) {
|
||||
const menu = menusIdMap.value.get(`${menuId}`);
|
||||
console.log('menu', menu);
|
||||
if (menu) {
|
||||
if (menu.name) {
|
||||
router.push({ name: menu.name as string })
|
||||
|
||||
} else {
|
||||
router.push({ path: menu.path as string })
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
menuJump,
|
||||
returnMenuName,
|
||||
menus,
|
||||
routes,
|
||||
mixedLayoutLeftRoutes,
|
||||
isRoutesLoaded,
|
||||
|
||||
37
src/store/modules/quick.ts
Normal file
37
src/store/modules/quick.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
import { store } from "@/store";
|
||||
import quickApi, { type QuickMenu } from "@/api/account/quick";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
|
||||
|
||||
export const useQuickStore = defineStore("quick", () => {
|
||||
const quickMenus = ref<QuickMenu[]>([]);
|
||||
|
||||
async function getQuickMenus() {
|
||||
const res = await quickApi.getList({ isEdit: 0 });
|
||||
const obj: any = {}
|
||||
let arr = []
|
||||
for (let menu of res) {
|
||||
if (obj.hasOwnProperty(menu.menuId) || menu.status != 1 || !usePermissionStoreHook().returnMenuName(menu.menuId)) {
|
||||
continue;
|
||||
} else {
|
||||
obj[menu.menuId] = true;
|
||||
arr.push(menu)
|
||||
}
|
||||
}
|
||||
quickMenus.value = arr;
|
||||
}
|
||||
getQuickMenus()
|
||||
return {
|
||||
quickMenus, getQuickMenus
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* 用于在组件外部(如在Pinia Store 中)使用 Pinia 提供的 store 实例。
|
||||
* 官方文档解释了如何在组件外部使用 Pinia Store:
|
||||
* https://pinia.vuejs.org/core-concepts/outside-component-usage.html#using-a-store-outside-of-a-component
|
||||
*/
|
||||
export function useQuickStoreHook() {
|
||||
return useQuickStore(store);
|
||||
}
|
||||
@@ -299,4 +299,18 @@ export function includesString(target, searchStr, options = {}) {
|
||||
|
||||
// 4. 执行包含判断
|
||||
return processedTarget.includes(processedSearch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验手机号码(中国大陆)
|
||||
* - 支持 11 位手机号,号段 13x-19x
|
||||
* @param {string} phone
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isValidMobile(phone: string): boolean {
|
||||
if (!phone && phone !== 0) return false;
|
||||
const s = String(phone).trim();
|
||||
// 中国大陆手机号正则:以1开头,第二位3-9,后面9位数字,总共11位
|
||||
const mobileRegex = /^1[3-9]\d{9}$/;
|
||||
return mobileRegex.test(s);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ service.interceptors.response.use(
|
||||
return;
|
||||
}
|
||||
ElMessage.error(formatErrorMsg(msg || "Error"));
|
||||
return Promise.reject(new Error(formatErrorMsg(msg || "Error")));
|
||||
return Promise.reject(response.data);
|
||||
},
|
||||
async (error: any) => {
|
||||
|
||||
|
||||
5
src/views/admin/system/commonlyUsedMenu/index.vue
Normal file
5
src/views/admin/system/commonlyUsedMenu/index.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<FastMenuConfig></FastMenuConfig>
|
||||
</div>
|
||||
</template>
|
||||
915
src/views/applyments/applyment_in.vue
Normal file
915
src/views/applyments/applyment_in.vue
Normal file
@@ -0,0 +1,915 @@
|
||||
<!-- 选择商户以及进件渠道 -->
|
||||
<template>
|
||||
<div class="gyq_container">
|
||||
<div class="gyq_content" ref="containerRef">
|
||||
<div class="row">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="250px" label-position="right">
|
||||
<el-form-item label="选择商户类型" prop="merchantBaseInfo.userType">
|
||||
<el-radio-group v-model="form.merchantBaseInfo.userType">
|
||||
<el-radio label="个体商户" value="0"></el-radio>
|
||||
<el-radio label="企业商户" value="1"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div class="title_row">
|
||||
<div class="t">
|
||||
<el-text size="large" type="primary">商户基础信息</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="企业类型" v-if="form.merchantBaseInfo.userType == '1'">
|
||||
<el-radio-group v-model="form.merchantBaseInfo.companyChildType">
|
||||
<el-radio label="普通企业" value="1"></el-radio>
|
||||
<el-radio label="事业单位" value="2"></el-radio>
|
||||
<el-radio label="政府机关" value="3"></el-radio>
|
||||
<el-radio label="社会组织" value="4"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户简称" prop="merchantBaseInfo.shortName">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.shortName" placeholder="请输入商户简称"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="行业类别码" prop="merchantBaseInfo.mccCode">
|
||||
<selectCategory v-model="form.merchantBaseInfo.mccCode" />
|
||||
</el-form-item>
|
||||
<el-form-item label="支付宝账号" prop="merchantBaseInfo.alipayAccount">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.alipayAccount" placeholder="请输入支付宝账号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人类型">
|
||||
<el-radio-group v-model="form.merchantBaseInfo.contactPersonType">
|
||||
<el-radio label="经营者/法定代表人" :value="'LEGAL'"></el-radio>
|
||||
<el-radio label="经办人" :value="'SUPER'"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="证件类型">
|
||||
<el-radio-group v-model="form.merchantBaseInfo.certType">
|
||||
<el-radio label="身份证" value="0"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人身份证号" prop="merchantBaseInfo.contactPersonId">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.contactPersonId" placeholder="请输入联系人身份证号"
|
||||
style="width: 300px;" v-loading="contactIdCardFrontPicUploadLoading"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人证件有效期开始日期" prop="merchantBaseInfo.contactPersonIdStartDate"
|
||||
v-loading="contactIdCardBackPicUploadLoading">
|
||||
<el-date-picker v-model="form.merchantBaseInfo.contactPersonIdStartDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人证件有效期结束日期" prop="merchantBaseInfo.contactPersonIdEndDate"
|
||||
v-loading="contactIdCardBackPicUploadLoading">
|
||||
<div class="center">
|
||||
<el-date-picker v-model="form.merchantBaseInfo.contactPersonIdEndDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
<el-checkbox
|
||||
@change="e => e ? form.merchantBaseInfo.contactPersonIdEndDate = longTime : form.merchantBaseInfo.contactPersonIdEndDate = ''">长期有效</el-checkbox>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人身份证正面照片" prop="merchantBaseInfo.contactIdCardFrontPic.url">
|
||||
<div class="column">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.merchantBaseInfo.contactIdCardFrontPic.url"
|
||||
@on-success="contactIdCardFrontPicUpload" />
|
||||
<div class="tips">国徽面为正面 (上传图片自动识别 有效期)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人身份证反面照片" prop="merchantBaseInfo.contactIdCardBackPic.url">
|
||||
<div class="column">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.merchantBaseInfo.contactIdCardBackPic.url"
|
||||
@on-success="contactIdCardBackPicUpload" />
|
||||
<div class="tips">人像面为反面 (上传图片自动识别 身份证名称 身份证号)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人手机号" prop="merchantBaseInfo.contactPhone">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.contactPhone" placeholder="请输入联系人手机号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人地址" prop="merchantBaseInfo.contactAddr">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.contactAddr" placeholder="请输入联系人地址"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系人电子邮箱" prop="merchantBaseInfo.contactEmail">
|
||||
<el-input v-model.trim="form.merchantBaseInfo.contactEmail" placeholder="请输入联系人电子邮箱"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<div class="title_row">
|
||||
<div class="t">
|
||||
<el-text size="large" type="primary">法人信息</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="身份证手持图片" prop="legalPersonInfo.idCardHandPic.url">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.legalPersonInfo.idCardHandPic.url" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证正面图片" prop="legalPersonInfo.idCardFrontPic.url">
|
||||
<div class="column">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.legalPersonInfo.idCardFrontPic.url"
|
||||
@on-success="idCardFrontPicSuccess" />
|
||||
<div class="tips">国徽面为正面 (上传图片自动识别 有效期)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证反面图片" prop="legalPersonInfo.idCardBackPic.url">
|
||||
<div class="column">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.legalPersonInfo.idCardBackPic.url"
|
||||
@on-success="idCardBackPicSuccess" />
|
||||
<div class="tips">人像面为反面 (上传图片自动识别 身份证名称 身份证号)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人姓名" prop="legalPersonInfo.legalPersonName" v-loading="idCardFrontPicSuccessLoading">
|
||||
<el-input v-model.trim="form.legalPersonInfo.legalPersonName" placeholder="请输入法定代表人姓名"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人身份证号" prop="legalPersonInfo.legalPersonId" v-loading="idCardFrontPicSuccessLoading">
|
||||
<el-input v-model.trim="form.legalPersonInfo.legalPersonId" placeholder="请输入法定代表人身份证号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人身份证开始日期" prop="legalPersonInfo.legalIdPersonStartDate"
|
||||
v-loading="idCardBackPicSuccessLoading">
|
||||
<el-date-picker v-model="form.legalPersonInfo.legalIdPersonStartDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人身份证结束日期" prop="legalPersonInfo.legalPersonIdEndDate"
|
||||
v-loading="idCardBackPicSuccessLoading">
|
||||
<div class="center">
|
||||
<el-date-picker v-model="form.legalPersonInfo.legalPersonIdEndDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
<el-checkbox
|
||||
@change="e => e ? form.legalPersonInfo.legalPersonIdEndDate = longTime : form.legalPersonInfo.legalPersonIdEndDate = ''">长期有效</el-checkbox>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人手机号" prop="legalPersonInfo.legalPersonPhone">
|
||||
<el-input v-model.trim="form.legalPersonInfo.legalPersonPhone" placeholder="请输入法定代表人手机号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人电子邮箱" prop="legalPersonInfo.legalPersonEmail">
|
||||
<el-input v-model.trim="form.legalPersonInfo.legalPersonEmail" placeholder="请输入法定代表人电子邮箱"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人性别" prop="legalPersonInfo.legalGender">
|
||||
<el-radio-group v-model="form.legalPersonInfo.legalGender">
|
||||
<el-radio label="男" :value="'0'"></el-radio>
|
||||
<el-radio label="女" :value="'1'"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="法定代表人联系地址" prop="legalPersonInfo.legalAddress">
|
||||
<el-input v-model.trim="form.legalPersonInfo.legalAddress" placeholder="请输入法定代表人联系地址"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<div class="title_row">
|
||||
<div class="t">
|
||||
<el-text size="large" type="primary">营业执照信息</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="营业执照全称" prop="businessLicenceInfo.licenceName">
|
||||
<el-input v-model.trim="form.businessLicenceInfo.licenceName" placeholder="请输入营业执照全称"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照注册号" prop="businessLicenceInfo.licenceNo" v-loading="licensePicSuccessLoading">
|
||||
<el-input v-model.trim="form.businessLicenceInfo.licenceNo" placeholder="请输入营业执照注册号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照有效期开始日期" prop="businessLicenceInfo.licenceStartDate">
|
||||
<el-date-picker v-model="form.businessLicenceInfo.licenceStartDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照有效期结束日期" prop="businessLicenceInfo.licenceEndDate">
|
||||
<div class="center">
|
||||
<el-date-picker v-model="form.businessLicenceInfo.licenceEndDate" type="date" placeholder="选择日期"
|
||||
value-format="YYYY-MM-DD" style="width: 300px;" />
|
||||
<el-checkbox
|
||||
@change="e => e ? form.businessLicenceInfo.licenceEndDate = longTime : form.businessLicenceInfo.licenceEndDate = ''">长期有效</el-checkbox>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="注册地址" prop="businessLicenceInfo.registeredAddress">
|
||||
<el-input v-model.trim="form.businessLicenceInfo.registeredAddress" placeholder="请输入注册地址"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="营业执照照片" prop="businessLicenceInfo.licensePic.url">
|
||||
<div class="column">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.businessLicenceInfo.licensePic.url"
|
||||
@on-success="licensePicSuccess" />
|
||||
<div class="tips">(上传图片自动识别 营业执照编号)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<div class="title_row">
|
||||
<div class="t">
|
||||
<el-text size="large" type="primary">门店信息</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="商户归属省市区" prop="storeInfo.mercProvCode">
|
||||
<selectAddress v-model:provCode="form.storeInfo.mercProvCode" v-model:cityCode="form.storeInfo.mercCityCode"
|
||||
v-model:areaCode="form.storeInfo.mercAreaCode" v-model:prov="form.storeInfo.mercProv"
|
||||
v-model:city="form.storeInfo.mercCity" v-model:area="form.storeInfo.mercArea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="营业地址" prop="storeInfo.businessAddress">
|
||||
<el-input v-model.trim="form.storeInfo.businessAddress" placeholder="请输入营业地址"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="经营场所内设照片" prop="storeInfo.insidePic.url">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.storeInfo.insidePic.url" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门头照" prop="storeInfo.doorPic.url">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.storeInfo.doorPic.url" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收银台照" prop="storeInfo.cashierDeskPic.url">
|
||||
<single-image-upload :maxFileSize="2" v-model="form.storeInfo.cashierDeskPic.url" />
|
||||
</el-form-item>
|
||||
<div class="title_row">
|
||||
<div class="t">
|
||||
<el-text size="large" type="primary">结算信息</el-text>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="结算类型" prop="settlementInfo.settlementType">
|
||||
<el-radio-group v-model="form.settlementInfo.settlementType">
|
||||
<el-radio label="非法人结算" value="0" disabled></el-radio>
|
||||
<el-radio label="法人结算" value="1"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算卡类型" prop="settlementInfo.settlementCardType">
|
||||
<el-radio-group v-model="form.settlementInfo.settlementCardType">
|
||||
<el-radio label="对私借记卡" :value="'11'"></el-radio>
|
||||
<el-radio label="对公借记卡" :value="'21'"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算卡号" prop="settlementInfo.settlementCardNo">
|
||||
<el-input v-model.trim="form.settlementInfo.settlementCardNo" placeholder="请输入结算卡号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户名称" prop="settlementInfo.settlementName" v-loading="bankCardFrontPicSuccessLoading">
|
||||
<el-input v-model.trim="form.settlementInfo.settlementName" placeholder="请输入开户名称"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="结算银行预留手机号" prop="settlementInfo.bankMobile">
|
||||
<el-input v-model.trim="form.settlementInfo.bankMobile" placeholder="请输入结算银行预留手机号"
|
||||
style="width: 300px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="开户行省市区" prop="settlementInfo.openAccProvinceId">
|
||||
<selectAddress v-model:wxProvinceCode="wxProvinceCode"
|
||||
v-model:provCode="form.settlementInfo.openAccProvinceId"
|
||||
v-model:cityCode="form.settlementInfo.openAccCityId" v-model:areaCode="form.settlementInfo.openAccAreaId"
|
||||
v-model:prov="form.settlementInfo.openAccProvince" v-model:city="form.settlementInfo.openAccCity"
|
||||
v-model:area="form.settlementInfo.openAccArea" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户行" prop="settlementInfo.bankInstId">
|
||||
<selectBank :province="form.settlementInfo.openAccProvince" :city="form.settlementInfo.openAccCity"
|
||||
:city-code="wxProvinceCode" v-model:bankInstId="form.settlementInfo.bankInstId"
|
||||
v-model:bankName="form.settlementInfo.bankName"
|
||||
v-model:bank-branch-code="form.settlementInfo.bankBranchCode"
|
||||
v-model:bank-branch-name="form.settlementInfo.bankBranchName" />
|
||||
</el-form-item>
|
||||
<el-form-item label="银行卡正面" prop="settlementInfo.bankCardFrontPic.url">
|
||||
<div class="column">
|
||||
<SingleImageUpload :maxFileSize="2" v-model="form.settlementInfo.bankCardFrontPic.url"
|
||||
@on-success="bankCardFrontPicSuccess" />
|
||||
<div class="tips">(上传图片自动识别 银行卡号)</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="银行卡反面" prop="settlementInfo.bankCardBackPic.url">
|
||||
<SingleImageUpload :maxFileSize="2" v-model="form.settlementInfo.bankCardBackPic.url" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开户许可证" prop="settlementInfo.openAccountLicencePic.url">
|
||||
<SingleImageUpload :maxFileSize="2" v-model="form.settlementInfo.openAccountLicencePic.url" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="btn_wrap" :style="{ width: `${containerDomInfo.width}px`, left: `${containerDomInfo.left}px` }"
|
||||
v-if="formType != 'check'">
|
||||
<div class="btn_content">
|
||||
<div class="btn">
|
||||
<el-button type="primary" size="large" style="width: 100%;" :loading="loading"
|
||||
@click="submitForm">提交</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button style="width: 100%;" size="large" @click="router.back()">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, onUnmounted } from "vue";
|
||||
import selectAddress from "./components/selectAddress.vue";
|
||||
import selectBank from "./components/selectBank.vue";
|
||||
import selectCategory from "./components/selectCategory.vue";
|
||||
import SingleImageUpload from "@/components/Upload/SingleImageUpload.vue";
|
||||
import { entryManagerPost, getInfoByImg, entryManagerDetail } from '@/api/common'
|
||||
import _ from 'lodash'
|
||||
import dayjs from "dayjs";
|
||||
import { isValidMobile } from "@/utils";
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const containerRef = ref<any>(null)
|
||||
|
||||
const containerDomInfo = ref({
|
||||
left: 0,
|
||||
width: 0
|
||||
})
|
||||
|
||||
const longTime = ref('2099-12-31')
|
||||
|
||||
const wxProvinceCode = ref('')
|
||||
|
||||
// 获取进件详情
|
||||
async function getDetailAjax(shopId: string) {
|
||||
try {
|
||||
const res: any = await entryManagerDetail({
|
||||
shopId: shopId
|
||||
})
|
||||
if (res && res.shopId) {
|
||||
form.value = res
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取containerDomInfo信息
|
||||
function getContainerDomInfo() {
|
||||
containerDomInfo.value = containerRef.value?.getBoundingClientRect() ?? {}
|
||||
}
|
||||
|
||||
const debouncedCheckWidth = _.debounce(getContainerDomInfo, 100)
|
||||
|
||||
onMounted(() => {
|
||||
getContainerDomInfo()
|
||||
window.addEventListener('resize', debouncedCheckWidth)
|
||||
|
||||
const type = route.query.type
|
||||
const shopId: string = String(route.query.shopId ?? '')
|
||||
const licenceNo: string = String(route.query.licenceNo ?? '')
|
||||
|
||||
if (shopId) {
|
||||
getDetailAjax(shopId)
|
||||
}
|
||||
|
||||
if (licenceNo && type && type == 'editor') {
|
||||
formType.value = 'editor'
|
||||
}
|
||||
|
||||
if (type && type == 'check') {
|
||||
formType.value = 'check'
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', debouncedCheckWidth)
|
||||
})
|
||||
|
||||
// 表单操作类型 add添加 editor编辑 check查看
|
||||
const formType = ref('add')
|
||||
const formRef = ref<any>(null);
|
||||
const form = ref({
|
||||
shopId: route.query.shopId,
|
||||
merchantCode: '',
|
||||
// 【必填】商户基础信息
|
||||
merchantBaseInfo: {
|
||||
userType: '0', // 0: 个体商户;1: 企业商户;3: 小微商户 暂不支持
|
||||
shortName: '', // 商户简称--企业、个体必填
|
||||
mccCode: '', // 行业类别码--必填
|
||||
alipayAccount: '', // 【必填】支付宝账号
|
||||
contactPersonType: 'LEGAL', // 联系人类型 LEGAL: 经营者/法定代表人 SUPER: 经办人 默认LEGAL
|
||||
contactName: '', // 联系人姓名
|
||||
certType: '0', // 证件类型 目前只支持身份证 传值:0
|
||||
contactPersonId: '', // 联系人身份证号
|
||||
contactPersonIdStartDate: '', // 联系人证件有效期开始日期
|
||||
contactPersonIdEndDate: '', // 联系人证件有效期结束日期
|
||||
// 联系人身份证反面照片
|
||||
contactIdCardBackPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 联系人身份证正面照片
|
||||
contactIdCardFrontPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
contactPhone: '', // 联系人手机号
|
||||
contactAddr: '', // 联系人地址
|
||||
contactEmail: '', // 联系人电子邮箱
|
||||
companyChildType: '1', // 企业类型,1:普通企业,2:事业单位,3:政府机关,4:社会组织 默认值:1
|
||||
},
|
||||
// 【必填】法人信息
|
||||
legalPersonInfo: {
|
||||
legalPersonName: '', // 法定代表人姓名
|
||||
legalPersonId: '', // 法定代表人身份证号
|
||||
legalIdPersonStartDate: '', // 法定代表人证件有效期开始日期
|
||||
legalPersonIdEndDate: '', // 法定代表人证件有效期结束日期
|
||||
legalPersonPhone: '', // 法定代表人手机号
|
||||
legalPersonEmail: '', // 法定代表人电子邮箱
|
||||
legalGender: '', // 法人性别(0男 1女)
|
||||
legalAddress: '', // 法人联系地址
|
||||
// 身份证手持 图片
|
||||
idCardHandPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 身份证正面 图片
|
||||
idCardFrontPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 身份证反面 图片
|
||||
idCardBackPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
},
|
||||
// 【必填】营业执照信息
|
||||
businessLicenceInfo: {
|
||||
licenceName: '', // 营业执照全称--非小微必填
|
||||
licenceNo: '', // 营业执照注册号--非小微必填
|
||||
licenceStartDate: '', // 营业执照有效期开始日期--非小微必填
|
||||
licenceEndDate: '', // 营业执照有效期结束日期--非小微必填
|
||||
registeredAddress: '', // 注册地址--非小微必填
|
||||
licensePic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
},
|
||||
// 【必填】门店信息
|
||||
storeInfo: {
|
||||
mercProvCode: '', // 【必填】商户归属省Code
|
||||
mercCityCode: '', // 【必填】商户归属市Code
|
||||
mercAreaCode: '', // 【必填】商户归属区Code
|
||||
mercProv: '', // 商户归属省
|
||||
mercCity: '', // 商户归属市
|
||||
mercArea: '', // 商户归属区
|
||||
businessAddress: '', // 【必填】 营业地址
|
||||
// 经营场所内设照片
|
||||
insidePic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 门头照
|
||||
doorPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 收银台照
|
||||
cashierDeskPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
},
|
||||
// 【必填】结算信息
|
||||
settlementInfo: {
|
||||
settlementType: '1', // 结算类型 0:非法人结算, 1:法人结算
|
||||
noLegalName: '', // 非法人姓名
|
||||
noLegalId: '', // 非法人身份证号
|
||||
settlementCardType: '', // 结算卡类型 必填 11 对私借记卡(结算卡正面照、结算卡反面照图片必传) 21 对公借记卡(只须结算卡正面照片)
|
||||
settlementCardNo: '', // 结算卡号
|
||||
settlementName: '', // 开户名称
|
||||
bankMobile: '', // 结算银行预留手机号
|
||||
openAccProvinceId: '', // 开户行省ID
|
||||
openAccCityId: '', // 开户行市ID
|
||||
openAccAreaId: '', // 开户行区ID
|
||||
openAccProvince: '', // 开户行省
|
||||
openAccCity: '', // 开户行市
|
||||
openAccArea: '', // 开户行区
|
||||
bankName: '', // 开户行别名名称 bankAlias
|
||||
bankInstId: '', // 开户行缩写 bankCode
|
||||
bankType: '', // 开户行编号 bankAliasCode
|
||||
bankBranchName: '', // 支行开户行行别名称 branchName
|
||||
bankBranchCode: '', // 支行开户行编号 bankCode
|
||||
// 银行卡正面
|
||||
bankCardFrontPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 银行卡反面
|
||||
bankCardBackPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 开户许可证
|
||||
openAccountLicencePic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 非法人手持结算授权书
|
||||
noLegalHandSettleAuthPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 非法人结算授权书
|
||||
noLegalSettleAuthPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 非法人身份证正面
|
||||
noLegalIdCardFrontPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
// 非法人身份证反面
|
||||
noLegalIdCardBackPic: {
|
||||
url: '',
|
||||
wechatId: '', // 微信图片ID
|
||||
alipayId: '', // 支付宝图片ID
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const rules = reactive({
|
||||
'merchantBaseInfo.userType': [{ required: true, message: '请选择商户类型', trigger: 'change' }],
|
||||
'merchantBaseInfo.shortName': [{ required: true, message: '请输入商户简称', trigger: 'blur' }],
|
||||
'merchantBaseInfo.mccCode': [{ required: true, message: '请输入行业类别码', trigger: 'change' }],
|
||||
'merchantBaseInfo.alipayAccount': [{ required: true, message: '请输入支付宝账号', trigger: 'blur' }],
|
||||
'merchantBaseInfo.contactPersonId': [{ required: true, message: '请输入联系人身份证号', trigger: 'blur' }],
|
||||
'merchantBaseInfo.contactPersonIdStartDate': [{ required: true, message: '请选择联系人证件有效期开始日期', trigger: 'change' }],
|
||||
'merchantBaseInfo.contactPersonIdEndDate': [{ required: true, message: '请选择联系人证件有效期结束日期', trigger: 'change' }],
|
||||
'merchantBaseInfo.contactIdCardFrontPic.url': [{ required: true, message: '请上传联系人身份证正面照片', trigger: 'blur' }],
|
||||
'merchantBaseInfo.contactIdCardBackPic.url': [{ required: true, message: '请上传联系人身份证反面照片', trigger: 'blur' }],
|
||||
'merchantBaseInfo.contactPhone': [
|
||||
{ required: true, message: '请输入联系人手机号', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!isValidMobile(value)) {
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
'merchantBaseInfo.contactAddr': [{ required: true, message: '请输入联系人地址', trigger: 'blur' }],
|
||||
'merchantBaseInfo.contactEmail': [{ required: true, message: '请输入联系人电子邮箱', trigger: 'blur' }],
|
||||
'legalPersonInfo.idCardHandPic.url': [{ required: true, message: '请上传身份证手持图片', trigger: 'blur' }],
|
||||
'legalPersonInfo.idCardFrontPic.url': [{ required: true, message: '请上传身份证正面图片', trigger: 'blur' }],
|
||||
'legalPersonInfo.idCardBackPic.url': [{ required: true, message: '请上传身份证反面图片', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalPersonName': [{ required: true, message: '请输入法定代表人姓名', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalPersonId': [{ required: true, message: '请输入法定代表人身份证号', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalIdPersonStartDate': [{ required: true, message: '请输入法定代表人身份证开始日期', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalPersonIdEndDate': [{ required: true, message: '请输入法定代表人身份证结束日期', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalPersonPhone': [
|
||||
{ required: true, message: '请输入法定代表人手机号', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!isValidMobile(value)) {
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
'legalPersonInfo.legalPersonEmail': [{ required: true, message: '请输入法定代表人电子邮箱', trigger: 'blur' }],
|
||||
'legalPersonInfo.legalGender': [{ required: true, message: '请选择法定代表人性别', trigger: 'change' }],
|
||||
'legalPersonInfo.legalAddress': [{ required: true, message: '请输入法定代表人联系地址', trigger: 'blur' }],
|
||||
// 营业执照信息
|
||||
'businessLicenceInfo.licenceName': [{ required: true, message: '请输入营业执照全称', trigger: 'blur' }],
|
||||
'businessLicenceInfo.licenceNo': [{ required: true, message: '请输入营业执照注册号', trigger: 'blur' }],
|
||||
'businessLicenceInfo.licenceStartDate': [{ required: true, message: '请输入营业执照有效期开始日期', trigger: 'blur' }],
|
||||
'businessLicenceInfo.licenceEndDate': [{ required: true, message: '请输入营业执照有效期结束日期', trigger: 'blur' }],
|
||||
'businessLicenceInfo.registeredAddress': [{ required: true, message: '请输入注册地址', trigger: 'blur' }],
|
||||
'businessLicenceInfo.licensePic.url': [{ required: true, message: '请上传营业执照照片', trigger: 'blur' }],
|
||||
// 门店信息
|
||||
'storeInfo.mercProvCode': [{ required: true, message: '请选择商户归属省市区', trigger: 'change' }],
|
||||
'storeInfo.mercCityCode': [{ required: true, message: '请选择商户归属市', trigger: 'change' }],
|
||||
'storeInfo.mercAreaCode': [{ required: true, message: '请选择商户归属区', trigger: 'change' }],
|
||||
'storeInfo.businessAddress': [{ required: true, message: '请输入营业地址', trigger: 'blur' }],
|
||||
'storeInfo.insidePic.url': [{ required: true, message: '请上传经营场所内设照片', trigger: 'blur' }],
|
||||
'storeInfo.doorPic.url': [{ required: true, message: '请上传门头照', trigger: 'blur' }],
|
||||
'storeInfo.cashierDeskPic.url': [{ required: true, message: '请上传收银台照', trigger: 'blur' }],
|
||||
// 结算信息
|
||||
'settlementInfo.settlementType': [{ required: true, message: '请选择结算类型', trigger: 'change' }],
|
||||
'settlementInfo.settlementCardType': [{ required: true, message: '请选择结算卡类型', trigger: 'change' }],
|
||||
'settlementInfo.settlementCardNo': [{ required: true, message: '请输入结算卡号', trigger: 'blur' }],
|
||||
'settlementInfo.settlementName': [{ required: true, message: '请输入开户名称', trigger: 'blur' }],
|
||||
'settlementInfo.bankMobile': [
|
||||
{ required: true, message: '请输入结算银行预留手机号', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (!isValidMobile(value)) {
|
||||
callback(new Error('请输入正确的手机号'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
'settlementInfo.openAccProvinceId': [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (form.value.settlementInfo.openAccProvinceId == '' || form.value.settlementInfo.openAccCityId == '' || form.value.settlementInfo.openAccAreaId == '') {
|
||||
callback(new Error('请选择开户行省市区'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
'settlementInfo.bankInstId': [
|
||||
{
|
||||
required: true,
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (form.value.settlementInfo.bankInstId == '') {
|
||||
callback(new Error('请选择开户行以及支行'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
trigger: 'change'
|
||||
}
|
||||
],
|
||||
'settlementInfo.bankCardFrontPic.url': [
|
||||
{
|
||||
required: true,
|
||||
message: '请上传银行卡正面图片',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'settlementInfo.bankCardBackPic.url': [
|
||||
{
|
||||
required: true,
|
||||
message: '请上传银行卡反面图片',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
'settlementInfo.openAccountLicencePic.url': [
|
||||
{
|
||||
required: true,
|
||||
message: '请上传开户许可证图片',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 联系人身份证正面照片
|
||||
const contactIdCardFrontPicUploadLoading = ref(false)
|
||||
async function contactIdCardFrontPicUpload(url: string) {
|
||||
try {
|
||||
form.value.merchantBaseInfo.contactIdCardBackPic.alipayId = ''
|
||||
form.value.merchantBaseInfo.contactIdCardBackPic.wechatId = ''
|
||||
|
||||
contactIdCardFrontPicUploadLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'IdCard'
|
||||
})
|
||||
|
||||
let date = res.subImages[0].kvInfo.data.validPeriod.split('-')
|
||||
form.value.merchantBaseInfo.contactPersonIdStartDate = dayjs(date[0]).format('YYYY-MM-DD')
|
||||
form.value.merchantBaseInfo.contactPersonIdEndDate = dayjs(date[1]).format('YYYY-MM-DD')
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
contactIdCardFrontPicUploadLoading.value = false
|
||||
}
|
||||
|
||||
// 联系人身份证反面照片
|
||||
const contactIdCardBackPicUploadLoading = ref(false)
|
||||
async function contactIdCardBackPicUpload(url: any) {
|
||||
try {
|
||||
form.value.merchantBaseInfo.contactIdCardFrontPic.alipayId = ''
|
||||
form.value.merchantBaseInfo.contactIdCardFrontPic.wechatId = ''
|
||||
|
||||
contactIdCardBackPicUploadLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'IdCard'
|
||||
})
|
||||
form.value.merchantBaseInfo.contactPersonId = res.subImages[0].kvInfo.data.idNumber
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
contactIdCardBackPicUploadLoading.value = false
|
||||
}
|
||||
|
||||
// 法人信息 身份证正面图片
|
||||
const idCardFrontPicSuccessLoading = ref(false)
|
||||
async function idCardFrontPicSuccess(url: string) {
|
||||
try {
|
||||
form.value.legalPersonInfo.idCardBackPic.alipayId = ''
|
||||
form.value.legalPersonInfo.idCardBackPic.wechatId = ''
|
||||
|
||||
idCardFrontPicSuccessLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'IdCard'
|
||||
})
|
||||
|
||||
let date = res.subImages[0].kvInfo.data.validPeriod.split('-')
|
||||
form.value.legalPersonInfo.legalIdPersonStartDate = dayjs(date[0]).format('YYYY-MM-DD')
|
||||
form.value.legalPersonInfo.legalPersonIdEndDate = dayjs(date[1]).format('YYYY-MM-DD')
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
idCardFrontPicSuccessLoading.value = false
|
||||
}
|
||||
|
||||
// 法人信息 身份证反图片
|
||||
const idCardBackPicSuccessLoading = ref(false)
|
||||
async function idCardBackPicSuccess(url: string) {
|
||||
try {
|
||||
form.value.legalPersonInfo.idCardFrontPic.alipayId = ''
|
||||
form.value.legalPersonInfo.idCardFrontPic.wechatId = ''
|
||||
|
||||
idCardBackPicSuccessLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'IdCard'
|
||||
})
|
||||
|
||||
form.value.legalPersonInfo.legalPersonName = res.subImages[0].kvInfo.data.name
|
||||
form.value.legalPersonInfo.legalPersonId = res.subImages[0].kvInfo.data.idNumber
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
idCardBackPicSuccessLoading.value = false
|
||||
}
|
||||
|
||||
// 营业执照信息 营业执照照片
|
||||
const licensePicSuccessLoading = ref(false)
|
||||
async function licensePicSuccess(url: string) {
|
||||
try {
|
||||
form.value.businessLicenceInfo.licensePic.alipayId = ''
|
||||
form.value.businessLicenceInfo.licensePic.wechatId = ''
|
||||
|
||||
licensePicSuccessLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'BusinessLicense'
|
||||
})
|
||||
let data = res.subImages[0].kvInfo.data
|
||||
// console.log('营业执照照片', data);
|
||||
form.value.businessLicenceInfo.licenceName = data.companyName
|
||||
form.value.businessLicenceInfo.licenceNo = data.creditCode
|
||||
// form.value.businessLicenceInfo.licenceStartDate = data.companyName
|
||||
// form.value.businessLicenceInfo.licenceEndDate = data.companyName
|
||||
form.value.businessLicenceInfo.registeredAddress = data.businessAddress
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
licensePicSuccessLoading.value = false
|
||||
}
|
||||
|
||||
// 结算信息 银行卡正面
|
||||
const bankCardFrontPicSuccessLoading = ref(false)
|
||||
async function bankCardFrontPicSuccess(url: string) {
|
||||
try {
|
||||
form.value.settlementInfo.bankCardFrontPic.alipayId = ''
|
||||
form.value.settlementInfo.bankCardFrontPic.wechatId = ''
|
||||
|
||||
bankCardFrontPicSuccessLoading.value = true
|
||||
const res: any = await getInfoByImg({
|
||||
url: url,
|
||||
type: 'BankCard'
|
||||
})
|
||||
let data = res.subImages[0].kvInfo.data
|
||||
// console.log('银行卡正面', data);
|
||||
form.value.settlementInfo.settlementCardNo = data.cardNumber
|
||||
form.value.settlementInfo.bankName = data.bankName
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
bankCardFrontPicSuccessLoading.value = false
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
function submitForm() {
|
||||
console.log('提交的表单数据:', form.value);
|
||||
console.log('formRef', formRef.value);
|
||||
formRef.value.validate(async (valid: boolean) => {
|
||||
console.log('valid===', valid);
|
||||
if (valid) {
|
||||
console.log('表单验证通过,可以提交');
|
||||
try {
|
||||
loading.value = true
|
||||
await entryManagerPost(form.value)
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '提交成功',
|
||||
type: 'success'
|
||||
})
|
||||
router.back()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
loading.value = false
|
||||
} else {
|
||||
console.log('表单验证失败,请检查输入项');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyq_container {
|
||||
padding: 14px;
|
||||
|
||||
.gyq_content {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.tips {
|
||||
--bg: #ffeed8;
|
||||
font-size: 12px;
|
||||
background-color: var(--bg);
|
||||
color: #c57000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
border-radius: 6px;
|
||||
margin-top: 15px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background-color: var(--bg);
|
||||
border: 1px solid var(--bg);
|
||||
border-radius: 4px;
|
||||
transform: rotate(-45deg);
|
||||
top: -7px;
|
||||
left: 40px;
|
||||
transform-origin: center;
|
||||
translate: -50% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title_row {
|
||||
padding: 14px 50px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #ececec;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.t {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background-color: #fff;
|
||||
padding: 0 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn_wrap {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
bottom: 10px;
|
||||
padding-bottom: 24px;
|
||||
|
||||
.btn_content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
|
||||
.btn {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
165
src/views/applyments/components/selectAddress.vue
Normal file
165
src/views/applyments/components/selectAddress.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<div class="center">
|
||||
<el-select placeholder="请选择省" style="width: 100px" v-model="provCode" @change="provChange">
|
||||
<el-option
|
||||
v-for="item in provList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionId"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
placeholder="请选择市"
|
||||
style="width: 100px"
|
||||
:disabled="!provCode"
|
||||
v-model="cityCode"
|
||||
@change="cityChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in cityList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionId"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select
|
||||
placeholder="请选择区"
|
||||
style="width: 100px"
|
||||
:disabled="!cityCode"
|
||||
v-model="areaCode"
|
||||
@change="areaChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in areaList"
|
||||
:key="item.regionId"
|
||||
:label="item.regionName"
|
||||
:value="item.regionId"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { getRegion } from "@/api/common";
|
||||
|
||||
const provList = ref<any[]>([]);
|
||||
const cityList = ref<any[]>([]);
|
||||
const areaList = ref<any[]>([]);
|
||||
|
||||
const provCode = defineModel("provCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
// 监听省份code变化
|
||||
watch(
|
||||
provCode,
|
||||
async (n, o) => {
|
||||
await getRegionAjax();
|
||||
if (n && n !== undefined) {
|
||||
provChange(n, true);
|
||||
|
||||
// 监听市区code变化
|
||||
watch(
|
||||
cityCode,
|
||||
async (n, o) => {
|
||||
if (n !== undefined && n) {
|
||||
cityChange(n, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true, // 可选:初始化立即执行,验证是否监听到初始值
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true, // 可选:初始化立即执行,验证是否监听到初始值
|
||||
}
|
||||
);
|
||||
|
||||
const cityCode = defineModel("cityCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const areaCode = defineModel("areaCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const prov = defineModel("prov", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const city = defineModel("city", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const area = defineModel("area", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const wxProvinceCode = defineModel("wxProvinceCode", {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
// 省份变化 e code isEcho是否回显
|
||||
function provChange(e: string, isEcho: boolean = false) {
|
||||
if (!isEcho) {
|
||||
cityCode.value = "";
|
||||
areaCode.value = "";
|
||||
cityList.value = [];
|
||||
areaList.value = [];
|
||||
}
|
||||
const provObj = provList.value.find((item) => item.regionId == e);
|
||||
prov.value = provObj ? provObj.regionName : "";
|
||||
if (provObj && provObj.children) {
|
||||
cityList.value = provObj.children;
|
||||
}
|
||||
}
|
||||
|
||||
// 市区变化
|
||||
function cityChange(e: string, isEcho: boolean = false) {
|
||||
if (!isEcho) {
|
||||
areaCode.value = "";
|
||||
areaList.value = [];
|
||||
}
|
||||
const cityObj = cityList.value.find((item) => item.regionId == e);
|
||||
|
||||
city.value = cityObj ? cityObj.regionName : "";
|
||||
if (cityObj && cityObj.children) {
|
||||
areaList.value = cityObj.children;
|
||||
wxProvinceCode.value = cityObj.wxProvinceCode;
|
||||
}
|
||||
}
|
||||
|
||||
// 区变化
|
||||
function areaChange(e: string) {
|
||||
const areaObj = areaList.value.find((item) => item.regionId == e);
|
||||
area.value = areaObj ? areaObj.regionName : "";
|
||||
}
|
||||
|
||||
// 获取省市区数据
|
||||
async function getRegionAjax() {
|
||||
try {
|
||||
const res = await getRegion();
|
||||
provList.value = res;
|
||||
} catch (error) {
|
||||
console.error("获取省市区数据失败:", error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
</style>
|
||||
145
src/views/applyments/components/selectBank.vue
Normal file
145
src/views/applyments/components/selectBank.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<div class="select_bank">
|
||||
<!-- 银行 -->
|
||||
<el-select v-model="bankInstId" placeholder="请选择银行,可搜索" style="width: 200px;" filterable remote
|
||||
:remote-method="remoteGetBank" :loading="loading" remote-show-suffix @change="bankChange" :disabled="!province">
|
||||
<el-option v-for="item in bankList" :key="item.bankAliasCode" :label="item.bankAlias" :value="item.bankCode" />
|
||||
</el-select>
|
||||
<!-- 支行 -->
|
||||
<el-select v-model="bankBranchCode" placeholder="请选择支行" style="width: 200px;" :disabled="!bankInstId"
|
||||
@change="bankBranchChange">
|
||||
<el-option v-for="item in bankBranchList" :key="item.bank_branch_id" :label="item.bank_branch_name"
|
||||
:value="item.bank_branch_id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { getBankInfo, getBankBranchList } from "@/api/common";
|
||||
|
||||
const loading = ref(false)
|
||||
const bankNameValue = ref('')
|
||||
|
||||
const props = defineProps({
|
||||
province: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
city: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
cityCode: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.cityCode, async (newValue, oldValue) => {
|
||||
try {
|
||||
// console.log('watch.props.cityCode===', `newValue=${newValue},oldValue=${oldValue}`);
|
||||
await getBankInfoAjax()
|
||||
if (newValue && newValue !== undefined) {
|
||||
// 监听银行code变化
|
||||
watch(bankInstId, (n, o) => {
|
||||
if (n !== undefined && n) {
|
||||
bankChange(n)
|
||||
}
|
||||
}, {
|
||||
immediate: true // 可选:初始化立即执行,验证是否监听到初始值
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
})
|
||||
|
||||
const bankList = ref<Array<{ id: string; bankAlias: string, bankCode: string, bankAliasCode: string, accountBank: string }>>([]);
|
||||
|
||||
const bankInstId = defineModel('bankInstId', {
|
||||
type: String,
|
||||
default: "",
|
||||
});
|
||||
|
||||
const bankName = defineModel('bankName', {
|
||||
type: String,
|
||||
default: "",
|
||||
})
|
||||
|
||||
// 选择银行
|
||||
function bankChange(e: any) {
|
||||
let obj = bankList.value.find(item => item.bankCode == e)
|
||||
if (obj && obj.id) {
|
||||
bankName.value = obj.accountBank
|
||||
bankInstId.value = obj.bankCode
|
||||
getBankBranchListAjax(obj.bankAliasCode)
|
||||
}
|
||||
}
|
||||
|
||||
// 支行开户行编号 bankCode
|
||||
const bankBranchCode = defineModel('bankBranchCode', {
|
||||
type: String,
|
||||
default: "",
|
||||
})
|
||||
|
||||
// 支行开户行行别名称 branchName
|
||||
const bankBranchName = defineModel('bankBranchName', {
|
||||
type: String,
|
||||
default: "",
|
||||
})
|
||||
|
||||
// 选择支行
|
||||
function bankBranchChange(e: string) {
|
||||
let obj = bankBranchList.value.find(item => item.bank_branch_id == e)
|
||||
if (obj && obj.bank_branch_id) {
|
||||
bankBranchName.value = obj.bank_branch_name
|
||||
}
|
||||
}
|
||||
|
||||
// 支行列表
|
||||
const bankBranchList = ref<Array<{ bank_branch_id: string; bank_branch_name: string }>>([]);
|
||||
async function getBankBranchListAjax(bankAliasCode: string) {
|
||||
try {
|
||||
const res: any = await getBankBranchList({
|
||||
bankAliceCode: bankAliasCode,
|
||||
cityCode: props.cityCode
|
||||
})
|
||||
bankBranchList.value = res.data
|
||||
} catch (error) {
|
||||
console.log('', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 远程搜索
|
||||
function remoteGetBank(query: string) {
|
||||
if (query) {
|
||||
bankNameValue.value = query
|
||||
getBankInfoAjax()
|
||||
}
|
||||
}
|
||||
|
||||
// 获取银行列表
|
||||
async function getBankInfoAjax() {
|
||||
try {
|
||||
loading.value = true
|
||||
const res: any = await getBankInfo({
|
||||
page: 1,
|
||||
size: 100,
|
||||
bankName: bankNameValue.value
|
||||
});
|
||||
bankList.value = res.records || [];
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.select_bank {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
}
|
||||
</style>
|
||||
43
src/views/applyments/components/selectCategory.vue
Normal file
43
src/views/applyments/components/selectCategory.vue
Normal file
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<el-cascader v-model="modelValue" placeholder="请选择类目" filterable :options="options" :props="props"
|
||||
style="width: 300px;"></el-cascader>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getCategory } from '@/api/common'
|
||||
|
||||
const modelValue = defineModel({
|
||||
type: String,
|
||||
default: ''
|
||||
})
|
||||
|
||||
const options = ref([])
|
||||
|
||||
const props = ref({
|
||||
children: 'child',
|
||||
emitPath: false
|
||||
})
|
||||
|
||||
// 获取类目
|
||||
async function getCategoryAjax() {
|
||||
try {
|
||||
const res = await getCategory()
|
||||
res.map(item => {
|
||||
item.label = item.firstCategory
|
||||
item.child.map(val => {
|
||||
val.label = `${val.secondCategory}`
|
||||
val.value = `${val.firstCategoryCode}_${val.secondCategoryCode}`
|
||||
})
|
||||
})
|
||||
options.value = res
|
||||
console.log('options.value', options.value);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getCategoryAjax()
|
||||
})
|
||||
</script>
|
||||
162
src/views/applyments/components/selectShopsDialog.vue
Normal file
162
src/views/applyments/components/selectShopsDialog.vue
Normal file
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<el-dialog title="请选择用户" width="1000px" v-model="visible">
|
||||
<div class="content">
|
||||
<el-form :model="queryForm" inline>
|
||||
<!-- <el-form-item>
|
||||
<el-input v-model="queryForm.no" placeholder="请输入商户号" />
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-input v-model="queryForm.shopName" placeholder="请输入商户名称" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" :loading="tableData.loading" @click="searchHandle">查询</el-button>
|
||||
<el-button icon="Refresh" :loading="tableData.loading" @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading" stripe border
|
||||
style="width: 100%; margin-top: 20px;">
|
||||
<el-table-column label="商户名称" prop="shopName"></el-table-column>
|
||||
<el-table-column label="联系人姓名" prop="contactName"></el-table-column>
|
||||
<el-table-column label="联系人电话" prop="phone"></el-table-column>
|
||||
<el-table-column label="店铺类型" prop="shopType" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="typeFilter(scope.row.shopType).type">{{ typeFilter(scope.row.shopType).label }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" @click="selectHandle(scope.row)">选择</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="row mt14">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
:page-sizes="[10, 30, 50, 100]" background layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- <template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="">确定</el-button>
|
||||
</div>
|
||||
</template> -->
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import ShopApi from "@/api/account/shop";
|
||||
|
||||
// 店铺类型过滤器
|
||||
type TagType = 'primary' | 'success' | 'danger' | 'info' | 'warning';
|
||||
function typeFilter(shopType: string): { value: string; label: string; type: TagType } {
|
||||
const typs: Array<{ value: string; label: string; type: TagType }> = [
|
||||
{
|
||||
value: 'only',
|
||||
label: '单店',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
value: 'chain',
|
||||
label: '连锁',
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
value: 'join',
|
||||
label: '加盟',
|
||||
type: 'danger'
|
||||
}
|
||||
];
|
||||
|
||||
const obj = typs.find(item => item.value === shopType);
|
||||
return obj ? obj : { value: shopType, label: shopType, type: 'info' };
|
||||
}
|
||||
|
||||
const visible = ref(false);
|
||||
|
||||
const queryForm = ref({
|
||||
shopName: "",
|
||||
});
|
||||
|
||||
// 分页大小发生变化
|
||||
function handleSizeChange(e: number) {
|
||||
tableData.size = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 分页发生变化
|
||||
function handleCurrentChange(e: number) {
|
||||
tableData.page = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 查询
|
||||
function searchHandle() {
|
||||
tableData.page = 1;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 重置
|
||||
function resetHandle() {
|
||||
queryForm.value.shopName = "";
|
||||
tableData.page = 1;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
const tableData = reactive({
|
||||
loading: false,
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: [],
|
||||
});
|
||||
|
||||
// 获取店铺列表
|
||||
async function getTableData() {
|
||||
try {
|
||||
tableData.loading = true;
|
||||
const res: any = await ShopApi.getList({
|
||||
page: tableData.page,
|
||||
size: tableData.size,
|
||||
shopName: queryForm.value.shopName,
|
||||
});
|
||||
tableData.list = res.records;
|
||||
tableData.total = res.totalRow;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
} finally {
|
||||
tableData.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: 'success', row: any): void;
|
||||
}>();
|
||||
|
||||
function selectHandle(row: any) {
|
||||
console.log("选择商户:", row);
|
||||
emits('success', row);
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
function show() {
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
getTableData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
63
src/views/applyments/components/singCodeDialog.vue
Normal file
63
src/views/applyments/components/singCodeDialog.vue
Normal file
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<el-dialog title="签约码" width="350px" v-model="visible">
|
||||
<div class="wrap">
|
||||
<el-image :src="srcUrl" style="width: 200px;height: 200px;"></el-image>
|
||||
<el-text>请前往{{ type == 1 ? '支付宝' : '微信' }}进行扫码</el-text>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
const visible = ref(false)
|
||||
|
||||
const srcUrl = ref('')
|
||||
const type = ref(1)
|
||||
|
||||
// 手动生成二维码
|
||||
async function generateQrcode(text) {
|
||||
try {
|
||||
// 生成 Base64 格式的二维码图片
|
||||
const base64 = await QRCode.toDataURL(text, {
|
||||
width: 200,
|
||||
margin: 1,
|
||||
color: {
|
||||
dark: '#000',
|
||||
light: '#fff'
|
||||
}
|
||||
})
|
||||
url.value = base64
|
||||
} catch (err) {
|
||||
console.error('生成二维码失败:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示二维码弹窗
|
||||
function show(url, t) {
|
||||
// console.log(url);
|
||||
visible.value = true
|
||||
type.value = t
|
||||
if (t == 2) {
|
||||
srcUrl.value = url
|
||||
} else {
|
||||
generateQrcode(url)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
</style>
|
||||
312
src/views/applyments/index.vue
Normal file
312
src/views/applyments/index.vue
Normal file
@@ -0,0 +1,312 @@
|
||||
<!-- 进件管理 -->
|
||||
<template>
|
||||
<div class="gyq_container">
|
||||
<div class="gyq_content">
|
||||
<div class="row">
|
||||
<el-form :model="queryForm" inline>
|
||||
<el-form-item label="商户类型">
|
||||
<el-select v-model="queryForm.userType" style="width: 200px;">
|
||||
<el-option v-for="item in userTypeList" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺名称">
|
||||
<el-input style="width: 200px;" v-model="queryForm.shopName" placeholder="请输入店铺名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="进件状态">
|
||||
<el-select v-model="queryForm.status" style="width: 200px;">
|
||||
<el-option v-for="item in statusList" :key="item.value" :label="item.label"
|
||||
:value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付宝账号">
|
||||
<el-input style="width: 200px;" v-model="queryForm.alipayAccount" placeholder="请输入支付宝账号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" :loading="tableData.loading" @click="queryHandle">查询</el-button>
|
||||
<el-button icon="Refresh" :loading="tableData.loading" @click="resetHandle">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="row">
|
||||
<el-button type="primary" icon="Plus" @click="selectShopsDialogRef?.show()">发起进件</el-button>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-table :data="tableData.list" v-loading="tableData.loading" stripe border>
|
||||
<el-table-column label="商户号" prop="merchantCode" width="200"></el-table-column>
|
||||
<el-table-column label="商户简称" prop="shortName" width="150"></el-table-column>
|
||||
<el-table-column label="商户类型" prop="userType" width="120">
|
||||
<template v-slot="scope">
|
||||
{{ userTypeListFilter(scope.row.userType).label }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="绑定店铺名称" prop="shopName" width="200"></el-table-column>
|
||||
<el-table-column label="支付宝进件状态" prop="alipayStatus" min-width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="column">
|
||||
<div>
|
||||
<el-tag :type="statusListFilter(scope.row.alipayStatus).type" disable-transitions>{{
|
||||
statusListFilter(scope.row.alipayStatus).label }}</el-tag>
|
||||
</div>
|
||||
<div class="error_text" v-if="scope.row.alipayStatus == 'REJECTED'">
|
||||
{{ scope.row.alipayErrorMsg }}
|
||||
</div>
|
||||
<div>
|
||||
<el-link type="primary" v-if="scope.row.alipayStatus == 'SIGN '"
|
||||
@click="singCodeDialogRef?.show(scope.row.alipaySignUrl, 1)">查看签约码</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="微信进件状态" prop="wechatStatus" min-width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="column">
|
||||
<div>
|
||||
<el-tag :type="statusListFilter(scope.row.wechatStatus).type" disable-transitions>{{
|
||||
statusListFilter(scope.row.wechatStatus).label }}</el-tag>
|
||||
</div>
|
||||
<div class="error_text" v-if="scope.row.wechatStatus == 'REJECTED'">
|
||||
{{ scope.row.wechatErrorMsg }}
|
||||
</div>
|
||||
<div>
|
||||
<el-link type="primary" v-if="scope.row.wechatStatus == 'SIGN'"
|
||||
@click="singCodeDialogRef?.show(scope.row.wechatSignUrl, 2)">查看签约码</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="更新时间" prop="updateTime" width="200"></el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="200"></el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="160">
|
||||
<template v-slot="scope">
|
||||
<el-button link type="primary"
|
||||
v-if="scope.row.wechatStatus == 'INIT' || scope.row.wechatStatus == 'AUDIT' || scope.row.wechatStatus == 'SIGN' || scope.row.alipayStatus == 'INIT' || scope.row.alipayStatus == 'AUDIT' || scope.row.alipayStatus == 'SIGN'"
|
||||
@click="checkStatusHandle(scope.row)">查询</el-button>
|
||||
<el-button link type="primary" @click="toDetail(scope.row, 'check')">详情</el-button>
|
||||
<el-button link type="primary" @click="toDetail(scope.row, 'editor')"
|
||||
v-if="scope.row.alipayStatus == 'REJECTED' || scope.row.wechatStatus == 'REJECTED'">修改</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="row mt14">
|
||||
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||
:page-sizes="[10, 30, 50, 100]" background layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 选择商户 -->
|
||||
<selectShopsDialog ref="selectShopsDialogRef" @success="selectSuccessHandle" />
|
||||
<!-- 显示签约码 -->
|
||||
<singCodeDialog ref="singCodeDialogRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from 'vue-router';
|
||||
import selectShopsDialog from "./components/selectShopsDialog.vue";
|
||||
import singCodeDialog from "./components/singCodeDialog.vue";
|
||||
import { entryManagerList, queryEntry } from '@/api/common'
|
||||
|
||||
const singCodeDialogRef = ref(null)
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const selectShopsDialogRef = ref(null);
|
||||
|
||||
// 选择商户成功回调
|
||||
function selectSuccessHandle(shop) {
|
||||
console.log('选择的商户:', shop);
|
||||
router.push({ name: 'applyment_in', query: { shopId: shop.id } });
|
||||
}
|
||||
|
||||
const userTypeList = ref([
|
||||
{
|
||||
value: '0',
|
||||
label: '个体商户'
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '企业商户'
|
||||
},
|
||||
])
|
||||
|
||||
function userTypeListFilter(userType) {
|
||||
let obj = userTypeList.value.find(item => item.value == userType)
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: userType,
|
||||
value: userType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const statusList = ref([
|
||||
{
|
||||
value: 'WAIT',
|
||||
label: '待提交',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
value: 'INIT',
|
||||
label: '待处理',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
value: 'AUDIT',
|
||||
label: '待审核',
|
||||
type: 'warning'
|
||||
},
|
||||
{
|
||||
value: 'SIGN',
|
||||
label: '待签约',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
value: 'FINISH',
|
||||
label: '已完成',
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
value: 'REJECTED',
|
||||
label: '失败',
|
||||
type: 'danger'
|
||||
},
|
||||
])
|
||||
|
||||
function statusListFilter(status) {
|
||||
let obj = statusList.value.find(item => item.value == status)
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: status,
|
||||
value: status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const queryForm = ref({
|
||||
userType: '',
|
||||
shopName: '',
|
||||
status: '',
|
||||
alipayAccount: ''
|
||||
});
|
||||
|
||||
function queryHandle() {
|
||||
tableData.page = 1
|
||||
getTableData()
|
||||
}
|
||||
|
||||
function resetHandle() {
|
||||
queryForm.value.userType = ''
|
||||
queryForm.value.shopName = ''
|
||||
queryForm.value.status = ''
|
||||
queryForm.value.alipayAccount = ''
|
||||
queryHandle()
|
||||
}
|
||||
|
||||
const tableData = reactive({
|
||||
loading: false,
|
||||
page: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
list: [],
|
||||
})
|
||||
|
||||
// 分页大小发生变化
|
||||
function handleSizeChange(e) {
|
||||
tableData.size = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 分页发生变化
|
||||
function handleCurrentChange(e) {
|
||||
tableData.page = e;
|
||||
getTableData();
|
||||
}
|
||||
|
||||
// 查询状态
|
||||
async function checkStatusHandle(row) {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const businessLicenceInfo = JSON.parse(row.businessLicenceInfo)
|
||||
await queryEntry({
|
||||
shopId: row.shopId,
|
||||
licenceNo: businessLicenceInfo.licenceNo
|
||||
})
|
||||
getTableData()
|
||||
} catch (error) {
|
||||
tableData.loading = false
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取表格数据
|
||||
async function getTableData() {
|
||||
try {
|
||||
tableData.loading = true
|
||||
const res = await entryManagerList({
|
||||
page: tableData.page,
|
||||
size: tableData.size,
|
||||
...queryForm.value
|
||||
})
|
||||
tableData.list = res.records
|
||||
tableData.total = res.totalRow
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
setTimeout(() => {
|
||||
tableData.loading = false;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// 跳转编辑页面
|
||||
function toDetail(row, type) {
|
||||
const businessLicenceInfo = JSON.parse(row.businessLicenceInfo)
|
||||
router.push({
|
||||
name: 'applyment_in',
|
||||
query: {
|
||||
shopId: row.shopId,
|
||||
licenceNo: businessLicenceInfo.licenceNo,
|
||||
type: type
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyq_container {
|
||||
padding: 14px;
|
||||
|
||||
.gyq_content {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.error_text {
|
||||
font-size: 14px;
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
</style>
|
||||
71
src/views/applyments/select_shop.vue
Normal file
71
src/views/applyments/select_shop.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<!-- 选择商户以及进件渠道 -->
|
||||
<template>
|
||||
<div class="gyq_container">
|
||||
<div class="gyq_content">
|
||||
<div class="row">
|
||||
<el-form :model="queryForm" inline>
|
||||
<el-form-item label="请选择用户">
|
||||
<el-input placeholder="用户号/名称/手机号" readonly @click="selectShopsDialogRef?.show()"
|
||||
v-model="queryForm.shopName">
|
||||
<template #suffix>
|
||||
<div class="center">
|
||||
<el-icon v-if="queryForm.shopName" @click.stop="queryForm.shopName = ''">
|
||||
<CircleCloseFilled />
|
||||
</el-icon>
|
||||
<el-icon @click="selectShopsDialogRef?.show()" style="cursor: pointer;">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Plus">新增用户</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<selectShopsDialog ref="selectShopsDialogRef" @success="selectShopSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from "vue";
|
||||
import selectShopsDialog from "./components/selectShopsDialog.vue";
|
||||
|
||||
const selectShopsDialogRef = ref<InstanceType<typeof selectShopsDialog> | null>(null);
|
||||
|
||||
const queryForm = ref({
|
||||
shopName: ""
|
||||
});
|
||||
|
||||
// 选择商户成功回调
|
||||
function selectShopSuccess(shop: any) {
|
||||
console.log('选择的商户:', shop);
|
||||
queryForm.value.shopName = shop.shopName;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyq_container {
|
||||
padding: 14px;
|
||||
|
||||
.gyq_content {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -56,7 +56,7 @@
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">¥{{ payCount.totalAmount || 0 }}</div>
|
||||
<div class="m">¥{{ multiplyAndFormat(payCount.totalAmount || 0) }}</div>
|
||||
<div class="t">总金额</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +67,7 @@
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">¥{{ payCount.refundAmount || 0 }}</div>
|
||||
<div class="m">¥{{ multiplyAndFormat(payCount.refundAmount || 0) }}</div>
|
||||
<div class="t">退款金额</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,7 +100,7 @@
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">{{ payCount.totalAmount - payCount.refundAmount || 0 }}</div>
|
||||
<div class="m">{{ multiplyAndFormat((payCount.totalAmount - payCount.refundAmount) || 0) }}</div>
|
||||
<div class="t">实际销售额总和</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,7 +111,7 @@
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="m">{{ payCount.saleCount - payCount.refundCount || 0 }}</div>
|
||||
<div class="m">{{ multiplyAndFormat((payCount.saleCount - payCount.refundCount) || 0) }}</div>
|
||||
<div class="t">实际销量总和</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -152,10 +152,10 @@
|
||||
<template v-slot="scope">¥{{ scope.row.refund }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际销量" prop="refundCount">
|
||||
<template v-slot="scope"> {{ scope.row.saleCount - scope.row.refundCount }} </template>
|
||||
<template v-slot="scope"> {{ multiplyAndFormat(scope.row.saleCount - scope.row.refundCount) }} </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际销售额" prop="refundCount">
|
||||
<template v-slot="scope"> ¥{{ scope.row.saleAmount - scope.row.refundAmount }} </template>
|
||||
<template v-slot="scope"> ¥{{ multiplyAndFormat(scope.row.saleAmount - scope.row.refundAmount) }} </template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-table :data="tableData.data" v-loading="tableData.loading" v-if="orderType == 2">
|
||||
@@ -165,17 +165,17 @@
|
||||
<el-table-column label="商品名称" prop="productName"></el-table-column>
|
||||
<el-table-column label="销量" prop="saleCount" sortable></el-table-column>
|
||||
<el-table-column label="销售金额" prop="saleAmount" sortable>
|
||||
<template v-slot="scope">¥{{ scope.row.saleAmount }}</template>
|
||||
<template v-slot="scope">¥{{ multiplyAndFormat(scope.row.saleAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="退单量" prop="refundCount" sortable></el-table-column>
|
||||
<el-table-column label="退款金额" prop="refundAmount" sortable>
|
||||
<template v-slot="scope">¥{{ scope.row.refundAmount }}</template>
|
||||
<template v-slot="scope">¥{{ multiplyAndFormat(scope.row.refundAmount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际销量" prop="refundCount" sortable>
|
||||
<template v-slot="scope"> {{ scope.row.saleCount - scope.row.refundCount }} </template>
|
||||
<template v-slot="scope"> {{ multiplyAndFormat(scope.row.saleCount - scope.row.refundCount) }} </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实际销售额" prop="refundCount" sortable>
|
||||
<template v-slot="scope"> ¥{{ scope.row.saleAmount - scope.row.refundAmount }} </template>
|
||||
<template v-slot="scope"> ¥{{ multiplyAndFormat(scope.row.saleAmount - scope.row.refundAmount) }} </template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
@@ -193,12 +193,13 @@ import saleSummaryApi from "@/api/order/sale-summary";
|
||||
import categoryApi from "@/api/product/productclassification";
|
||||
import ShopApi from "@/api/account/shop";
|
||||
import dayjs from "dayjs";
|
||||
import { downloadFile } from "@/utils/index";
|
||||
import { downloadFile, multiplyAndFormat } from "@/utils/index";
|
||||
import { formatDateRange } from './utils/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
multiplyAndFormat,
|
||||
timeValue: "today",
|
||||
resetQuery: null,
|
||||
orderType: "2",
|
||||
@@ -314,7 +315,8 @@ export default {
|
||||
endDate: this.query.createdAt[1],
|
||||
categoryId: this.query.prodCategoryId,
|
||||
productName: this.query.productName,
|
||||
shopId: this.shopId
|
||||
shopId: this.shopId,
|
||||
rangeType: this.timeValue,
|
||||
});
|
||||
downloadFile(file, "数据", "xlsx");
|
||||
} catch (error) {
|
||||
|
||||
@@ -187,7 +187,8 @@ export default {
|
||||
const file = await tableSummaryApi.export({
|
||||
beginDate: this.query.createdAt[0],
|
||||
endDate: this.query.createdAt[1],
|
||||
shopId: this.shopId
|
||||
shopId: this.shopId,
|
||||
rangeType: this.timeValue,
|
||||
});
|
||||
downloadFile(file, "数据", "xlsx");
|
||||
this.downloadLoading = false;
|
||||
|
||||
@@ -12,7 +12,15 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="耗材价格" prop="price">
|
||||
<el-input-number v-model="form.price" placeholder="请输入耗材价格"></el-input-number>
|
||||
<div class="center">
|
||||
<el-input-number v-model="form.price" placeholder="请输入" @change="onPriceChange"></el-input-number>
|
||||
<span>{{ form.conUnit }}</span>
|
||||
<div class="ipt">
|
||||
第二单位价格:
|
||||
<el-input-number v-model="twoPrice" placeholder="请输入" @change="onTwoPriceChange"></el-input-number>
|
||||
<span>{{ form.conUnitTwo }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="库存">
|
||||
<el-input-number v-model="form.stockNumber" placeholder="请输入库存值"></el-input-number>
|
||||
@@ -23,7 +31,7 @@
|
||||
<el-form-item label="单位" prop="conUnit">
|
||||
<el-input v-model="form.conUnit" placeholder="请输入单位"></el-input>
|
||||
</el-form-item>
|
||||
<el-alert class="u-m-t-10 u-m-b-10" title="提示" description="换算值为第二单位*第二单位转换数量=第一单位" type="warning" show-icon
|
||||
<el-alert class="u-m-t-10 u-m-b-10" title="提示" description="换算值为第一单位*第二单位转换数量=第二单位" type="warning" show-icon
|
||||
:closable="false"></el-alert>
|
||||
<el-form-item label="预警值">
|
||||
<el-input-number v-model="form.conWarning" placeholder="请输入耗材预警值"></el-input-number>
|
||||
@@ -50,9 +58,11 @@
|
||||
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from "vue";
|
||||
import consApi from "@/api/product/cons";
|
||||
import consGroupApi from "@/api/product/cons-group";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
const consGroups = ref([]);
|
||||
const rules = {
|
||||
conName: [{ required: true, message: "请输入耗材名称", trigger: "blur" }],
|
||||
@@ -94,6 +104,34 @@ const form = reactive({
|
||||
...basicForm,
|
||||
});
|
||||
|
||||
// 第二单位价格为计算字段:第一单位价格 * 第二单位转换数量
|
||||
const twoPrice = computed({
|
||||
get() {
|
||||
const p = Number(form.price || 0);
|
||||
const c = Number(form.conUnitTwoConvert || 0);
|
||||
const val = c ? p * c : 0;
|
||||
return parseFloat(val.toFixed(4));
|
||||
},
|
||||
set(val) {
|
||||
const c = Number(form.conUnitTwoConvert || 0);
|
||||
if (!c || !isFinite(Number(val))) return;
|
||||
// 修改第二单位价格时,反算第一单位价格并保留四位小数
|
||||
form.price = parseFloat((Number(val) / c).toFixed(4));
|
||||
},
|
||||
});
|
||||
|
||||
function onPriceChange(val) {
|
||||
if (!isFinite(Number(val))) return;
|
||||
form.price = parseFloat(Number(val).toFixed(4));
|
||||
}
|
||||
|
||||
function onTwoPriceChange(val) {
|
||||
if (!isFinite(Number(val))) return;
|
||||
const c = Number(form.conUnitTwoConvert || 0);
|
||||
if (!c) return;
|
||||
form.price = parseFloat((Number(val) / c).toFixed(4));
|
||||
}
|
||||
|
||||
const show = ref(false);
|
||||
let dialogtitle = ref("");
|
||||
function open(item) {
|
||||
@@ -171,4 +209,18 @@ defineExpose({
|
||||
open,
|
||||
close,
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.ipt {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin-left: 28px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -280,9 +280,9 @@ export default {
|
||||
return price;
|
||||
}
|
||||
if (row.conUnitTwo && row.unit == row.conUnitTwo) {
|
||||
console.log(price / row.conUnitTwoConvert);
|
||||
console.log(new Decimal(price).div(new Decimal(row.conUnitTwoConvert)));
|
||||
return new Decimal(price).div(new Decimal(row.conUnitTwoConvert));
|
||||
// console.log(price / row.conUnitTwoConvert);
|
||||
// console.log(new Decimal(price).div(new Decimal(row.conUnitTwoConvert)));
|
||||
return new Decimal(price).mul(new Decimal(row.conUnitTwoConvert));
|
||||
}
|
||||
return price;
|
||||
},
|
||||
@@ -294,7 +294,7 @@ export default {
|
||||
return number;
|
||||
}
|
||||
if (row.conUnitTwo && row.unit == row.conUnitTwo) {
|
||||
return number * row.conUnitTwoConvert;
|
||||
return number / row.conUnitTwoConvert;
|
||||
}
|
||||
return number;
|
||||
},
|
||||
|
||||
@@ -14,7 +14,9 @@ const contentConfig: IContentConfig = {
|
||||
pageSizes: [10, 20, 30, 50],
|
||||
},
|
||||
indexAction: function (params) {
|
||||
return Api.getList({});
|
||||
return Api.getList({
|
||||
...params,
|
||||
});
|
||||
},
|
||||
deleteAction: function (id) {
|
||||
return Api.delete(id);
|
||||
@@ -79,7 +81,7 @@ const contentConfig: IContentConfig = {
|
||||
fixed: "right",
|
||||
width: 280,
|
||||
templet: "tool",
|
||||
operat: [{ text: "编辑", icon: 'edit', name: "edit"}, { text: "删除", icon: 'delete', type: 'danger', name: "delete"}],
|
||||
operat: [{ text: "编辑", icon: 'edit', name: "edit" }, { text: "删除", icon: 'delete', type: 'danger', name: "delete" }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -74,8 +74,7 @@ const accountList = reactive([
|
||||
{ username: "19107220837", type: 'danger', label: '快乐时光店铺' },
|
||||
{ username: "18199991111", type: 'success', label: '草莓加盟主店可直接管理' },
|
||||
{ username: "18821670757", type: 'primary', label: '强盛集团' },
|
||||
{ username: "19107220837", type: 'warning', label: '万维时光' },
|
||||
{ username: "19112345678", type: 'success', label: '酸橘子·云贵小馆' },
|
||||
{ username: "19112345678", type: 'danger', label: '酸橘子·云贵小馆' },
|
||||
]);
|
||||
|
||||
// 快捷模拟登录
|
||||
|
||||
@@ -336,7 +336,8 @@ async function confirmRefundHandle(form) {
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
tableData.loading = false
|
||||
getTableData()
|
||||
wareCountAjax()
|
||||
}
|
||||
|
||||
// 审核退款操作
|
||||
|
||||
@@ -34,6 +34,7 @@ function returnPrice(skuList) {
|
||||
const emits = defineEmits(['success'])
|
||||
function selectItem(item) {
|
||||
emits('success', {
|
||||
id: item.id,
|
||||
coverImg: item.coverImg,
|
||||
name: item.name,
|
||||
price: returnPrice(item.skuList)
|
||||
|
||||
@@ -42,7 +42,7 @@ const form = ref({
|
||||
watch(() => form.value.isEnable, (newValue, OldValue) => {
|
||||
if (loading.value == false) {
|
||||
if (newValue == 0) {
|
||||
ElMessageBox.confirm('关闭商品拼团所有未支付的订单都将自动取消,是否确定关闭?', '注意', {
|
||||
ElMessageBox.confirm('关闭商品拼团所有未成团的订单都将自动取消,是否确定关闭?', '注意', {
|
||||
confirmButtonText: '确认关闭',
|
||||
type: 'danger'
|
||||
}).then(() => {
|
||||
|
||||
@@ -56,8 +56,13 @@
|
||||
<el-table-column label="操作" width="150">
|
||||
<template v-slot="scope">
|
||||
<template v-if="scope.row.shopId === shopInfo.id">
|
||||
<el-button link type="primary" @click="addGroupGoodsRef.show(scope.row)">编辑</el-button>
|
||||
<el-button type="danger" link @click="delHandle(scope.row)">删除</el-button>
|
||||
<template v-if="scope.row.onlineStatus">
|
||||
<el-button link type="primary" disabled>(下架后编辑/删除)</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" @click="addGroupGoodsRef.show(scope.row)">编辑</el-button>
|
||||
<el-button link type="danger" @click="delHandle(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button link type="primary" disabled>无权操作</el-button>
|
||||
|
||||
@@ -233,7 +233,7 @@ import shopExtendApi from "@/api/account/shopExtend";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableActive: "",
|
||||
tableActive: "ticket_logo",
|
||||
tableData: [],
|
||||
selectItem: {},
|
||||
imageUrl: "",
|
||||
@@ -248,7 +248,10 @@ export default {
|
||||
methods: {
|
||||
// 刷新列表数据
|
||||
async doSubmit() {
|
||||
this.selectItem.value = JSON.stringify(this.imgList)
|
||||
// console.log('this.selectItem.value', this.selectItem.value);
|
||||
// return
|
||||
|
||||
// this.selectItem.value = JSON.stringify(this.imgList)
|
||||
await shopExtendApi.edit({
|
||||
...this.selectItem,
|
||||
autokey: this.selectItem.autoKey,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="query.payType" placeholder="支付类型">
|
||||
<el-option label="微信支付" value="wechatPay" />
|
||||
<el-option label="支付宝支付" value="aliPay" />
|
||||
<el-option label="微信支付" value="WECHAT" />
|
||||
<el-option label="支付宝支付" value="ALIPAY" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -135,11 +135,11 @@ export default {
|
||||
},
|
||||
payTypes: [
|
||||
{
|
||||
value: "wechatPay",
|
||||
value: "WECHAT",
|
||||
label: "微信支付"
|
||||
},
|
||||
{
|
||||
value: "aliPay",
|
||||
value: "ALIPAY",
|
||||
label: "支付宝支付"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="item">
|
||||
<div class="t">订单类型</div>
|
||||
<div class="b">
|
||||
{{ sendTypeFilter(detail.sendType) }}
|
||||
{{ sendTypeFilter(detail.dineMode) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,12 +46,12 @@
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="t">下单时间</div>
|
||||
<div class="b">{{ timeFilter(detail.createdAt) }}</div>
|
||||
<div class="b">{{ timeFilter(detail.createTime) }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="t">支付时间</div>
|
||||
<div class="b">
|
||||
{{ timeFilter(detail.createdAt) }}
|
||||
{{ timeFilter(detail.paidTime) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,15 +51,15 @@ export default {
|
||||
label: "快递",
|
||||
},
|
||||
{
|
||||
key: "takeaway",
|
||||
key: "take-away",
|
||||
label: "外卖",
|
||||
},
|
||||
{
|
||||
key: "takeself",
|
||||
key: "take-out",
|
||||
label: "自提",
|
||||
},
|
||||
{
|
||||
key: "table",
|
||||
key: "dine-in",
|
||||
label: "堂食",
|
||||
},
|
||||
],
|
||||
|
||||
@@ -14,14 +14,22 @@ const contentConfig: IContentConfig = {
|
||||
pageSize: 10,
|
||||
pageSizes: [10, 20, 30, 50],
|
||||
},
|
||||
indexAction: function (params) {
|
||||
async indexAction(params) {
|
||||
console.log(params);
|
||||
if (params.createAt) {
|
||||
params.startTime = params.createAt[0];
|
||||
params.endTime = params.createAt[1];
|
||||
delete params.createAt;
|
||||
}
|
||||
return OrderApi.getList(params);
|
||||
|
||||
const res = await OrderApi.getList(params)
|
||||
console.log('OrderApi.getList', res);
|
||||
|
||||
res.records.map(item => {
|
||||
item.payLoading = false
|
||||
item.printStatus = JSON.parse(item.printStatus || '[]')
|
||||
})
|
||||
return res;
|
||||
},
|
||||
indexActionData: {},
|
||||
// deleteAction: OrderApi.delete,
|
||||
@@ -93,7 +101,14 @@ const contentConfig: IContentConfig = {
|
||||
templet: "custom",
|
||||
slotName: "options",
|
||||
},
|
||||
|
||||
{
|
||||
label: "打印状态",
|
||||
align: "center",
|
||||
prop: "printStatus",
|
||||
width: 120,
|
||||
templet: "custom",
|
||||
slotName: "printStatus",
|
||||
},
|
||||
{
|
||||
label: "状态",
|
||||
align: "center",
|
||||
@@ -116,7 +131,7 @@ const contentConfig: IContentConfig = {
|
||||
label: "操作",
|
||||
align: "center",
|
||||
fixed: "right",
|
||||
width: 150,
|
||||
width: 180,
|
||||
templet: "custom",
|
||||
slotName: "operate",
|
||||
},
|
||||
|
||||
@@ -51,6 +51,13 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 打印状态 -->
|
||||
<template #printStatus="scope">
|
||||
<span v-if="scope.row.printStatus.length > 0" style="color: var(--el-color-danger)">
|
||||
打印失败({{scope.row.printStatus.map(item => item.name).join('、')}})
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #options="scope">
|
||||
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
|
||||
</template>
|
||||
@@ -65,6 +72,7 @@
|
||||
</template>
|
||||
<template #operate="scope">
|
||||
<div>
|
||||
<el-button link @click="printOrderHandle(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 == 'unpaid'" type="primary" @click="toPayOrder(scope.row)">
|
||||
@@ -148,6 +156,19 @@ onMounted(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// 打印订单
|
||||
async function printOrderHandle(order: getListResponse) {
|
||||
try {
|
||||
await orderApi.printOrder({
|
||||
id: order.id,
|
||||
type: 0
|
||||
});
|
||||
ElMessage.success("打印成功");
|
||||
} catch (error) {
|
||||
ElMessage.error("打印失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
|
||||
// 新增
|
||||
async function handleAddClick() {
|
||||
addModalRef.value?.setModalVisible();
|
||||
|
||||
@@ -2,26 +2,14 @@
|
||||
<div class="app-container">
|
||||
<!-- 列表 -->
|
||||
<!-- 搜索 -->
|
||||
<page-search
|
||||
ref="searchRef"
|
||||
:search-config="searchConfig"
|
||||
@query-click="newHandleQueryClick"
|
||||
@reset-click="handleResetClick2"
|
||||
/>
|
||||
<page-search ref="searchRef" :search-config="searchConfig" @query-click="newHandleQueryClick"
|
||||
@reset-click="handleResetClick2" />
|
||||
<!-- 顶部数据 -->
|
||||
<Statistics :data="gongjiData"></Statistics>
|
||||
<!-- 列表 -->
|
||||
<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"
|
||||
>
|
||||
<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 ? "启用" : "禁用" }}
|
||||
@@ -34,20 +22,11 @@
|
||||
<DictLabel v-model="scope.row[scope.prop]" code="gender" />
|
||||
</template>
|
||||
<template #shangjia="scope">
|
||||
<el-switch
|
||||
v-model="scope.row[scope.prop]"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@click="handleSwitchChange(scope.row)"
|
||||
></el-switch>
|
||||
<el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||
@click="handleSwitchChange(scope.row)"></el-switch>
|
||||
</template>
|
||||
<template #isStock="scope">
|
||||
<el-switch
|
||||
disabled
|
||||
v-model="scope.row[scope.prop]"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
<el-switch disabled v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</template>
|
||||
|
||||
<template #kucunedit="scope">
|
||||
@@ -60,29 +39,16 @@
|
||||
</template>
|
||||
|
||||
<template #tuikuantuihui="scope">
|
||||
<el-switch
|
||||
v-if="!scope.row.productId"
|
||||
v-model="scope.row[scope.prop]"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@click="handleSwitchhaocai(scope.row)"
|
||||
></el-switch>
|
||||
<el-switch v-if="!scope.row.productId" v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||
@click="handleSwitchhaocai(scope.row)"></el-switch>
|
||||
</template>
|
||||
<template #sellOut="scope">
|
||||
<el-switch
|
||||
v-model="scope.row[scope.prop]"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
@click="handleSwitchChangeTwo(scope.row)"
|
||||
></el-switch>
|
||||
<el-switch v-model="scope.row[scope.prop]" :active-value="1" :inactive-value="0"
|
||||
@click="handleSwitchChangeTwo(scope.row)"></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"
|
||||
/>
|
||||
<copy-button v-if="scope.row[scope.prop]" :text="scope.row[scope.prop]" style="margin-left: 2px" />
|
||||
</template>
|
||||
<template #consumables="scope">
|
||||
<template v-if="scope.row.type != null">
|
||||
@@ -105,11 +71,7 @@
|
||||
</page-modal>
|
||||
|
||||
<!-- 编辑 -->
|
||||
<page-modal
|
||||
ref="editModalRef"
|
||||
:modal-config="editModalConfig"
|
||||
@submit-click="handleSubmitClick"
|
||||
>
|
||||
<page-modal ref="editModalRef" :modal-config="editModalConfig" @submit-click="handleSubmitClick">
|
||||
<template #gender="scope">
|
||||
<Dict v-model="scope.formData[scope.prop]" code="gender" v-bind="scope.attrs" />
|
||||
</template>
|
||||
@@ -156,32 +118,24 @@
|
||||
<el-table-column label="序号" type="index" width="60"></el-table-column>
|
||||
<el-table-column label="耗材名称" prop="consInfoId">
|
||||
<template v-slot="scope">
|
||||
<el-select
|
||||
v-model="scope.row.consInfoId"
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
@change="selectionChange($event, scope.row)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.id"
|
||||
:label="item.conName"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
<el-select v-model="scope.row.consInfoId" reserve-keyword placeholder="请输入关键词"
|
||||
@change="selectionChange($event, scope.row)">
|
||||
<el-option v-for="item in options" :key="item.id" :label="item.conName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
<!-- <div class="tips" v-if="scope.row.stockNumber">库存:{{ scope.row.stockNumber }}</div> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" prop="conUnit">
|
||||
<template v-slot="scope">
|
||||
<el-select v-model="scope.row.conUnit" reserve-keyword placeholder="请输入关键词">
|
||||
<el-input v-model="scope.row.conUnit" readonly disabled placeholder="请选择耗材"></el-input>
|
||||
<!-- <el-select v-model="scope.row.conUnit" reserve-keyword placeholder="请输入关键词">
|
||||
<el-option
|
||||
v-for="item in returnConUnits(scope.row.consInfoId)"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-select> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用数量" prop="surplusStock" min-width="150px">
|
||||
@@ -192,20 +146,13 @@
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="scope">
|
||||
<div class="table_btn_wrap">
|
||||
<div
|
||||
class="btn sub"
|
||||
v-if="haocaiData.consList.length > 1"
|
||||
@click="haocaiData.consList.splice(scope.$index, 1)"
|
||||
>
|
||||
<div class="btn sub" v-if="haocaiData.consList.length > 1"
|
||||
@click="haocaiData.consList.splice(scope.$index, 1)">
|
||||
<el-icon>
|
||||
<RemoveFilled />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div
|
||||
class="btn add"
|
||||
v-if="scope.$index == haocaiData.consList.length - 1"
|
||||
@click="createItem(scope.row)"
|
||||
>
|
||||
<div class="btn add" v-if="scope.$index == haocaiData.consList.length - 1" @click="createItem(scope.row)">
|
||||
<el-icon>
|
||||
<CirclePlusFilled />
|
||||
</el-icon>
|
||||
|
||||
@@ -222,7 +222,6 @@
|
||||
<el-form-item label="库存数量">
|
||||
<el-input-number v-model="ruleForm.stockNumber" :min="0" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="打包费" prop="delivery">
|
||||
<div style="display: block;">
|
||||
<el-input-number v-model="ruleForm.packFee" controls-position="right"
|
||||
@@ -230,6 +229,42 @@
|
||||
<div style="color: #999;">单份商品打包费。注:店铺开启外卖模式下该数据才生效</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联推荐商品">
|
||||
<div class="column">
|
||||
<div class="row">
|
||||
<div class="center">
|
||||
<el-button type="primary" @click="selecProductDialogRef?.show()"
|
||||
:disabled="ruleForm.relatedRecommendJson.length >= goodsListMax">添加商品</el-button>
|
||||
<div class="tips">设置商品后,用户可以在商品详情页中看到推荐商品可拖动调整顺序,最多设置{{ goodsListMax }}个商品</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div id="goods_table_drag">
|
||||
<el-table :data="ruleForm.relatedRecommendJson" border stripe style="width: 500px;" row-key="id">
|
||||
<!-- 拖拽列 -->
|
||||
<el-table-column label="排序" width="60">
|
||||
<template v-slot="scope">
|
||||
<div class="drag-handle">☰</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品图片" prop="coverImg" width="90">
|
||||
<template v-slot="scope">
|
||||
<el-image :src="scope.row.coverImg" style="width: 50px;height: 50px;border-radius: 4px;"
|
||||
fit="cover"></el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="name"></el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="scope">
|
||||
<el-button link type="danger"
|
||||
@click="ruleForm.relatedRecommendJson.splice(scope.$index, 1)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
|
||||
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
|
||||
@@ -256,11 +291,13 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 选择商品弹窗 -->
|
||||
<selecProductDialog ref="selecProductDialogRef" @success="selecProductSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from "vue";
|
||||
import { reactive, ref, onMounted, nextTick } from "vue";
|
||||
import type { FormInstance, FormRules } from "element-plus";
|
||||
// 规格属性
|
||||
import SpecificationAttribute from "./SpecificationAttribute.vue";
|
||||
@@ -272,7 +309,69 @@ import UserAPI4 from "@/api/product/specificationsconfig";
|
||||
import shopList from "@/components/mycomponents/shopList.vue";
|
||||
import AddImg from "@/components/mycomponents/addImg.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import Sortable from "sortablejs";
|
||||
import { useTagsViewStore } from "@/store";
|
||||
import selecProductDialog from "@/views/marketing_center/group_booking/components/selecProductDialog.vue";
|
||||
|
||||
const selecProductDialogRef = ref(null)
|
||||
const goodsListMax = ref(9)
|
||||
|
||||
onMounted(() => {
|
||||
// Sortable 需要在 el-table 渲染 tbody 后初始化,尝试多次以确保 DOM 可用
|
||||
const initSortable = async () => {
|
||||
await nextTick();
|
||||
let attempts = 0;
|
||||
const maxAttempts = 8;
|
||||
const tryInit = () => {
|
||||
const el = document.querySelector("#goods_table_drag .el-table__body-wrapper tbody");
|
||||
if (!el) {
|
||||
attempts++;
|
||||
if (attempts < maxAttempts) {
|
||||
setTimeout(tryInit, 80);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 已找到表体,初始化 Sortable
|
||||
new Sortable(el as HTMLElement, {
|
||||
animation: 150,
|
||||
handle: ".drag-handle",
|
||||
ghostClass: "sortable-ghost",
|
||||
chosenClass: "sortable-chosen",
|
||||
onEnd: (e) => {
|
||||
if (e.oldIndex == null || e.newIndex == null) return;
|
||||
if (e.oldIndex === e.newIndex) return;
|
||||
const from = e.oldIndex;
|
||||
const to = e.newIndex;
|
||||
const item = ruleForm.relatedRecommendJson.splice(from, 1)[0];
|
||||
ruleForm.relatedRecommendJson.splice(to, 0, item);
|
||||
// 触发响应式更新
|
||||
ruleForm.relatedRecommendJson = ruleForm.relatedRecommendJson.slice();
|
||||
console.log("排序后的数据", ruleForm.relatedRecommendJson);
|
||||
},
|
||||
});
|
||||
};
|
||||
tryInit();
|
||||
};
|
||||
|
||||
initSortable();
|
||||
});
|
||||
|
||||
// 已选择的商品
|
||||
function selecProductSuccess(res: any) {
|
||||
if (res.id == ruleForm.id) {
|
||||
ElMessage.error("不能选择当前商品");
|
||||
return;
|
||||
}
|
||||
|
||||
let obj = ruleForm.relatedRecommendJson.find((item) => item.id == res.id);
|
||||
if (obj && obj.id) {
|
||||
ElMessage.error("该商品已选择");
|
||||
return;
|
||||
}
|
||||
ruleForm.relatedRecommendJson.push({ ...res });
|
||||
}
|
||||
|
||||
const tagsViewStore = useTagsViewStore();
|
||||
const router = useRouter();
|
||||
let list = ref<any[]>([
|
||||
@@ -338,6 +437,7 @@ interface datasForm {
|
||||
addGroupIndex: any;
|
||||
}
|
||||
interface RuleForm {
|
||||
id: number | string;
|
||||
name: string;
|
||||
shortTitle: string;
|
||||
unitId: string;
|
||||
@@ -362,9 +462,11 @@ interface RuleForm {
|
||||
sort: Number;
|
||||
proGroupVo: any[];
|
||||
selectSpecInfo: any;
|
||||
relatedRecommendJson: any[];
|
||||
}
|
||||
const ruleFormRef = ref<FormInstance>();
|
||||
const ruleForm = reactive<RuleForm>({
|
||||
id: '',
|
||||
//商品名称
|
||||
name: "",
|
||||
//商品介绍
|
||||
@@ -418,6 +520,7 @@ const ruleForm = reactive<RuleForm>({
|
||||
// 排序值
|
||||
sort: 1,
|
||||
selectSpecInfo: {},
|
||||
relatedRecommendJson: [] // 关联推荐商品
|
||||
});
|
||||
const rules = reactive<FormRules<RuleForm>>({
|
||||
name: [{ required: true, message: "请输入商品名称", trigger: "blur" }],
|
||||
@@ -915,6 +1018,27 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.drag-handle {
|
||||
cursor: move;
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* SortableJS classes */
|
||||
.sortable-ghost {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.sortable-chosen {
|
||||
background: #f5f7ff !important;
|
||||
}
|
||||
|
||||
.el-table__body-wrapper tbody tr {
|
||||
transition: transform 150ms ease, background-color 150ms ease;
|
||||
}
|
||||
|
||||
.showStyle:hover>.buttonstyle {
|
||||
display: block;
|
||||
}
|
||||
@@ -942,4 +1066,26 @@ const resetForm = (formEl: FormInstance | undefined) => {
|
||||
top: -10px;
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
|
||||
.column {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.row {
|
||||
flex: 1;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
5
src/views/shop/commonlyUsedMenu/index.vue
Normal file
5
src/views/shop/commonlyUsedMenu/index.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<FastMenuConfig></FastMenuConfig>
|
||||
</div>
|
||||
</template>
|
||||
113
src/views/shop/config/components/contactSetting.vue
Normal file
113
src/views/shop/config/components/contactSetting.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<!-- 客服设置 -->
|
||||
<template>
|
||||
<div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="100" label-position="right">
|
||||
<el-form-item label="企业ID" prop="weworkId">
|
||||
<el-input v-model="form.weworkId" placeholder="请输入企业ID" style="width: 400px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="接入链接" prop="weworkUrl">
|
||||
<el-input v-model="form.weworkUrl" placeholder="请输入接入链接" style="width: 400px;"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div class="detail">
|
||||
<h3>如何获取企业</h3>
|
||||
<p>1.登录【企业微信管理后台】(<el-link type="primary" target="_blank"
|
||||
href="https://work.weixin.qq.com">work.weixin.qq.com</el-link>)</p>
|
||||
<p>2.获取企业ID:登录后,进入【我的企业>>企业信息>>企业ID】</p>
|
||||
<el-image :src="imgs[0]" style="width: 600px;height: auto;" :preview-src-list="imgs"
|
||||
:initial-index="0"></el-image>
|
||||
<h3>如何获取接入链接</h3>
|
||||
<p>1. 登录【企业微信管理后台】(<el-link type="primary" target="_blank"
|
||||
href="https://work.weixin.qq.com">work.weixin.qq.com</el-link>)。
|
||||
</p>
|
||||
<p>2.找到《微信客服》应用,路径:【应用管理>> 应用管理>>应用>>微信客服】</p>
|
||||
<el-image :src="imgs[1]" style="width: 600px;height: auto;" :preview-src-list="imgs"
|
||||
:initial-index="1"></el-image>
|
||||
<p>3.进入《微信客服》,找到《创建账号》按钮,点击后进入页面完成创建。(具体的接待时间、接待人员等商家可自行配置)</p>
|
||||
<el-image :src="imgs[2]" style="width: 600px;height: auto;" :preview-src-list="imgs"
|
||||
:initial-index="2"></el-image>
|
||||
<p>4.创建成功后,再次点击刚刚创建的账号,进入后复制《接入链接》粘贴过来即可;特别说明,账号可选用已创建的账号;</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="loading" @click="submitHandle">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import ShopApi from "@/api/account/shop";
|
||||
|
||||
const imgs = [
|
||||
"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/06f236d656be479284833a166a5b98c1.png",
|
||||
"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/96f3c5c4c1f940c390eef901bcd11a14.png",
|
||||
"https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/1/5dbbd3a7d31c4bef8af57c6679421dd5.png",
|
||||
];
|
||||
|
||||
const formRef = ref();
|
||||
const loading = ref(false);
|
||||
const form = ref({
|
||||
id: '',
|
||||
weworkId: "",
|
||||
weworkUrl: "",
|
||||
});
|
||||
|
||||
const rules = {
|
||||
weworkId: [{ required: true, message: "请输入企业ID", trigger: "blur" }],
|
||||
weworkUrl: [{ required: true, message: "请输入接入链接", trigger: "blur" }],
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
function submitHandle() {
|
||||
formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
loading.value = true;
|
||||
await ShopApi.edit(form.value);
|
||||
ElNotification({
|
||||
title: "成功",
|
||||
message: "保存成功",
|
||||
type: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
loading.value = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 获取店铺信息
|
||||
async function getShopInfo() {
|
||||
try {
|
||||
const res = await ShopApi.get()
|
||||
form.value.id = res.id;
|
||||
form.value.weworkId = res.weworkId;
|
||||
form.value.weworkUrl = res.weworkUrl;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getShopInfo();
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail {
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 600px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,25 +3,14 @@
|
||||
<div>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="160px" label-position="left">
|
||||
<el-form-item label="门店名称" prop="shopName">
|
||||
<el-input
|
||||
v-model.trim="form.shopName"
|
||||
placeholder="请输入门店名称"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input v-model.trim="form.shopName" placeholder="请输入门店名称" style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="连锁店扩展店名">
|
||||
<el-input
|
||||
v-model.trim="form.chainName"
|
||||
placeholder="请输入连锁店扩展店名"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input v-model.trim="form.chainName" placeholder="请输入连锁店扩展店名" style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店logo">
|
||||
<div class="img_box">
|
||||
<single-image-upload
|
||||
style="width: 80px; height: 80px"
|
||||
v-model="form.logo"
|
||||
></single-image-upload>
|
||||
<single-image-upload style="width: 80px; height: 80px" v-model="form.logo"></single-image-upload>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="门店照片">
|
||||
@@ -38,22 +27,14 @@
|
||||
<el-form-item label="门店收款码">
|
||||
<div class="img_box">
|
||||
<canvas ref="canvas" id="QRCode_header" style="width: 80px; height: 80px"></canvas>
|
||||
<el-button
|
||||
size="small"
|
||||
plain
|
||||
v-if="form.paymentQrcode"
|
||||
@click="downloadCanvas(form.paymentQrcode)"
|
||||
>
|
||||
<el-button size="small" plain v-if="form.paymentQrcode" @click="downloadCanvas(form.paymentQrcode)">
|
||||
下载
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信二维码">
|
||||
<div class="img_box">
|
||||
<single-image-upload
|
||||
style="width: 80px; height: 80px"
|
||||
v-model="form.shopQrcode"
|
||||
></single-image-upload>
|
||||
<single-image-upload style="width: 80px; height: 80px" v-model="form.shopQrcode"></single-image-upload>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="店铺小程序码">
|
||||
@@ -84,11 +65,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="联系电话" prop="phone">
|
||||
<el-input
|
||||
v-model.trim="form.phone"
|
||||
placeholder="请输入联系电话"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input v-model.trim="form.phone" placeholder="请输入联系电话" style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="外卖起送金额">
|
||||
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||
@@ -114,62 +91,30 @@
|
||||
<div style="color: #999">注:准确的定位便于用户导航到店铺</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店详细地址">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model.trim="form.address"
|
||||
placeholder="请输入门店详细地址"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input type="textarea" v-model.trim="form.address" placeholder="请输入门店详细地址" style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="营业时间">
|
||||
<div class="u-flex gap-2" style="width: 50%">
|
||||
<el-select v-model="form.businessStartDay" placeholder="周几开始">
|
||||
<el-option
|
||||
:value="item.label"
|
||||
:label="item.label"
|
||||
v-for="item in weeks"
|
||||
:key="item.value"
|
||||
></el-option>
|
||||
<el-option :value="item.label" :label="item.label" v-for="item in weeks" :key="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-select v-model="form.businessEndDay" placeholder="周几结束">
|
||||
<el-option
|
||||
:value="item.label"
|
||||
:label="item.label"
|
||||
v-for="item in weeks"
|
||||
:key="item.value"
|
||||
></el-option>
|
||||
<el-option :value="item.label" :label="item.label" v-for="item in weeks" :key="item.value"></el-option>
|
||||
</el-select>
|
||||
<el-time-picker
|
||||
placeholder="起始时间"
|
||||
v-model="startTime"
|
||||
:picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
format: 'HH:mm',
|
||||
}"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
></el-time-picker>
|
||||
<el-time-picker
|
||||
placeholder="结束时间"
|
||||
v-model="endTime"
|
||||
:picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
}"
|
||||
format="HH:mm"
|
||||
value-format="HH:mm"
|
||||
></el-time-picker>
|
||||
<el-time-picker placeholder="起始时间" v-model="startTime" :picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
format: 'HH:mm',
|
||||
}" format="HH:mm" value-format="HH:mm"></el-time-picker>
|
||||
<el-time-picker placeholder="结束时间" v-model="endTime" :picker-options="{
|
||||
selectableRange: '00:00:00 - 23:59:59',
|
||||
}" format="HH:mm" value-format="HH:mm"></el-time-picker>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="桌位费/位/元">
|
||||
<el-input-number :disabled="!!form.isTableFee" v-model="form.tableFee" :min="0" />
|
||||
<!-- <el-checkbox v-model="form.isTableFee" :label="1">免餐位费</el-checkbox> -->
|
||||
<el-switch
|
||||
class="u-m-l-10"
|
||||
v-model.trim="form.isTableFee"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
active-text="免餐位费"
|
||||
></el-switch>
|
||||
<el-switch class="u-m-l-10" v-model.trim="form.isTableFee" :active-value="1" :inactive-value="0"
|
||||
active-text="免餐位费"></el-switch>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="是否开启8折活动">
|
||||
<el-switch v-model.trim="form.isOpenYhq" active-value="true" inactive-value="false"></el-switch>
|
||||
@@ -203,41 +148,24 @@
|
||||
</el-time-picker>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="店铺简介">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model.trim="form.detail"
|
||||
placeholder="请输入店铺简介"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input type="textarea" v-model.trim="form.detail" placeholder="请输入店铺简介" style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="台桌预订短信">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model.trim="form.bookingSms"
|
||||
placeholder="请输入台桌预订短信"
|
||||
style="width: 500px"
|
||||
></el-input>
|
||||
<el-input type="textarea" v-model.trim="form.bookingSms" placeholder="请输入台桌预订短信"
|
||||
style="width: 500px"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="电子围栏" prop="isOrderFence">
|
||||
<div class="column">
|
||||
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
||||
<el-switch
|
||||
v-model="form.isOrderFence"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
<el-switch v-model="form.isOrderFence" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips" style="font-size: 14px; color: #999">
|
||||
开启后,用户只能在店铺附近xx公里内点餐
|
||||
</div>
|
||||
</div>
|
||||
<div class="center" v-if="form.isOrderFence == 1">
|
||||
<el-input
|
||||
v-model="form.orderFenceDistance"
|
||||
placeholder="请输入"
|
||||
@input="(e) => (form.orderFenceDistance = filterNumberInput(e))"
|
||||
style="width: 250px"
|
||||
input-style="text-align: center;"
|
||||
>
|
||||
<el-input v-model="form.orderFenceDistance" placeholder="请输入"
|
||||
@input="(e) => (form.orderFenceDistance = filterNumberInput(e))" style="width: 250px"
|
||||
input-style="text-align: center;">
|
||||
<template #prepend>限制:</template>
|
||||
<template #append>公里</template>
|
||||
</el-input>
|
||||
@@ -247,29 +175,24 @@
|
||||
<el-form-item label="上菜时间(分钟)" prop="isServeTimeControl">
|
||||
<div class="column">
|
||||
<div class="center" style="display: flex; align-items: center; gap: 14px">
|
||||
<el-switch
|
||||
v-model="form.isServeTimeControl"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
></el-switch>
|
||||
<el-switch v-model="form.isServeTimeControl" :active-value="1" :inactive-value="0"></el-switch>
|
||||
<div class="tips" style="font-size: 14px; color: #999">
|
||||
起菜到上菜的时间间隔,开启后会有超时提示
|
||||
</div>
|
||||
</div>
|
||||
<div class="center" v-if="form.isServeTimeControl == 1">
|
||||
<el-input
|
||||
v-model="form.serveTime"
|
||||
placeholder="请输入"
|
||||
@input="(e) => (form.serveTime = filterNumberInput(e))"
|
||||
style="width: 250px"
|
||||
input-style="text-align: center;"
|
||||
>
|
||||
<el-input v-model="form.serveTime" placeholder="请输入"
|
||||
@input="(e) => (form.serveTime = filterNumberInput(e))" style="width: 250px"
|
||||
input-style="text-align: center;">
|
||||
<template #prepend>限制:</template>
|
||||
<template #append>分钟</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="数签子功能">
|
||||
<el-switch v-model="form.isCountStick" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :value="1">营业中</el-radio>
|
||||
@@ -285,24 +208,11 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<ChooseAddress ref="refChooseAddress" @choose="chooseAddressConfirm"></ChooseAddress>
|
||||
<el-dialog
|
||||
v-model="showUpload"
|
||||
:close-on-click-modal="false"
|
||||
append-to-body
|
||||
width="500px"
|
||||
@close="showUpload = false"
|
||||
>
|
||||
<el-upload
|
||||
:before-remove="handleBeforeRemove"
|
||||
:on-success="handleSuccess"
|
||||
:on-error="handleError"
|
||||
:file-list="fileList"
|
||||
:headers="headers"
|
||||
:action="qiNiuUploadApi"
|
||||
:limit="1"
|
||||
list-type="picture"
|
||||
class="upload-demo"
|
||||
>
|
||||
<el-dialog v-model="showUpload" :close-on-click-modal="false" append-to-body width="500px"
|
||||
@close="showUpload = false">
|
||||
<el-upload :before-remove="handleBeforeRemove" :on-success="handleSuccess" :on-error="handleError"
|
||||
:file-list="fileList" :headers="headers" :action="qiNiuUploadApi" :limit="1" list-type="picture"
|
||||
class="upload-demo">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div style="display: block" class="el-upload__tip">请勿上传违法文件,且文件不超过15M</div>
|
||||
@@ -549,7 +459,7 @@ export default {
|
||||
handleBeforeRemove(file, fileList) {
|
||||
for (let i = 0; i < this.files.length; i++) {
|
||||
if (this.files[i].uid === file.uid) {
|
||||
crudQiNiu.del([this.files[i].id]).then((res) => {});
|
||||
crudQiNiu.del([this.files[i].id]).then((res) => { });
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
<el-tab-pane label="安全设置" name="4"></el-tab-pane>
|
||||
<el-tab-pane label="跳转小程序" name="6" v-if="shopId == 1"></el-tab-pane>
|
||||
<el-tab-pane label="通知中心" name="7"></el-tab-pane>
|
||||
<el-tab-pane label="客服设置" name="8"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<shopInfo v-if="activeName == 1" />
|
||||
<safe v-if="activeName == 4" />
|
||||
<notifications v-if="activeName == 7" />
|
||||
<!-- <goxcx v-if="activeName == 6" />-->
|
||||
<contactSetting v-if="activeName == 8" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -19,6 +21,7 @@
|
||||
import shopInfo from "./components/shopInfo.vue";
|
||||
import safe from "./components/safe.vue";
|
||||
import notifications from "./components/notifications.vue";
|
||||
import contactSetting from "./components/contactSetting.vue";
|
||||
|
||||
const state = reactive({
|
||||
activeName: "1",
|
||||
|
||||
@@ -245,8 +245,8 @@ const tableData = reactive({
|
||||
// 支付方式类型
|
||||
function payTypeFilter(t) {
|
||||
const m = {
|
||||
wechatPay: '微信支付',
|
||||
aliPay: '支付宝支付'
|
||||
WECHAT: '微信支付',
|
||||
ALIPAY: '支付宝支付'
|
||||
}
|
||||
return m[t]
|
||||
}
|
||||
|
||||
@@ -1,86 +1,181 @@
|
||||
<template>
|
||||
<el-dialog :title="state.form.id ? '编辑店铺' : '添加店铺'" v-model="state.dialogVisible" @close="reset">
|
||||
<div style="height: 50vh; overflow-y: auto">
|
||||
<el-form ref="refForm" :model="state.form" :rules="state.rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="店铺名称" prop="shopName">
|
||||
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺类型">
|
||||
<el-radio-group v-model="state.form.shopType" :disabled="state.isEdit || state.type == 'addBranch'">
|
||||
<el-radio-button value="only">单店</el-radio-button>
|
||||
<el-radio-button value="chain">连锁店</el-radio-button>
|
||||
<el-radio-button value="join">加盟店</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="是否为主店" prop="isHeadShop" v-if="state.form.shopType != 'only'">
|
||||
<el-radio-group v-model="state.form.isHeadShop" @change=" state.form.mainId = ''" :disabled="state.isEdit || state.type == 'addBranch'">
|
||||
<el-radio :value="1">是</el-radio>
|
||||
<el-radio :value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择主店" prop="mainId" v-if="state.form.isHeadShop == '0'&&state.form.shopType != 'only'">
|
||||
<!-- <el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> -->
|
||||
<el-select v-model="state.form.mainId" placeholder="请选择主店铺" filterable reserve-keyword
|
||||
:remote-method="getTableData" :loading="state.shopListLoading" :disabled="state.isEdit || state.type == 'addBranch'">
|
||||
<el-option v-for="item in state.shopList" :label="`${item.shopName}`" :value="item.id"
|
||||
:key="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="连锁店扩展店名">
|
||||
<el-input v-model="state.form.chainName" placeholder="请输入连锁店扩展店名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店logo" prop="logo">
|
||||
<SingleImageUpload v-model="state.form.logo" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店照片">
|
||||
<SingleImageUpload v-model="state.form.frontImg" />
|
||||
</el-form-item>
|
||||
<el-form-item label="经营模式">
|
||||
<el-radio-group v-model="state.form.registerType">
|
||||
<el-radio-button value="before">先付费</el-radio-button>
|
||||
<el-radio-button value="after">后付费</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="管理方式" v-if="state.form.shopType != 'only'">
|
||||
<el-radio-group v-model="state.form.tubeType">
|
||||
<el-radio-button :value="0">不可直接管理</el-radio-button>
|
||||
<el-radio-button :value="1">直接管理</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips"><el-alert title="请谨慎修改" type="warning" size="7" effect="dark" show-icon :closable="false"/></div>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="试用/正式">
|
||||
<el-radio-group v-model="state.form.profiles">
|
||||
<el-radio-button value="probation">试用</el-radio-button>
|
||||
<el-radio-button value="release">正式</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="激活码">
|
||||
<el-input v-model="state.form.activateCode" placeholder="请输入激活码"></el-input>
|
||||
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录账号" prop="accountName">
|
||||
<el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录密码" prop="password" v-if="!state.form.id">
|
||||
<el-input type="password" show-password v-model="state.form.accountPwd" placeholder="请输入登录密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="phone">
|
||||
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备数量">
|
||||
<el-input-number v-model="state.form.supportDeviceNumber" controls-position="right" :min="1" :step="1"
|
||||
step-strictly></el-input-number>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="外卖起送金额">
|
||||
<div>
|
||||
<el-dialog
|
||||
:title="state.form.id ? '编辑店铺' : '添加店铺'"
|
||||
v-model="state.dialogVisible"
|
||||
@close="reset"
|
||||
>
|
||||
<div style="height: 50vh; overflow-y: auto">
|
||||
<el-form
|
||||
ref="refForm"
|
||||
:model="state.form"
|
||||
:rules="state.rules"
|
||||
label-width="120px"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form-item label="店铺名称" prop="shopName">
|
||||
<el-input v-model="state.form.shopName" placeholder="请输入门店名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺类型">
|
||||
<el-radio-group
|
||||
v-model="state.form.shopType"
|
||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
||||
>
|
||||
<el-radio-button value="only">单店</el-radio-button>
|
||||
<el-radio-button value="chain">连锁店</el-radio-button>
|
||||
<el-radio-button value="join">加盟店</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips">
|
||||
<el-alert
|
||||
title="请谨慎修改"
|
||||
type="warning"
|
||||
size="7"
|
||||
effect="dark"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否为主店" prop="isHeadShop" v-if="state.form.shopType != 'only'">
|
||||
<el-radio-group
|
||||
v-model="state.form.isHeadShop"
|
||||
@change="state.form.mainId = ''"
|
||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
||||
>
|
||||
<el-radio :value="1">是</el-radio>
|
||||
<el-radio :value="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="选择主店"
|
||||
prop="mainId"
|
||||
v-if="state.form.isHeadShop == '0' && state.form.shopType != 'only'"
|
||||
>
|
||||
<!-- <el-form-item label="主店账号" prop="mainId" v-if="state.form.shopType != 'only'"> -->
|
||||
<el-select
|
||||
v-model="state.form.mainId"
|
||||
placeholder="请选择主店铺"
|
||||
filterable
|
||||
reserve-keyword
|
||||
:remote-method="getTableData"
|
||||
:loading="state.shopListLoading"
|
||||
:disabled="state.isEdit || state.type == 'addBranch'"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in state.shopList"
|
||||
:label="`${item.shopName}`"
|
||||
:value="item.id"
|
||||
:key="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="连锁店扩展店名">
|
||||
<el-input v-model="state.form.chainName" placeholder="请输入连锁店扩展店名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="门店logo" prop="logo">
|
||||
<SingleImageUpload v-model="state.form.logo" />
|
||||
</el-form-item>
|
||||
<el-form-item label="门店照片">
|
||||
<SingleImageUpload v-model="state.form.frontImg" />
|
||||
</el-form-item>
|
||||
<el-form-item label="经营模式">
|
||||
<el-radio-group v-model="state.form.registerType">
|
||||
<el-radio-button value="before">先付费</el-radio-button>
|
||||
<el-radio-button value="after">后付费</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips">
|
||||
<el-alert
|
||||
title="请谨慎修改"
|
||||
type="warning"
|
||||
size="7"
|
||||
effect="dark"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="管理方式" v-if="state.form.shopType != 'only'">
|
||||
<el-radio-group v-model="state.form.tubeType">
|
||||
<el-radio-button :value="0">不可直接管理</el-radio-button>
|
||||
<el-radio-button :value="1">直接管理</el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="tips">
|
||||
<el-alert
|
||||
title="请谨慎修改"
|
||||
type="warning"
|
||||
size="7"
|
||||
effect="dark"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="试用/正式">
|
||||
<el-radio-group v-model="state.form.profiles">
|
||||
<el-radio-button value="probation">试用</el-radio-button>
|
||||
<el-radio-button value="release">正式</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="激活码">
|
||||
<el-input v-model="state.form.activateCode" placeholder="请输入激活码"></el-input>
|
||||
<div class="tips">注:输入有效激活码表示添加的同时直接激活该店铺。</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录账号" prop="accountName">
|
||||
<el-input v-model="state.form.accountName" placeholder="请输入登录账号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="登录密码" prop="password" v-if="!state.form.id">
|
||||
<el-input
|
||||
type="password"
|
||||
show-password
|
||||
v-model="state.form.accountPwd"
|
||||
placeholder="请输入登录密码"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="联系电话" prop="phone">
|
||||
<el-input v-model="state.form.phone" placeholder="请输入联系电话"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备数量">
|
||||
<el-input-number
|
||||
v-model="state.form.supportDeviceNumber"
|
||||
controls-position="right"
|
||||
:min="1"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="外卖起送金额">
|
||||
<el-input-number v-model="form.takeaway_money" placeholder="0.00" controls-position="right"
|
||||
:min="0"></el-input-number>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="店铺经度" prop="lat">
|
||||
<el-form-item label="店铺地址" prop="districts">
|
||||
<AddressSelect
|
||||
v-model:prov="state.form.provinces"
|
||||
v-model:city="state.form.cities"
|
||||
v-model:area="state.form.districts"
|
||||
></AddressSelect>
|
||||
</el-form-item>
|
||||
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="经度" prop="lng">
|
||||
<el-input v-model="state.form.lng" placeholder="经度"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="纬度" prop="lat" label-width="auto">
|
||||
<el-input v-model="state.form.lat" placeholder="纬度"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button type="primary" plain icon="place" @click="latShow = true">
|
||||
打开地图复制坐标
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- <el-form-item label="店铺经度" prop="lat">
|
||||
<el-row>
|
||||
<el-col :span="9" v-if="state.form.provinces">
|
||||
<el-input :value="`${state.form.provinces}-${state.form.cities}-${state.form.districts}`" disabled />
|
||||
@@ -97,69 +192,105 @@
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺详细地址">
|
||||
<el-input type="textarea" v-model="state.form.address" placeholder="请输入门店详细地址"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺简介">
|
||||
<el-input type="textarea" v-model="state.form.detail" placeholder="请输入店铺简介"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="state.form.status">
|
||||
<el-radio :value="1">开启</el-radio>
|
||||
<el-radio :value="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-dialog title="选择地址" v-model="state.showLocation" :modal="false" :modal-append-to-body="false">
|
||||
<div class="map_box">
|
||||
<div class="map">
|
||||
<el-amap ref="map" :center="state.amapOptions.center" @init="mapInit">
|
||||
<el-amap-marker :position="state.amapOptions.center"></el-amap-marker>
|
||||
</el-amap>
|
||||
</div>
|
||||
<div class="search_box">
|
||||
<el-input v-model="state.searchOption.keyword" placeholder="请输入关键字" @focus="state.searchOption.focus = true"
|
||||
@blur="autoCompleteSearchBlur" @input="autoCompleteSearch(state.searchOption.keyword)">
|
||||
<template #append>
|
||||
<el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)">
|
||||
搜索
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="list" v-if="state.searchOption.focus && state.searchOption.show">
|
||||
<div class="item" @click="autoCompleteListClick(item)" v-for="item in state.autoCompleteList"
|
||||
:key="item.id">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search_wrap">
|
||||
<div class="item" v-for="item in state.locationSearchList" :key="item.id">
|
||||
<div class="left">
|
||||
<div class="name">{{ item.name }}-{{ item.address }}</div>
|
||||
<div class="location">经纬度:{{ item.location.lng }},{{ item.location.lat }}</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="selectLocationHandle(item)">选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="店铺详细地址">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="state.form.address"
|
||||
placeholder="请输入门店详细地址"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺简介">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="state.form.detail"
|
||||
placeholder="请输入店铺简介"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-radio-group v-model="state.form.status">
|
||||
<el-radio :value="1">开启</el-radio>
|
||||
<el-radio :value="0">关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-dialog
|
||||
title="选择地址"
|
||||
v-model="state.showLocation"
|
||||
:modal="false"
|
||||
:modal-append-to-body="false"
|
||||
>
|
||||
<div class="map_box">
|
||||
<div class="map">
|
||||
<el-amap ref="map" :center="state.amapOptions.center" @init="mapInit">
|
||||
<el-amap-marker :position="state.amapOptions.center"></el-amap-marker>
|
||||
</el-amap>
|
||||
</div>
|
||||
<div class="search_box">
|
||||
<el-input
|
||||
v-model="state.searchOption.keyword"
|
||||
placeholder="请输入关键字"
|
||||
@focus="state.searchOption.focus = true"
|
||||
@blur="autoCompleteSearchBlur"
|
||||
@input="autoCompleteSearch(state.searchOption.keyword)"
|
||||
>
|
||||
<template #append>
|
||||
<el-button type="primary" @click="placeSearchSearch(state.searchOption.keyword)">
|
||||
搜索
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
<div class="list" v-if="state.searchOption.focus && state.searchOption.show">
|
||||
<div
|
||||
class="item"
|
||||
@click="autoCompleteListClick(item)"
|
||||
v-for="item in state.autoCompleteList"
|
||||
:key="item.id"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="search_wrap">
|
||||
<div class="item" v-for="item in state.locationSearchList" :key="item.id">
|
||||
<div class="left">
|
||||
<div class="name">{{ item.name }}-{{ item.address }}</div>
|
||||
<div class="location">经纬度:{{ item.location.lng }},{{ item.location.lat }}</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="selectLocationHandle(item)">选择</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="state.formLoading">
|
||||
<span v-if="!state.formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="state.formLoading">
|
||||
<span v-if="!state.formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog title="坐标搜索" v-model="latShow" width="60vw">
|
||||
<iframe
|
||||
style="width: 100%; height: 60vh"
|
||||
src="https://lbs.baidu.com/maptool/getpoint"
|
||||
frameborder="0"
|
||||
></iframe>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="latShow = false">取消</el-button>
|
||||
<el-button type="primary" @click="latConfirm">确认</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -170,6 +301,8 @@ import { initMapLoad } from "@/utils/mapLoadUtil";
|
||||
import { ElNotification } from "element-plus";
|
||||
// { geocode, ShopApi.getList }
|
||||
import ShopApi from "@/api/account/shop";
|
||||
|
||||
const latShow = ref(false);
|
||||
const validateLogo = (rule, value, callback) => {
|
||||
if (!state.form.logo) {
|
||||
callback(new Error("请上传门店logo"));
|
||||
@@ -177,6 +310,28 @@ const validateLogo = (rule, value, callback) => {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
async function latConfirm() {
|
||||
//js获取当前剪贴板内容
|
||||
try {
|
||||
// 核心:异步读取剪贴板文本内容
|
||||
const clipboardText = await navigator.clipboard.readText();
|
||||
|
||||
// 显示获取到的内容
|
||||
console.log("剪贴板内容:", clipboardText);
|
||||
if (clipboardText && clipboardText.indexOf(",") > 0) {
|
||||
const latLng = clipboardText.split(",");
|
||||
state.form.lat = latLng[1];
|
||||
state.form.lng = latLng[0];
|
||||
latShow.value = false;
|
||||
} else [ElMessage.error("请搜索地址后复制经纬度")];
|
||||
} catch (err) {
|
||||
// 捕获异常(用户拒绝权限、浏览器不支持、非交互上下文等)
|
||||
console.error("获取剪贴板失败:", err);
|
||||
}
|
||||
}
|
||||
function openMap() {
|
||||
window.open("https://lbs.baidu.com/maptool/getpoint");
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
uploadImg: uploadImg,
|
||||
@@ -213,7 +368,7 @@ const state = reactive({
|
||||
chainName: "",
|
||||
isHeadShop: 0,
|
||||
},
|
||||
type: '',
|
||||
type: "",
|
||||
resetForm: "",
|
||||
rules: {
|
||||
activateCode: [
|
||||
@@ -244,6 +399,20 @@ const state = reactive({
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
districts: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择店铺地址",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
lng: [
|
||||
{
|
||||
required: true,
|
||||
message: "请选择坐标",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
lat: [
|
||||
{
|
||||
required: true,
|
||||
@@ -311,7 +480,7 @@ onMounted(() => {
|
||||
|
||||
// 获取商家列表
|
||||
async function getTableData(query = "") {
|
||||
console.log(123)
|
||||
console.log(123);
|
||||
state.shopListLoading = true;
|
||||
try {
|
||||
const res = await ShopApi.getList({
|
||||
@@ -360,7 +529,7 @@ function submitHandle() {
|
||||
type: "success",
|
||||
});
|
||||
close();
|
||||
location.reload()
|
||||
location.reload();
|
||||
} catch (error) {
|
||||
state.formLoading = false;
|
||||
console.log(error);
|
||||
@@ -376,7 +545,7 @@ function handleSuccess(response, file, fileList) {
|
||||
state.files = response.data;
|
||||
}
|
||||
|
||||
function show(obj,type) {
|
||||
function show(obj, type) {
|
||||
getTableData();
|
||||
state.dialogVisible = true;
|
||||
if (obj && obj.id) {
|
||||
@@ -386,13 +555,13 @@ function show(obj,type) {
|
||||
if (obj && obj.mainId) {
|
||||
Object.assign(state.form, obj);
|
||||
}
|
||||
if( type ){
|
||||
state.type = type
|
||||
if (type) {
|
||||
state.type = type;
|
||||
}
|
||||
console.log(state.form);
|
||||
console.log(state.type);
|
||||
if( state.form.shopType != 'only'){
|
||||
state.isEdit = true
|
||||
if (state.form.shopType != "only") {
|
||||
state.isEdit = true;
|
||||
}
|
||||
for (let key in state.rules) {
|
||||
if (key === "accountName") {
|
||||
@@ -409,12 +578,12 @@ function close() {
|
||||
state.dialogVisible = false;
|
||||
state.form = { ...state.resetForm };
|
||||
state.type = "";
|
||||
state.isEdit = false
|
||||
state.isEdit = false;
|
||||
}
|
||||
function reset() {
|
||||
state.form = { ...state.resetForm };
|
||||
state.type = "";
|
||||
state.isEdit = false
|
||||
state.isEdit = false;
|
||||
}
|
||||
|
||||
let ElMap = undefined;
|
||||
@@ -551,7 +720,7 @@ defineExpose({
|
||||
.amap-sug-result {
|
||||
z-index: 2000;
|
||||
}
|
||||
.tips{
|
||||
.tips {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,156 +1,110 @@
|
||||
<template>
|
||||
<el-dialog v-model="dialogVisible" :show-close="false" @close="reset">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="聚合支付" name="pay">
|
||||
<el-form ref="form" :model="form" label-width="120px" label-position="left">
|
||||
<el-form-item label="店铺id">
|
||||
<el-input v-model="form.storeId" placeholder="请输入店铺id"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户名称">
|
||||
<el-input v-model="form.merchantName" placeholder="请输入支付系统商户名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户应用id">
|
||||
<el-input v-model="form.appId" placeholder="请输入商户应用id"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户密钥">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="form.appSecret"
|
||||
placeholder="请输入商户密钥"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付密码">
|
||||
<el-input v-model="form.payPassword" placeholder="请输入支付密码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信appid">
|
||||
<el-input
|
||||
v-model="form.wechatSmallAppid"
|
||||
placeholder="请输入微信小程序appid"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付宝appid">
|
||||
<el-input
|
||||
v-model="form.alipaySmallAppid"
|
||||
placeholder="请输入支付宝小程序appid"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="支付宝商户号">
|
||||
<el-input v-model="form.alipayAppId" placeholder="请输入支付宝商户号"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付宝商户密钥">
|
||||
<el-input v-model="form.alipayAppToken" placeholder="请输入支付宝商户密钥"></el-input>
|
||||
</el-form-item> -->
|
||||
|
||||
<!-- <el-form-item label="状态">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio :value="1">启用</el-radio>
|
||||
<el-radio :value="-1">禁用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item> -->
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" @click="submitHandle" :loading="formLoading">
|
||||
<span v-if="!formLoading">保存</span>
|
||||
<span v-else>保存中...</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<div class="row mt14">
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="left">
|
||||
<el-form-item label="店铺ID" prop="storeId">
|
||||
<el-input v-model="form.storeId" placeholder="请输入店铺ID" :style="inputStyle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户名称" prop="merchantName">
|
||||
<el-input v-model="form.merchantName" placeholder="请输入商户名称" :style="inputStyle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="appId" prop="appId">
|
||||
<el-input v-model="form.appId" placeholder="请输入appId" :style="inputStyle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="appSecret" prop="appSecret">
|
||||
<el-input type="textarea" :rows="4" v-model="form.appSecret" placeholder="请输入appSecret"
|
||||
:style="inputStyle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitHandle" v-loading="loading">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { tbMerchantThirdApply, tbMerchantThirdApplyPut } from "@/api/shop";
|
||||
import ShopApi from "@/api/account/shop";
|
||||
import shopMerchantApi from "@/api/account/shopMerchant";
|
||||
import { ElNotification } from "element-plus";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
activeName: "pay",
|
||||
formLoading: false,
|
||||
form: {
|
||||
appSecret: "",
|
||||
id: "",
|
||||
payPassword: "",
|
||||
status: 1,
|
||||
appId: "",
|
||||
wechatSmallAppid: "",
|
||||
storeId: "",
|
||||
alipaySmallAppid: "",
|
||||
alipayAppToken: "",
|
||||
alipayAppId: "",
|
||||
},
|
||||
shopId: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 保存
|
||||
async submitHandle() {
|
||||
this.formLoading = true;
|
||||
try {
|
||||
await shopMerchantApi.edit(this.shopId, this.form);
|
||||
this.$emit("success");
|
||||
this.formLoading = false;
|
||||
ElNotification({
|
||||
title: "成功",
|
||||
message: `修改成功`,
|
||||
type: "success",
|
||||
});
|
||||
this.close();
|
||||
} catch (error) {
|
||||
this.formLoading = false;
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
reset() {
|
||||
this.form.appSecret = "";
|
||||
this.form.id = "";
|
||||
this.form.payPassword = "";
|
||||
this.form.status = 1;
|
||||
this.form.appId = "";
|
||||
this.shopId = "";
|
||||
},
|
||||
// 详情(配置三方支付)
|
||||
async getDetail(id) {
|
||||
console.log(id);
|
||||
this.shopId = id;
|
||||
try {
|
||||
const res = await shopMerchantApi.get(id);
|
||||
this.form.appSecret = res.appSecret || "";
|
||||
this.form.payPassword = res.payPassword || "";
|
||||
this.form.status = res.status || "";
|
||||
this.form.appId = res.appId || "";
|
||||
this.form.wechatSmallAppid = res.wechatSmallAppid || "";
|
||||
this.form.alipaySmallAppid = res.alipaySmallAppid || "";
|
||||
this.form.merchantName = res.merchantName || "";
|
||||
//this.form.alipayAppToken = res.alipayAppToken
|
||||
//this.form.alipayAppId = res.alipayAppId
|
||||
this.form.storeId = res.storeId || "";
|
||||
this.dialogVisible = true;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
},
|
||||
show(obj) {
|
||||
if (obj && obj.id) {
|
||||
this.form.id = obj.id;
|
||||
this.getDetail(obj.id);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { shopMerchantPut } from '@/api/common'
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.el-dialog__header) {
|
||||
padding: 0;
|
||||
const inputStyle = {
|
||||
width: '500px'
|
||||
}
|
||||
</style>
|
||||
|
||||
const props = defineProps({
|
||||
detail: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const formRef = ref(null)
|
||||
|
||||
const form = defineModel({
|
||||
storeId: '',
|
||||
merchantName: '',
|
||||
appId: '',
|
||||
appSecret: '',
|
||||
})
|
||||
|
||||
const rules = ref({
|
||||
storeId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入店铺ID',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
merchantName: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入店铺名称',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
appId: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入appId',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
appSecret: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入appSecret',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 验证表单
|
||||
function submitHandle() {
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
shopMerchantPostAjax()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 更新聚合支付
|
||||
const loading = ref(false)
|
||||
async function shopMerchantPostAjax() {
|
||||
try {
|
||||
loading.value = true
|
||||
const res = await shopMerchantPut({
|
||||
shopId: route.query.shopId,
|
||||
polyMerchantDTO: form.value
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '更新成功',
|
||||
type: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
console.log('shopMerchantPostAjax=', error);
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
</script>
|
||||
325
src/views/shop/list/components/payStatusCard.vue
Normal file
325
src/views/shop/list/components/payStatusCard.vue
Normal file
@@ -0,0 +1,325 @@
|
||||
<template>
|
||||
<div class="row mt14">
|
||||
<el-form label-width="150" label-position="left" v-loading="loading">
|
||||
<el-form-item label="信息来源" v-if="isHeadShop != 1">
|
||||
<el-radio-group :model-value="typeValue" @change="typeValueChange">
|
||||
<el-radio label="进件信息" :value="route.query.shopId"></el-radio>
|
||||
<el-radio label="复用主店信息" :value="route.query.mainId" v-if="mainInfo && mainInfo.shopId"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<template v-if="!form.shopId">
|
||||
<el-form-item label-width="0">
|
||||
<el-text>您还未申请进件</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="0">
|
||||
<el-button type="primary" @click="toApplyment">去申请</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-form-item label="商户号">
|
||||
<el-text>{{ form.merchantCode }}</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="商户类型">
|
||||
<el-text>{{ userTypeListFilter(form.userType).label }}</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="支付宝进件状态">
|
||||
<div class="column">
|
||||
<el-text :type="statusListFilter(form.alipayStatus).type">
|
||||
{{ statusListFilter(form.alipayStatus).label }}
|
||||
</el-text>
|
||||
<div class="center" v-if="form.alipayStatus == 'SIGN'">
|
||||
<el-text>待签约</el-text>
|
||||
<el-link type="primary" @click="singCodeDialogRef?.show(form.alipaySignUrl, 1)">查看签约码</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="微信进件状态">
|
||||
<div class="column">
|
||||
<el-text :type="statusListFilter(form.wechatStatus).type">
|
||||
{{ statusListFilter(form.wechatStatus).label }}
|
||||
</el-text>
|
||||
<div class="center" v-if="form.wechatStatus == 'SIGN'">
|
||||
<el-text>待签约</el-text>
|
||||
<el-link type="primary" @click="singCodeDialogRef?.show(form.wechatSignUrl, 2)">查看签约码</el-link>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="最后提交时间">
|
||||
<el-text>{{ form.updateTime }}</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间">
|
||||
<el-text>{{ form.createTime }}</el-text>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="typeValue == shopId">
|
||||
<el-button link type="primary"
|
||||
v-if="form.wechatStatus == 'INIT' || form.wechatStatus == 'AUDIT' || form.wechatStatus == 'SIGN' || form.alipayStatus == 'INIT' || form.alipayStatus == 'AUDIT' || form.alipayStatus == 'SIGN'"
|
||||
@click="checkStatusHandle()">查询</el-button>
|
||||
<el-button type="primary" @click="toDetail('check')">查看详情</el-button>
|
||||
<el-button type="primary" @click="toDetail('editor')"
|
||||
v-if="form.alipayStatus == 'REJECTED' || form.wechatStatus == 'REJECTED'">修改</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<singCodeDialog ref="singCodeDialogRef" />
|
||||
<!-- 分店复用主店信息弹窗 -->
|
||||
<el-dialog title="注意" width="400px" top="40vh" v-model="mainDialogVisable">
|
||||
<span>是否复用主店?</span>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="toApplymentRouter">自己申请</el-button>
|
||||
<el-button type="primary" @click="shopMerchantPutAjax" :loading="mainDialogVisableLoading">复用主店信息</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { shopMerchantGet, getMainMerchant, shopMerchantPut, entryManagerDetail } from '@/api/common'
|
||||
import singCodeDialog from '@/views/applyments/components/singCodeDialog.vue';
|
||||
|
||||
const singCodeDialogRef = ref(null)
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const shopId = ref(route.query.shopId)
|
||||
const userTypeList = ref([
|
||||
{
|
||||
value: '0',
|
||||
label: '个体商户'
|
||||
},
|
||||
{
|
||||
value: '1',
|
||||
label: '企业商户'
|
||||
},
|
||||
])
|
||||
function userTypeListFilter(userType) {
|
||||
let obj = userTypeList.value.find(item => item.value == userType)
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: userType,
|
||||
value: userType
|
||||
}
|
||||
}
|
||||
}
|
||||
const statusList = ref([
|
||||
{
|
||||
value: 'WAIT',
|
||||
label: '待提交',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
value: 'INIT',
|
||||
label: '待处理',
|
||||
type: 'info'
|
||||
},
|
||||
{
|
||||
value: 'AUDIT',
|
||||
label: '待审核',
|
||||
type: 'warning'
|
||||
},
|
||||
{
|
||||
value: 'SIGN',
|
||||
label: '待签约',
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
value: 'FINISH',
|
||||
label: '已完成',
|
||||
type: 'success'
|
||||
},
|
||||
{
|
||||
value: 'REJECTED',
|
||||
label: '失败',
|
||||
type: 'danger'
|
||||
},
|
||||
])
|
||||
function statusListFilter(status) {
|
||||
let obj = statusList.value.find(item => item.value == status)
|
||||
if (obj) {
|
||||
return obj
|
||||
} else {
|
||||
return {
|
||||
label: status,
|
||||
value: status
|
||||
}
|
||||
}
|
||||
}
|
||||
const loading = ref(false)
|
||||
const form = ref({})
|
||||
|
||||
|
||||
// 查询状态
|
||||
async function checkStatusHandle() {
|
||||
try {
|
||||
loading.value = true
|
||||
const businessLicenceInfo = form.value.businessLicenceInfo
|
||||
await queryEntry({
|
||||
shopId: form.value.shopId,
|
||||
licenceNo: businessLicenceInfo.licenceNo
|
||||
})
|
||||
updateData()
|
||||
} catch (error) {
|
||||
loading.value = false
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取主店进件信息
|
||||
const mainInfo = ref({})
|
||||
async function headShopApplmentInfo() {
|
||||
try {
|
||||
if (route.query.mainId) {
|
||||
const res = await getMainMerchant({
|
||||
shopId: route.query.mainId
|
||||
})
|
||||
mainInfo.value = res
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转进件逻辑处理
|
||||
const mainDialogVisable = ref(false)
|
||||
const mainDialogVisableLoading = ref(false)
|
||||
const isHeadShop = ref(route.query.isHeadShop)
|
||||
async function toApplyment() {
|
||||
let shopType = route.query.shopType
|
||||
if (shopType == 'chain' || shopType == 'join') {
|
||||
if (isHeadShop == 1) {
|
||||
toApplymentRouter()
|
||||
} else {
|
||||
// 分店弹窗选择
|
||||
await headShopApplmentInfo()
|
||||
if (mainInfo.value && mainInfo.value.shopId) {
|
||||
mainDialogVisable.value = true
|
||||
} else {
|
||||
toApplymentRouter()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toApplymentRouter()
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转进件
|
||||
function toApplymentRouter() {
|
||||
router.push({ name: 'applyment_in', query: { shopId: shopId.value } });
|
||||
}
|
||||
|
||||
// 复用主店的进件信息
|
||||
async function shopMerchantPutAjax() {
|
||||
try {
|
||||
mainDialogVisableLoading.value = true
|
||||
await shopMerchantPut({
|
||||
shopId: shopId.value,
|
||||
relatedId: mainInfo.value.shopId,
|
||||
nativeMerchantDTO: {
|
||||
wechatMerchantId: mainInfo.value.wechatMerchantId,
|
||||
alipayMerchantId: mainInfo.value.alipayMerchantId,
|
||||
alipayAuthInfo: mainInfo.value.alipayAuthInfo
|
||||
}
|
||||
})
|
||||
ElNotification({
|
||||
title: '注意',
|
||||
message: '复用成功',
|
||||
type: 'success'
|
||||
})
|
||||
mainDialogVisable.value = false
|
||||
updateData()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
mainDialogVisableLoading.value = false
|
||||
}
|
||||
|
||||
// 跳转编辑页面
|
||||
function toDetail(type) {
|
||||
const businessLicenceInfo = form.value.businessLicenceInfo
|
||||
router.push({
|
||||
name: 'applyment_in',
|
||||
query: {
|
||||
shopId: shopId.value,
|
||||
licenceNo: businessLicenceInfo.licenceNo,
|
||||
type: type
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 切换进件类型
|
||||
const typeValue = ref('')
|
||||
async function typeValueChange(e) {
|
||||
await ElMessageBox.confirm('确定要切换进件类型吗?', '注意').then(async () => {
|
||||
try {
|
||||
try {
|
||||
loading.value = true
|
||||
await shopMerchantPut({
|
||||
shopId: shopId.value,
|
||||
relatedId: e,
|
||||
})
|
||||
typeValue.value = e
|
||||
updateData()
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
loading.value = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
// 刷新进件数据
|
||||
async function updateData() {
|
||||
try {
|
||||
loading.value = true
|
||||
const res = await shopMerchantGet({
|
||||
shopId: shopId.value
|
||||
})
|
||||
|
||||
if (res && res.shopDirectMerchant) {
|
||||
form.value = res.shopDirectMerchant
|
||||
typeValue.value = res.relatedId
|
||||
} else {
|
||||
typeValue.value = shopId.value
|
||||
const applymentRes = await entryManagerDetail({ shopId: shopId.value })
|
||||
if (applymentRes && applymentRes.shopId) {
|
||||
form.value = applymentRes
|
||||
} else {
|
||||
form.value = ''
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateData()
|
||||
headShopApplmentInfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
@@ -25,7 +25,7 @@
|
||||
<el-button type="primary" icon="plus" @click="addShopShow">添加店铺</el-button>
|
||||
</div>
|
||||
<div class="head-container">
|
||||
<el-table v-loading="state.tableData.loading" :data="state.tableData.list">
|
||||
<el-table v-loading="state.tableData.loading" :data="state.tableData.list" stripe border>
|
||||
<el-table-column label="店铺信息" width="200">
|
||||
<template v-slot="scope">
|
||||
<div class="shop_info">
|
||||
@@ -57,23 +57,25 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="登录账号" prop="phone"></el-table-column>
|
||||
<el-table-column prop="registerType" label="经营模式">
|
||||
<template v-slot="scope">
|
||||
<span v-if="scope.row.registerType == 'before'">快餐版</span>
|
||||
<span v-if="scope.row.registerType == 'after'">餐饮版</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="address" label="商户号" />
|
||||
<el-table-column prop="status" label="店铺类型" align="center">
|
||||
<template v-slot="scope">
|
||||
<div>
|
||||
<span v-if="scope.row.shopType == 'only'">单店</span>
|
||||
<span v-if="scope.row.shopType == 'chain'">连锁店</span>
|
||||
<span v-if="scope.row.shopType == 'join'">加盟店</span>
|
||||
<div v-if="scope.row.shopType != 'only'&&scope.row.isHeadShop == 0">(主店:{{ scope.row.headShopName }})</div>
|
||||
<div v-if="scope.row.shopType != 'only' && scope.row.isHeadShop == 0">(主店:{{ scope.row.headShopName }})
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="address" label="商户号" />
|
||||
<el-table-column prop="status" label="店铺状态">
|
||||
<template v-slot="scope">
|
||||
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" disabled />
|
||||
@@ -113,7 +115,7 @@
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-if="scope.row.isHeadShop == 1" :command="0">添加分店</el-dropdown-item>
|
||||
<el-dropdown-item :command="{ row: scope.row, command: 1 }">
|
||||
三方配置
|
||||
支付配置
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item :command="2">续费记录</el-dropdown-item>
|
||||
<el-dropdown-item :command="3">前往店铺</el-dropdown-item>
|
||||
@@ -132,7 +134,7 @@
|
||||
layout="total, sizes , prev, pager ,next, jumper " @current-change="paginationChange" />
|
||||
</div>
|
||||
<addShop ref="refAddShop" @success="getTableData" />
|
||||
<detailModal ref="refDetailModal" />
|
||||
<!-- <detailModal ref="refDetailModal" /> -->
|
||||
<!-- 激活码 -->
|
||||
<activateCode ref="refActivateCode" @success="getTableData" />
|
||||
</div>
|
||||
@@ -145,6 +147,10 @@ import ShopApi from "@/api/account/shop";
|
||||
import { ElNotification, ElMessageBox } from "element-plus";
|
||||
import addShop from "./components/addShop.vue";
|
||||
import detailModal from "./components/detailModal.vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const refActivateCode = ref(null);
|
||||
function activateCodeShow(row) {
|
||||
refActivateCode.value.open(row);
|
||||
@@ -186,12 +192,24 @@ function dropdownClick(e, row) {
|
||||
console.log(e);
|
||||
console.log(row);
|
||||
if (e == 0) {
|
||||
refAddShop.value.show({mainId:row.id,shopType:row.shopType,isHeadShop:0},'addBranch');
|
||||
refAddShop.value.show({ mainId: row.id, shopType: row.shopType, isHeadShop: 0 }, 'addBranch');
|
||||
|
||||
return;
|
||||
}
|
||||
if (e.command == 1) {
|
||||
refDetailModal.value.show(e.row);
|
||||
console.log('row===', row);
|
||||
|
||||
// refDetailModal.value.show(e.row);
|
||||
router.push({
|
||||
name: 'pay_setting',
|
||||
query: {
|
||||
shopId: row.id,
|
||||
shopType: row.shopType,
|
||||
isHeadShop: row.isHeadShop,
|
||||
mainId: row.mainId,
|
||||
shopName: row.shopName
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (e == 5) {
|
||||
|
||||
149
src/views/shop/list/pay_setting.vue
Normal file
149
src/views/shop/list/pay_setting.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<!-- 支付配置页面 -->
|
||||
<template>
|
||||
<div class="gyq_container">
|
||||
<div class="header_wrap">
|
||||
<div class="left_btn" @click="router.back()">
|
||||
<el-icon size="22" color="#333">
|
||||
<Back />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="t">{{ route.query.shopName }} | 支付配置</div>
|
||||
<div class="intro">管理您的支付渠道和进件信息</div>
|
||||
</div>
|
||||
<div class="center">
|
||||
<el-text size="large">当前模式:</el-text>
|
||||
<el-radio-group size="large" :model-value="payModel" @change="handleRadioChange">
|
||||
<el-radio :label="item.label" :value="item.value" v-for="item in tabList" :key="item.value"></el-radio>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gyq_content row mt14">
|
||||
<tabHeader v-model="tabActiveIndex" :list="tabList" />
|
||||
<payStatusCard name="payStatusCard" key="payStatusCard" ref="payStatusCardRef" v-if="tabActiveIndex == 0" />
|
||||
<detailModal name="detailModal" key="detailModal" ref="detailModalRef" v-model="detail"
|
||||
v-if="tabActiveIndex == 1" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import detailModal from './components/detailModal.vue';
|
||||
import payStatusCard from './components/payStatusCard.vue';
|
||||
import { shopMerchantGet, shopMerchantPut } from '@/api/common'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const payModel = ref('')
|
||||
const tabActiveIndex = ref(0)
|
||||
const tabList = ref([
|
||||
{
|
||||
label: '支付进件',
|
||||
value: 'native'
|
||||
},
|
||||
{
|
||||
label: '聚合支付',
|
||||
value: 'poly'
|
||||
}
|
||||
])
|
||||
|
||||
// 二次确认支付模式 更换支付模式
|
||||
async function handleRadioChange(value) {
|
||||
await ElMessageBox.confirm('确定要选择该模式吗?', '注意').then(async () => {
|
||||
try {
|
||||
await shopMerchantPut({
|
||||
shopId: route.query.shopId,
|
||||
channel: value
|
||||
})
|
||||
payModel.value = value
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}).catch(() => { })
|
||||
}
|
||||
|
||||
// 与子组件的form绑定
|
||||
const detail = ref({})
|
||||
async function shopMerchantGetAjax() {
|
||||
try {
|
||||
const res = await shopMerchantGet({ shopId: route.query.shopId })
|
||||
console.log('shopMerchantGetAjax===', res);
|
||||
if (res && res.shopId) {
|
||||
payModel.value = res.channel
|
||||
|
||||
if (res && res.polyMerchantDTO) {
|
||||
detail.value = res.polyMerchantDTO
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
shopMerchantGetAjax()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gyq_container {
|
||||
padding: 14px;
|
||||
|
||||
.gyq_content {
|
||||
padding: 14px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
&.mt14 {
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.header_wrap {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 14px;
|
||||
|
||||
.left_btn {
|
||||
height: 73px;
|
||||
padding: 14px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
padding: 14px 14px 14px 0;
|
||||
|
||||
.t {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.intro {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,22 +4,38 @@
|
||||
<template v-if="carts.list && carts.list.length >= 1">
|
||||
<!-- 当前购物车 -->
|
||||
<div v-for="(item, index) in carts.list" :key="index">
|
||||
<carts-item :item="item" :useVipPrice="carts.useVipPrice" @changeNumber="changeNumber"
|
||||
:selCart="carts.selCart" @itemClick="itemClick(item)" @editNote="editNote"></carts-item>
|
||||
<carts-item
|
||||
:item="item"
|
||||
:useVipPrice="carts.useVipPrice"
|
||||
@changeNumber="changeNumber"
|
||||
:selCart="carts.selCart"
|
||||
@itemClick="itemClick(item)"
|
||||
@editNote="editNote"
|
||||
></carts-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 赠菜 -->
|
||||
<div class="cart-title" v-if="carts.giftList.length > 0"><span>以下是优惠菜品</span></div>
|
||||
<div v-for="(item, index) in carts.giftList" :key="index">
|
||||
<carts-item :item="item" @changeNumber="changeNumber" :useVipPrice="carts.useVipPrice" :selCart="carts.selCart"
|
||||
@itemClick="itemClick(item)" @editNote="editNote"></carts-item>
|
||||
<carts-item
|
||||
:item="item"
|
||||
@changeNumber="changeNumber"
|
||||
:useVipPrice="carts.useVipPrice"
|
||||
:selCart="carts.selCart"
|
||||
@itemClick="itemClick(item)"
|
||||
@editNote="editNote"
|
||||
></carts-item>
|
||||
</div>
|
||||
<el-empty :image-size="60" v-if="carts.isEmpty" description="点餐列表为空" />
|
||||
<!-- 打包费 -->
|
||||
<template v-if="carts.packNum > 0">
|
||||
<div class="cart-title"><span>打包费</span></div>
|
||||
<extra-fee name="打包费" :number="carts.packNum" :price="carts.orderCostSummary.packFee"></extra-fee>
|
||||
<extra-fee
|
||||
name="打包费"
|
||||
:number="carts.packNum"
|
||||
:price="carts.orderCostSummary.packFee"
|
||||
></extra-fee>
|
||||
</template>
|
||||
<!-- 餐位费 -->
|
||||
<template v-if="perpole >= 1 && carts.dinnerType == 'dine-in'">
|
||||
@@ -40,9 +56,17 @@
|
||||
</div>
|
||||
|
||||
<div v-for="(detaiItem, index) in item" :key="index">
|
||||
<carts-item :useVipPrice="carts.useVipPrice" :canChangeNumber="false" isOld :dinerType="dinerType"
|
||||
:item="detaiItem" @changeNumber="changeNumber" :selCart="carts.selCart" @itemClick="itemClick(detaiItem)"
|
||||
@editNote="editNote"></carts-item>
|
||||
<carts-item
|
||||
:useVipPrice="carts.useVipPrice"
|
||||
:canChangeNumber="false"
|
||||
isOld
|
||||
:dinerType="dinerType"
|
||||
:item="detaiItem"
|
||||
@changeNumber="changeNumber"
|
||||
:selCart="carts.selCart"
|
||||
@itemClick="itemClick(detaiItem)"
|
||||
@editNote="editNote"
|
||||
></carts-item>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -50,9 +74,14 @@
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="u-flex u-row-right">
|
||||
<el-tooltip placement="top" effect="light" popper-class="youhui-tips" :popper-options="{
|
||||
'background-color': '#fff',
|
||||
}">
|
||||
<el-tooltip
|
||||
placement="top"
|
||||
effect="light"
|
||||
popper-class="youhui-tips"
|
||||
:popper-options="{
|
||||
'background-color': '#fff',
|
||||
}"
|
||||
>
|
||||
<template #content>
|
||||
<div class="u-flex color-000 u-font-14 u-row-between">
|
||||
<span class="font-bold">会员优惠</span>
|
||||
@@ -74,20 +103,36 @@
|
||||
</div>
|
||||
|
||||
<div class="u-flex u-row-between">
|
||||
<el-link type="primary">打印制作单</el-link>
|
||||
<!-- <el-link type="primary">打印制作单</el-link> -->
|
||||
<div></div>
|
||||
<div>
|
||||
<span class="totalNumber">共{{ customTruncateToTwoDecimals(carts.totalNumber) }}件</span>
|
||||
<span class="totalPrice">¥{{ customTruncateToTwoDecimals(carts.payMoney) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group" v-if="isXianFuKuan">
|
||||
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('wx-aiplay')">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!disabledMorePay"
|
||||
@click="createOrder('wx-aiplay')"
|
||||
>
|
||||
微信/支付宝
|
||||
</el-button>
|
||||
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('cash')">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!disabledMorePay"
|
||||
@click="createOrder('cash')"
|
||||
>
|
||||
现金
|
||||
</el-button>
|
||||
<el-button type="primary" size="large" :disabled="!disabledMorePay" @click="createOrder('more-pay')">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!disabledMorePay"
|
||||
@click="createOrder('more-pay')"
|
||||
>
|
||||
更多支付
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -100,20 +145,31 @@
|
||||
<el-button type="primary" size="large" :disabled="disabledMorePay" @click="createOrder('to-pay')">
|
||||
去结账
|
||||
</el-button> -->
|
||||
<el-button type="primary" size="large"
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="carts.list.length == 0 || carts.oldOrder.detailMap.length == 0"
|
||||
@click="createOrder('only-create')">
|
||||
@click="createOrder('only-create')"
|
||||
>
|
||||
仅下单
|
||||
</el-button>
|
||||
<el-button type="primary" size="large"
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="carts.list.length == 0 && isEmptyObject(carts.oldOrder.detailMap)"
|
||||
@click="createOrder('to-pay')">
|
||||
@click="createOrder('to-pay')"
|
||||
>
|
||||
去结账
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="default" size="large" @click="hideOrder()">加菜/返回</el-button>
|
||||
<el-button type="primary" size="large" :disabled="!carts.isLinkFinshed" @click="createOrder('to-pay')">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
:disabled="!carts.isLinkFinshed"
|
||||
@click="createOrder('to-pay')"
|
||||
>
|
||||
立即支付
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -131,7 +187,7 @@ import { useUserStore } from "@/store/modules/user";
|
||||
|
||||
function isEmptyObject(obj) {
|
||||
// 步骤1:排除null和非对象类型
|
||||
if (obj === null || typeof obj !== 'object') {
|
||||
if (obj === null || typeof obj !== "object") {
|
||||
return false;
|
||||
}
|
||||
// 步骤2:排除数组(数组也是对象,需单独判断)
|
||||
@@ -313,4 +369,4 @@ defineExpose({
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
{{ multiplyAndFormat(scope.row.amount || 0) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="积分" prop="accountPoints">
|
||||
<el-table-column label="积分" prop="pointBalance">
|
||||
<template #default="scope">
|
||||
{{ scope.row.accountPoints || 0 }}
|
||||
{{ scope.row.pointBalance || 0 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="90" fixed="right">
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</p>
|
||||
<p class="u-font-14 color-666 u-m-t-10">
|
||||
<span class="money">余额:{{ carts.vipUser.amount }}</span>
|
||||
<span class="score u-m-l-10">积分:{{ carts.vipUser.accountPoints }}</span>
|
||||
<span class="score u-m-l-10">积分:{{ carts.vipUser.pointBalance }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,7 +46,8 @@
|
||||
</el-radio-group>
|
||||
<el-input-number class="u-m-l-10" v-if="score.sel != -1" v-model="usePointsNumber" step-strictly
|
||||
:step="pointsRes.equivalentPoints" placeholder="请输入积分抵扣数量" :min="pointsRes.minDeductionPoints"
|
||||
:max="pointsRes.maxUsablePoints" @change="pointsToMoney"></el-input-number>
|
||||
:max="pointsRes.maxUsablePoints" :disabled="!pointsRes.usable"
|
||||
@change="pointsToMoney"></el-input-number>
|
||||
</div>
|
||||
<p class="u-font-14 color-666 u-m-t-10" v-if="pointsRes.unusableReason && !pointsRes.usable">
|
||||
<span class="color-red">*</span>
|
||||
@@ -219,6 +220,25 @@
|
||||
<popup-coupon ref="refCoupon" :user="carts.vipUser" @confirm="refCouponConfirm"></popup-coupon>
|
||||
<!-- 挂账 -->
|
||||
<chooseGuaZahng ref="refGuaZhang" :payMoney="currentpayMoney" @confirm="refGuaZhangConfirm"></chooseGuaZahng>
|
||||
<!-- 扫码等待用户支付转台查询 -->
|
||||
<el-dialog v-model="showCheckPayStauts" width="400" title="订单支付状态查询中..." :close-on-click-modal="false"
|
||||
:show-close="false">
|
||||
<div class="pay_status_content">
|
||||
<div class="loading" v-loading="checkPayStautsLoading" element-loading-text="用户支付中..."></div>
|
||||
<div class="btn">
|
||||
<el-button style="width: 100%" :disabled="!closeState" type="primary" @click="resetScanCode">
|
||||
<span v-if="!closeState">{{ closeStateTime }}秒后可重新扫码</span>
|
||||
<span v-else>重新扫码</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button style="width: 100%" :disabled="!closeState" @click="closeScanCode">
|
||||
<span v-if="!closeState">{{ closeStateTime }}秒后可关闭</span>
|
||||
<span v-else>关闭</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -242,6 +262,7 @@ import discount from "./discount.vue";
|
||||
import { ElLoading } from "element-plus";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { BigNumber } from "bignumber.js";
|
||||
import { onUnmounted } from 'vue'
|
||||
|
||||
// 配置BigNumber精度
|
||||
BigNumber.set({
|
||||
@@ -398,8 +419,16 @@ watch(
|
||||
);
|
||||
|
||||
//002-获取订单可用积分及抵扣金额(支付页面使用)
|
||||
const pointsRes = ref({ usable: true, maxUsablePoints: 0, minDeductionPoints: 0 });
|
||||
const usePointsNumber = ref(0);
|
||||
const pointsRes = ref({
|
||||
usable: false,
|
||||
equivalentPoints: 0, // 积分换算比例 eg: 20 积分 = 1 元
|
||||
maxDeductionRatio: 0, // 下单最高抵扣比例(小数)
|
||||
minPaymentAmount: 0, // 下单实付抵扣门槛(元)
|
||||
maxUsablePoints: 0,
|
||||
minDeductionPoints: 0,
|
||||
unusableReason: "",
|
||||
});
|
||||
const usePointsNumber = ref(0); // 输入的积分数量(用户填写)
|
||||
//积分可抵扣最大金额
|
||||
const scoreMaxMoney = computed(() => {
|
||||
return (
|
||||
@@ -421,22 +450,145 @@ async function pointsInit() {
|
||||
if (!carts.vipUser.id) {
|
||||
return;
|
||||
}
|
||||
const res = await PointsApi.calcOrderUsablePoints({
|
||||
const { pointsConfig, pointsUser } = await PointsApi.calcOrderUsablePoints({
|
||||
shopUserId: carts.vipUser.id,
|
||||
orderAmount: scoreMaxMoney.value,
|
||||
});
|
||||
|
||||
// 不修改 accountPoints(为余额),将积分保存到 pointBalance 字段
|
||||
carts.vipUser.pointBalance = pointsUser && pointsUser.id ? pointsUser.pointBalance : 0;
|
||||
|
||||
// 保险取值
|
||||
const eq = pointsConfig?.equivalentPoints || 0;
|
||||
const rawMaxRatio = pointsConfig?.maxDeductionRatio || 0;
|
||||
// 兼容后端返回的百分比或小数两种形式:如果大于1,则视为百分比(如100表示100%),需除以100
|
||||
const maxRatio = rawMaxRatio > 1 ? rawMaxRatio / 100 : rawMaxRatio;
|
||||
const minPay = pointsConfig?.minPaymentAmount || 0;
|
||||
|
||||
// 计算当前订单可抵扣金额上限(元)
|
||||
// 使用“抵扣前实付金额”作为门槛判断(即把当前已应用的积分抵扣金额加回),
|
||||
// 避免在已经抵扣导致 finalPay 变小后错误地判定为不可用。
|
||||
let finalPay = Number(carts.orderCostSummary.finalPayAmount) || 0;
|
||||
const currentPointDeduction = Number(carts.orderCostSummary.pointDeductionAmount) || 0;
|
||||
const basePay = finalPay + currentPointDeduction;
|
||||
|
||||
const res = {
|
||||
usable: true,
|
||||
equivalentPoints: eq,
|
||||
maxDeductionRatio: maxRatio,
|
||||
minPaymentAmount: minPay,
|
||||
maxUsablePoints: 0,
|
||||
minDeductionPoints: pointsConfig?.minDeductionPoints || eq,
|
||||
unusableReason: "",
|
||||
};
|
||||
|
||||
// 如果订单实付低于最小使用门槛,则不可用(门槛仅作为启用条件)
|
||||
// 这里使用 basePay(抵扣前实付)进行判断,确保已填写积分后不会回退为不可用
|
||||
if (basePay <= 0 || (minPay > 0 && basePay < minPay)) {
|
||||
res.usable = false;
|
||||
res.unusableReason = `订单实付金额低于 ${minPay} 元,无法使用积分抵扣`;
|
||||
} else if (eq <= 0) {
|
||||
res.usable = false;
|
||||
res.unusableReason = `积分换算比例配置错误,无法使用积分抵扣`;
|
||||
} else {
|
||||
// 计算基于比例限制的最大抵扣金额(元)
|
||||
// 注意:此处不再减少 minPaymentAmount,minPaymentAmount 仅用作是否可用的门槛;
|
||||
// 真正的最大抵扣由 maxRatio(抵扣比例)与用户积分数量共同决定。
|
||||
// 计算基于比例限制的最大抵扣金额(元),基于抵扣前实付金额
|
||||
let maxByRatio = basePay * maxRatio;
|
||||
|
||||
if (res.usable) {
|
||||
// 可用积分上限(按等价积分步长对齐到 eq 的倍数)
|
||||
const maxByMoney = Math.floor(maxByRatio * eq);
|
||||
const userPoints = carts.vipUser.pointBalance || 0;
|
||||
let computedMax = Math.min(userPoints, maxByMoney);
|
||||
// 对齐到等价积分步长,保证输入步长生效
|
||||
if (eq > 0) {
|
||||
computedMax = Math.floor(computedMax / eq) * eq;
|
||||
}
|
||||
res.maxUsablePoints = computedMax;
|
||||
console.debug("pointsInit debug:", { finalPay: finalPay, basePay: basePay, eq, rawMaxRatio, maxRatio, maxByMoney, userPoints, computedMax });
|
||||
// 最小抵扣积分为配置值或等于换算比
|
||||
res.minDeductionPoints = pointsConfig?.minDeductionPoints || eq;
|
||||
if (res.maxUsablePoints < res.minDeductionPoints) {
|
||||
res.usable = false;
|
||||
res.unusableReason = `可用积分不足,至少需要 ${res.minDeductionPoints} 积分才可抵扣`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pointsRes.value = res;
|
||||
carts.pointDeductionRule.pointsPerYuan = res.equivalentPoints;
|
||||
|
||||
if (score.sel == -1) {
|
||||
// 未选择使用积分
|
||||
return res;
|
||||
}
|
||||
|
||||
// 如果可用则默认填充可用最大值(对齐步长),否则清零
|
||||
if (res.usable) {
|
||||
// 计算默认填充值:基于抵扣前实付的比例上限与等价比计算需要的积分数
|
||||
const defaultMaxByMoney = Math.floor(basePay * res.maxDeductionRatio * res.equivalentPoints);
|
||||
let defaultPts = Math.min(res.maxUsablePoints || 0, defaultMaxByMoney || 0);
|
||||
if (res.equivalentPoints > 0) {
|
||||
defaultPts = Math.floor(defaultPts / res.equivalentPoints) * res.equivalentPoints;
|
||||
}
|
||||
// 最终确保不超过用户积分
|
||||
const userPts = carts.vipUser.pointBalance || 0;
|
||||
usePointsNumber.value = Math.min(defaultPts, userPts);
|
||||
} else {
|
||||
usePointsNumber.value = 0;
|
||||
}
|
||||
if (!res.usable) score.sel = -1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// 将输入的积分数转换为抵扣金额并写回 carts.orderCostSummary
|
||||
function pointsToMoney(val) {
|
||||
const cfg = pointsRes.value;
|
||||
if (!cfg.usable || cfg.equivalentPoints <= 0) {
|
||||
usePointsNumber.value = 0;
|
||||
carts.orderCostSummary.pointUsed = 0;
|
||||
carts.orderCostSummary.pointDeductionAmount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
usePointsNumber.value = res.usable ? res.maxUsablePoints : 0;
|
||||
if (res.usable) {
|
||||
} else {
|
||||
score.sel = -1;
|
||||
// 确保为整数积分
|
||||
let pts = parseInt(usePointsNumber.value || 0, 10);
|
||||
if (isNaN(pts) || pts <= 0) {
|
||||
pts = 0;
|
||||
}
|
||||
return res;
|
||||
|
||||
// 限制最大值
|
||||
if (cfg.maxUsablePoints && pts > cfg.maxUsablePoints) {
|
||||
pts = cfg.maxUsablePoints;
|
||||
}
|
||||
|
||||
// 计算抵扣金额(元),向下保留两位
|
||||
const money = new BigNumber(pts).div(cfg.equivalentPoints).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
||||
|
||||
// 再次校验不超过允许的最大抵扣金额(基于比例或门槛)
|
||||
let finalPay = Number(carts.orderCostSummary.finalPayAmount) || 0;
|
||||
let maxByRatio = finalPay * cfg.maxDeductionRatio;
|
||||
// 对于单笔抵扣:若订单实付低于配置的最小门槛,则不可使用(作为启用条件)
|
||||
if (cfg.minPaymentAmount > 0 && finalPay < cfg.minPaymentAmount) {
|
||||
usePointsNumber.value = 0;
|
||||
carts.orderCostSummary.pointUsed = 0;
|
||||
carts.orderCostSummary.pointDeductionAmount = 0;
|
||||
return;
|
||||
}
|
||||
const maxAllowedMoney = new BigNumber(maxByRatio).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
||||
console.debug("pointsToMoney debug:", { finalPay, cfg, pts, money, maxByRatio, maxAllowedMoney });
|
||||
if (money > maxAllowedMoney) {
|
||||
// 调整积分到允许的最大金额对应的积分
|
||||
const allowedPts = Math.floor(maxAllowedMoney * cfg.equivalentPoints);
|
||||
pts = Math.min(allowedPts, cfg.maxUsablePoints);
|
||||
}
|
||||
|
||||
usePointsNumber.value = pts;
|
||||
const finalMoney = new BigNumber(pts).div(cfg.equivalentPoints).decimalPlaces(2, BigNumber.ROUND_DOWN).toNumber();
|
||||
carts.orderCostSummary.pointUsed = pts;
|
||||
carts.orderCostSummary.pointDeductionAmount = finalMoney;
|
||||
}
|
||||
|
||||
const emits = defineEmits(["chooseUser", "paysuccess"]);
|
||||
@@ -619,7 +771,12 @@ async function payOrder(payType, isScan, guazhangren) {
|
||||
}
|
||||
carts.clear();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log('payOrder===', error);
|
||||
// 启动状态查询
|
||||
if (error.code == 211) {
|
||||
showCheckPayStauts.value = true
|
||||
autoCheckOrder()
|
||||
}
|
||||
clearTimeout(payTimer);
|
||||
loading.close();
|
||||
}
|
||||
@@ -630,6 +787,102 @@ async function payOrder(payType, isScan, guazhangren) {
|
||||
}
|
||||
}
|
||||
|
||||
function clearAutoCheckOrder() {
|
||||
clearInterval(timer.value)
|
||||
timer.value = null
|
||||
}
|
||||
|
||||
// 关闭查询
|
||||
function closeScanCode() {
|
||||
showCheckPayStauts.value = false;
|
||||
reset()
|
||||
}
|
||||
|
||||
// 重新扫码
|
||||
function resetScanCode() {
|
||||
reset()
|
||||
showCheckPayStauts.value = false;
|
||||
clearInterval(timer.value)
|
||||
timer.value = null
|
||||
|
||||
clearInterval(closeStateTimer.value)
|
||||
closeStateTimer.value = null
|
||||
|
||||
setTimeout(() => {
|
||||
refScanPay.value.open(returnPayParams(), "scanCode")
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const closeState = ref(false)
|
||||
const closeStateTime = ref(5);
|
||||
const closeStateTimer = ref(null)
|
||||
|
||||
function closeStateTimerFuc() {
|
||||
closeStateTimer.value = setInterval(() => {
|
||||
closeStateTime.value--
|
||||
if (closeStateTime.value <= 0) {
|
||||
clearInterval(closeStateTimer.value)
|
||||
closeStateTimer.value = null
|
||||
closeState.value = true
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 自动查询订单状态
|
||||
const timer = ref(null)
|
||||
function autoCheckOrder() {
|
||||
closeStateTimerFuc()
|
||||
timer.value = setInterval(() => {
|
||||
// 开始锁单
|
||||
// goodsStore.isOrderLock({
|
||||
// table_code: table_code.value
|
||||
// }, 'pay_lock')
|
||||
checkPayStauts(false)
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
function reset() {
|
||||
checkPayStautsLoading.value = true;
|
||||
closeState.value = false
|
||||
closeStateTime.value = 5
|
||||
}
|
||||
|
||||
// 查询订单支付状态
|
||||
const showCheckPayStauts = ref(false)
|
||||
const checkPayStautsLoading = ref(true)
|
||||
async function checkPayStauts(tips = true) {
|
||||
try {
|
||||
// 扫码下单
|
||||
const res = await payApi.queryOrderStatus({ orderId: props.orderInfo.id });
|
||||
if (res == "done") {
|
||||
// 支付成功,解锁订单
|
||||
// await goodsStore.isOrderLock({
|
||||
// table_code: table_code.value
|
||||
// }, 'pay_unlock')
|
||||
|
||||
// userPayWait.value = false
|
||||
checkPayStautsLoading.value = false;
|
||||
// scanCode.value = "";
|
||||
showCheckPayStauts.value = false;
|
||||
clearAutoCheckOrder()
|
||||
paysuccess();
|
||||
return;
|
||||
}
|
||||
if (res == "unpaid") {
|
||||
if (tips) {
|
||||
ElMessage.warning("用户支付中...");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
clearAutoCheckOrder()
|
||||
ElMessage.warning(res.msg || '');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
function paysuccess() {
|
||||
clearTimeout(payTimer);
|
||||
ElMessage.success("支付成功");
|
||||
@@ -690,9 +943,17 @@ watch(
|
||||
}
|
||||
);
|
||||
|
||||
onUnmounted(() => {
|
||||
clearAutoCheckOrder()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
carts.payParamsInit();
|
||||
getPaytype();
|
||||
|
||||
if (carts.vipUser.id) {
|
||||
pointsInit();
|
||||
}
|
||||
});
|
||||
defineExpose({
|
||||
nowPayClick,
|
||||
@@ -738,9 +999,13 @@ defineExpose({
|
||||
.order-info {
|
||||
font-size: 14px;
|
||||
|
||||
.title {}
|
||||
.title {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.value {}
|
||||
.value {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #fa5555;
|
||||
@@ -759,4 +1024,30 @@ defineExpose({
|
||||
color: #666;
|
||||
padding: 8px 10px 8px 20px;
|
||||
}
|
||||
|
||||
.pay_status_content {
|
||||
flex: 1;
|
||||
padding: 0 var(--el-font-size-base);
|
||||
height: 400px;
|
||||
padding-bottom: 100px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.loading {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
--el-loading-spinner-size: 100px;
|
||||
|
||||
:deep(.el-loading-text) {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 200px;
|
||||
padding-top: var(--el-font-size-base);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -2,12 +2,8 @@
|
||||
<el-dialog width="400px" :title="title" v-model="show" @close="reset">
|
||||
<div class="u-p-15">
|
||||
<div v-if="openSwitch" class="u-m-b-20">
|
||||
<el-button
|
||||
@click="changeKey('paysSel', index)"
|
||||
v-for="(item, index) in pays"
|
||||
:key="index"
|
||||
:type="paysSel == index ? 'primary' : ''"
|
||||
>
|
||||
<el-button @click="changeKey('paysSel', index)" v-for="(item, index) in pays" :key="index"
|
||||
:type="paysSel == index ? 'primary' : ''">
|
||||
{{ item.text }}
|
||||
</el-button>
|
||||
</div>
|
||||
@@ -21,13 +17,8 @@
|
||||
<el-input :value="form.money" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="付款码">
|
||||
<el-input
|
||||
v-model="form.code"
|
||||
@change="codeInputChange"
|
||||
autofocus
|
||||
placeholder="请扫码或者输入付款码"
|
||||
ref="refInputCode"
|
||||
></el-input>
|
||||
<el-input v-model="form.code" @change="inputChange" autofocus placeholder="请扫码或者输入付款码"
|
||||
ref="refInputCode"></el-input>
|
||||
</el-form-item>
|
||||
<div class="u-flex u-row-center u-m-t-50">
|
||||
<el-button @click="close">取消</el-button>
|
||||
@@ -46,7 +37,9 @@
|
||||
</div>
|
||||
<div class="color-333 u-font-20 u-m-t-20">{{ form.money }}元</div>
|
||||
<div class="color-aaa u-font-12 u-m-t-10">
|
||||
<el-icon class="loading-ani"><Loading /></el-icon>
|
||||
<el-icon class="loading-ani">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
<span>等待用户支付</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +48,8 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
import QRCode from "qrcode";
|
||||
import orderApi from "@/api/order/order";
|
||||
import payApi from "@/api/order/pay";
|
||||
@@ -128,6 +122,9 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
inputChange: _.debounce(function (e) {
|
||||
this.confirm();
|
||||
}, 100),
|
||||
to2(n) {
|
||||
return n.toFixed(2);
|
||||
},
|
||||
@@ -175,7 +172,6 @@ export default {
|
||||
changeKey(key, val) {
|
||||
this[key] = val;
|
||||
},
|
||||
|
||||
confirm() {
|
||||
if (!this.form.code) {
|
||||
return ElMessage.error("请输入或扫付款码");
|
||||
@@ -239,14 +235,15 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.codeImg {
|
||||
width: 164px;
|
||||
border: 1px solid rgb(220, 223, 230);
|
||||
height: 164px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@keyframes rotating {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
@@ -258,6 +255,7 @@ export default {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-ani {
|
||||
animation: rotating 2s linear infinite;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ const contentConfig: IContentConfig<any> = {
|
||||
{
|
||||
label: "消费次数累计",
|
||||
align: "center",
|
||||
prop: "consumeAmount",
|
||||
prop: "consumeCount",
|
||||
},
|
||||
{
|
||||
label: "注册时间",
|
||||
|
||||
Reference in New Issue
Block a user