|
|
@@ -14,8 +14,13 @@
|
|
|
</view>
|
|
|
<view class="header-toolbar">
|
|
|
<view class="filter-tabs">
|
|
|
- <view class="tab-item" v-for="(tab, index) in timeFilters" :key="index"
|
|
|
- :class="{ active: currentFilter === tab.value }" @click="switchFilter(tab.value)">
|
|
|
+ <view
|
|
|
+ class="tab-item"
|
|
|
+ v-for="(tab, index) in timeFilters"
|
|
|
+ :key="index"
|
|
|
+ :class="{ active: currentFilter === tab.value }"
|
|
|
+ @click="switchFilter(tab.value)"
|
|
|
+ >
|
|
|
{{ tab.label }}
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -24,26 +29,41 @@
|
|
|
<text class="selector-text">{{
|
|
|
selectedProvince || "全部省份"
|
|
|
}}</text>
|
|
|
- <text class="selector-arrow" :class="{ open: dropdownProvinceOpen }"></text>
|
|
|
+ <text
|
|
|
+ class="selector-arrow"
|
|
|
+ :class="{ open: dropdownProvinceOpen }"
|
|
|
+ ></text>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
</view>
|
|
|
<!-- 背景装饰 -->
|
|
|
<view class="header-circle circle-1"></view>
|
|
|
<view class="header-circle circle-2"></view>
|
|
|
</view>
|
|
|
|
|
|
- <scroll-view class="list-scroll" scroll-y="true" refresher-enabled :refresher-triggered="isRefreshing"
|
|
|
- @refresherrefresh="onRefresh">
|
|
|
+ <scroll-view
|
|
|
+ class="list-scroll"
|
|
|
+ scroll-y="true"
|
|
|
+ refresher-enabled
|
|
|
+ :refresher-triggered="isRefreshing"
|
|
|
+ @refresherrefresh="onRefresh"
|
|
|
+ >
|
|
|
<view class="list-container">
|
|
|
- <view class="date-group" v-for="groupItem in groupedRows" :key="groupItem.date">
|
|
|
+ <view
|
|
|
+ class="date-group"
|
|
|
+ v-for="groupItem in groupedRows"
|
|
|
+ :key="groupItem.date"
|
|
|
+ >
|
|
|
<view class="date-group-card">
|
|
|
<view class="group-left">
|
|
|
- <view class="group-select-btn" :class="{
|
|
|
- selected: isGroupFullySelected(groupItem),
|
|
|
- partial: isGroupPartiallySelected(groupItem),
|
|
|
- }" @click.stop="toggleGroupSelection(groupItem)">
|
|
|
+ <view
|
|
|
+ class="group-select-btn"
|
|
|
+ :class="{
|
|
|
+ selected: isGroupFullySelected(groupItem),
|
|
|
+ partial: isGroupPartiallySelected(groupItem),
|
|
|
+ }"
|
|
|
+ @click.stop="toggleGroupSelection(groupItem)"
|
|
|
+ >
|
|
|
<text v-if="isGroupFullySelected(groupItem)">✓</text>
|
|
|
<text v-else-if="isGroupPartiallySelected(groupItem)">-</text>
|
|
|
</view>
|
|
|
@@ -51,12 +71,19 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
- <view class="card-item" v-for="(item, index) in groupItem.list" :key="item.__selectId || index"
|
|
|
- @click="toDetail(item)">
|
|
|
+ <view
|
|
|
+ class="card-item"
|
|
|
+ v-for="(item, index) in groupItem.list"
|
|
|
+ :key="item.__selectId || index"
|
|
|
+ @click="toDetail(item)"
|
|
|
+ >
|
|
|
<view class="card-header">
|
|
|
<view class="header-left">
|
|
|
- <view class="company-select-btn" :class="{ selected: isCompanySelected(item) }"
|
|
|
- @click.stop="toggleCompanySelection(item)">
|
|
|
+ <view
|
|
|
+ class="company-select-btn"
|
|
|
+ :class="{ selected: isCompanySelected(item) }"
|
|
|
+ @click.stop="toggleCompanySelection(item)"
|
|
|
+ >
|
|
|
<text v-if="isCompanySelected(item)">✓</text>
|
|
|
</view>
|
|
|
<text class="company-name">{{ item.queryCustomer }}</text>
|
|
|
@@ -94,35 +121,69 @@
|
|
|
</view>
|
|
|
|
|
|
<!-- 蒙层 -->
|
|
|
- <view class="report-export-create-modal-mask" v-if="emailModalOpen" @click="closeEmailModal"
|
|
|
- @touchmove.stop.prevent></view>
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-mask"
|
|
|
+ v-if="emailModalOpen"
|
|
|
+ @click="closeEmailModal"
|
|
|
+ @touchmove.stop.prevent
|
|
|
+ ></view>
|
|
|
|
|
|
<!-- 邮箱导出弹窗 -->
|
|
|
- <view class="report-export-create-modal report-export-create-email-modal"
|
|
|
- :class="{ 'report-export-create-modal--open': emailModalOpen }" v-if="emailModalOpen">
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal report-export-create-email-modal"
|
|
|
+ :class="{ 'report-export-create-modal--open': emailModalOpen }"
|
|
|
+ v-if="emailModalOpen"
|
|
|
+ >
|
|
|
<view class="report-export-create-modal-title">
|
|
|
<text>发送至邮箱</text>
|
|
|
- <view class="report-export-create-modal-close" @click.stop="closeEmailModal">×</view>
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-close"
|
|
|
+ @click.stop="closeEmailModal"
|
|
|
+ >×</view
|
|
|
+ >
|
|
|
</view>
|
|
|
- <view class="report-export-create-modal-body" :style="{ padding: '40rpx' }">
|
|
|
- <up-input v-model="emailForm.email" border="none" :customStyle="{
|
|
|
- backgroundColor: '#ebf3fb',
|
|
|
- height: '80rpx',
|
|
|
- paddingLeft: '20rpx',
|
|
|
- }" placeholder="请填写邮箱" @input="emailError = false" disabled>
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-body"
|
|
|
+ :style="{ padding: '40rpx' }"
|
|
|
+ >
|
|
|
+ <up-input
|
|
|
+ v-model="emailForm.email"
|
|
|
+ border="none"
|
|
|
+ :customStyle="{
|
|
|
+ backgroundColor: '#ebf3fb',
|
|
|
+ height: '80rpx',
|
|
|
+ paddingLeft: '20rpx',
|
|
|
+ }"
|
|
|
+ placeholder="请填写邮箱"
|
|
|
+ @input="emailError = false"
|
|
|
+ disabled
|
|
|
+ >
|
|
|
<template #suffix>
|
|
|
<view style="margin-right: 20rpx; color: #666">@999.com.cn</view>
|
|
|
</template>
|
|
|
</up-input>
|
|
|
- <text v-if="emailError" class="report-export-error-text">请输入邮箱</text>
|
|
|
+ <text v-if="emailError" class="report-export-error-text"
|
|
|
+ >请输入邮箱</text
|
|
|
+ >
|
|
|
</view>
|
|
|
- <view class="report-export-create-modal-footer" :style="{
|
|
|
- padding: '20rpx 40rpx 40rpx',
|
|
|
- display: 'flex',
|
|
|
- 'justify-content': 'space-between',
|
|
|
- }">
|
|
|
- <view class="report-export-create-modal-btn cancel-btn" @click.stop="closeEmailModal">取消</view>
|
|
|
- <view class="report-export-create-modal-btn confirm-btn" @click.stop="handleSendEmail">发送</view>
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-footer"
|
|
|
+ :style="{
|
|
|
+ padding: '20rpx 40rpx 40rpx',
|
|
|
+ display: 'flex',
|
|
|
+ 'justify-content': 'space-between',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-btn cancel-btn"
|
|
|
+ @click.stop="closeEmailModal"
|
|
|
+ >取消</view
|
|
|
+ >
|
|
|
+ <view
|
|
|
+ class="report-export-create-modal-btn confirm-btn"
|
|
|
+ @click.stop="handleSendEmail"
|
|
|
+ >发送</view
|
|
|
+ >
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
@@ -130,17 +191,34 @@
|
|
|
<view class="dropdown-layer" v-if="dropdownProvinceOpen" @click.stop>
|
|
|
<view class="dropdown">
|
|
|
<view class="dropdown-search-bar">
|
|
|
- <input class="dropdown-search-input" v-model="provinceSearchText" @input="onProvinceSearch"
|
|
|
- placeholder="搜索省份..." placeholder-style="color: #999" />
|
|
|
+ <input
|
|
|
+ class="dropdown-search-input"
|
|
|
+ v-model="provinceSearchText"
|
|
|
+ @input="onProvinceSearch"
|
|
|
+ placeholder="搜索省份..."
|
|
|
+ placeholder-style="color: #999"
|
|
|
+ />
|
|
|
</view>
|
|
|
<scroll-view scroll-y="true" class="dropdown-scroll-view">
|
|
|
- <view class="dropdown-item" v-for="(p, i) in filteredProvinceList" :key="p || i" :class="{
|
|
|
- active: p === selectedProvince || (!selectedProvince && i === 0),
|
|
|
- }" @click.stop="selectProvince(p)">
|
|
|
+ <view
|
|
|
+ class="dropdown-item"
|
|
|
+ v-for="(p, i) in filteredProvinceList"
|
|
|
+ :key="p || i"
|
|
|
+ :class="{
|
|
|
+ active: p === selectedProvince || (!selectedProvince && i === 0),
|
|
|
+ }"
|
|
|
+ @click.stop="selectProvince(p)"
|
|
|
+ >
|
|
|
{{ p || "全部省份" }}
|
|
|
- <text v-if="p === selectedProvince || (!selectedProvince && i === 0)" class="check-mark">✓</text>
|
|
|
+ <text
|
|
|
+ v-if="p === selectedProvince || (!selectedProvince && i === 0)"
|
|
|
+ class="check-mark"
|
|
|
+ >✓</text
|
|
|
+ >
|
|
|
</view>
|
|
|
- <view v-if="filteredProvinceList.length === 0" class="dropdown-empty">暂无数据</view>
|
|
|
+ <view v-if="filteredProvinceList.length === 0" class="dropdown-empty"
|
|
|
+ >暂无数据</view
|
|
|
+ >
|
|
|
</scroll-view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -154,11 +232,10 @@ import BottomScrollTip from "../../../wigets/BottomScrollTip.vue";
|
|
|
import request from "../../../request/index.js";
|
|
|
import { formatDate, guid } from "../../../utils/utils.js";
|
|
|
|
|
|
-
|
|
|
export default {
|
|
|
components: {
|
|
|
EmptyView,
|
|
|
- BottomScrollTip
|
|
|
+ BottomScrollTip,
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
@@ -193,8 +270,8 @@ export default {
|
|
|
created() {
|
|
|
this.resetFetch();
|
|
|
this.getProviceList();
|
|
|
- const userEmail = uni.getStorageSync('traceCode_useremail')
|
|
|
- this.emailForm.email = userEmail
|
|
|
+ const userEmail = uni.getStorageSync("traceCode_useremail");
|
|
|
+ this.emailForm.email = userEmail;
|
|
|
},
|
|
|
methods: {
|
|
|
formatDate,
|
|
|
@@ -206,7 +283,13 @@ export default {
|
|
|
|
|
|
// 用于选择的唯一 key(优先 socialCreditCode)
|
|
|
getCompanyKey(item = {}) {
|
|
|
- return String(item.__selectId || item.socialCreditCode || item.id || item.queryCustomer || "");
|
|
|
+ return String(
|
|
|
+ item.__selectId ||
|
|
|
+ item.socialCreditCode ||
|
|
|
+ item.id ||
|
|
|
+ item.queryCustomer ||
|
|
|
+ "",
|
|
|
+ );
|
|
|
},
|
|
|
|
|
|
isCompanySelected(item) {
|
|
|
@@ -220,7 +303,9 @@ export default {
|
|
|
if (!key) return;
|
|
|
const has = this.selectedCompanyKeys.includes(key);
|
|
|
if (has) {
|
|
|
- this.selectedCompanyKeys = this.selectedCompanyKeys.filter((k) => k !== key);
|
|
|
+ this.selectedCompanyKeys = this.selectedCompanyKeys.filter(
|
|
|
+ (k) => k !== key,
|
|
|
+ );
|
|
|
} else {
|
|
|
this.selectedCompanyKeys = [...this.selectedCompanyKeys, key];
|
|
|
}
|
|
|
@@ -235,14 +320,18 @@ export default {
|
|
|
isGroupPartiallySelected(groupItem = {}) {
|
|
|
const list = Array.isArray(groupItem.list) ? groupItem.list : [];
|
|
|
if (!list.length) return false;
|
|
|
- const selectedCount = list.filter((it) => this.isCompanySelected(it)).length;
|
|
|
+ const selectedCount = list.filter((it) =>
|
|
|
+ this.isCompanySelected(it),
|
|
|
+ ).length;
|
|
|
return selectedCount > 0 && selectedCount < list.length;
|
|
|
},
|
|
|
|
|
|
toggleGroupSelection(groupItem = {}) {
|
|
|
const list = Array.isArray(groupItem.list) ? groupItem.list : [];
|
|
|
if (!list.length) return;
|
|
|
- const groupKeys = list.map((it) => this.getCompanyKey(it)).filter(Boolean);
|
|
|
+ const groupKeys = list
|
|
|
+ .map((it) => this.getCompanyKey(it))
|
|
|
+ .filter(Boolean);
|
|
|
if (!groupKeys.length) return;
|
|
|
|
|
|
const allSelected = groupKeys.every((k) =>
|
|
|
@@ -332,9 +421,9 @@ export default {
|
|
|
if (this.selectedCompanyKeys?.length === 0) {
|
|
|
uni.showToast({
|
|
|
title: "请选择要导出的企业",
|
|
|
- icon: 'none'
|
|
|
+ icon: "none",
|
|
|
});
|
|
|
- return
|
|
|
+ return;
|
|
|
}
|
|
|
this.emailModalOpen = true;
|
|
|
this.emailError = false;
|
|
|
@@ -345,7 +434,6 @@ export default {
|
|
|
},
|
|
|
|
|
|
handleSendEmail() {
|
|
|
-
|
|
|
if (!this.emailForm.email) {
|
|
|
this.emailError = true;
|
|
|
return;
|
|
|
@@ -357,44 +445,69 @@ export default {
|
|
|
}
|
|
|
uni.showLoading({ title: "发送中..." });
|
|
|
|
|
|
- const doSingleSend = async (taskId) => {
|
|
|
- return request("/report/sendemail", {
|
|
|
- taskId,
|
|
|
- emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
- path: "traceabilityReport/pages/blacklist/index.vue",
|
|
|
- });
|
|
|
+ const doSingleSend = async () => {
|
|
|
+ const keys = new Set(this.selectedCompanyKeys || []);
|
|
|
+ const selectedRows = (this.rows || []).filter((r) =>
|
|
|
+ keys.has(this.getCompanyKey(r)),
|
|
|
+ );
|
|
|
+ const emailDTOList = selectedRows.map((item) => ({
|
|
|
+ companyNameList: item.customerName.split(","),
|
|
|
+ statisticsDate: item.billTime,
|
|
|
+ taskId: item.taskId,
|
|
|
+ }));
|
|
|
+ return request(
|
|
|
+ "/api/email/send",
|
|
|
+ {
|
|
|
+ emailDTOList,
|
|
|
+ type: 0,
|
|
|
+ uid: uni.getStorageSync("userInfo").ldap,
|
|
|
+ emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
+ path: "traceabilityReport/pages/blacklist/index.vue",
|
|
|
+ },
|
|
|
+ "post",
|
|
|
+ );
|
|
|
};
|
|
|
|
|
|
const run = async () => {
|
|
|
- try {
|
|
|
- // 先尝试一次性传多个 taskId(后端若支持)
|
|
|
- const res = await request("/report/sendemail", {
|
|
|
- taskId: selectedTaskIds,
|
|
|
- emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
- path: "traceabilityReport/pages/blacklist/index.vue",
|
|
|
- });
|
|
|
- if (res?.code == 200) {
|
|
|
- uni.hideLoading();
|
|
|
- uni.showToast({ title: "发送成功", icon: "success" });
|
|
|
- this.closeEmailModal();
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- // ignore, fallback below
|
|
|
- }
|
|
|
+ // try {
|
|
|
+ // // 先尝试一次性传多个 taskId(后端若支持)
|
|
|
+ // const res = await request("/report/sendemail", {
|
|
|
+ // taskId: selectedTaskIds,
|
|
|
+ // emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
+ // path: "traceabilityReport/pages/blacklist/index.vue",
|
|
|
+ // });
|
|
|
+ // if (res?.code == 200) {
|
|
|
+ // uni.hideLoading();
|
|
|
+ // uni.showToast({ title: "发送成功", icon: "success" });
|
|
|
+ // this.closeEmailModal();
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // } catch (e) {
|
|
|
+ // // ignore, fallback below
|
|
|
+ // }
|
|
|
|
|
|
// 不支持 combinedTask:逐个发送
|
|
|
- for (let i = 0; i < selectedTaskIds.length; i++) {
|
|
|
- const taskId = selectedTaskIds[i];
|
|
|
- const r = await doSingleSend(taskId);
|
|
|
- if (r?.code != 200) {
|
|
|
- uni.hideLoading();
|
|
|
- uni.showToast({
|
|
|
- title: r?.msg || "发送失败",
|
|
|
- icon: "none",
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
+ // for (let i = 0; i < selectedTaskIds.length; i++) {
|
|
|
+ // const taskId = selectedTaskIds[i];
|
|
|
+ // const r = await doSingleSend(taskId);
|
|
|
+ // if (r?.code != 200) {
|
|
|
+ // uni.hideLoading();
|
|
|
+ // uni.showToast({
|
|
|
+ // title: r?.msg || "发送失败",
|
|
|
+ // icon: "none",
|
|
|
+ // });
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ const r = await doSingleSend();
|
|
|
+ if (r?.code != 200) {
|
|
|
+ uni.hideLoading();
|
|
|
+ uni.showToast({
|
|
|
+ title: r?.msg || "发送失败",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
uni.hideLoading();
|
|
|
@@ -418,7 +531,9 @@ export default {
|
|
|
if (!this.selectedProvince) {
|
|
|
this.rows = [...this.allRows];
|
|
|
} else {
|
|
|
- this.rows = this.allRows.filter(item => item.customerProvinceName === this.selectedProvince);
|
|
|
+ this.rows = this.allRows.filter(
|
|
|
+ (item) => item.customerProvinceName === this.selectedProvince,
|
|
|
+ );
|
|
|
}
|
|
|
this.totalCount = this.rows.length;
|
|
|
// 切换省份/刷新数据后,清空已选企业,避免“跨筛选脏选中”
|