|
@@ -18,21 +18,19 @@
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
<view class="header-toolbar">
|
|
<view class="header-toolbar">
|
|
|
- <view class="update-tip">
|
|
|
|
|
- <!-- <text class="tip-icon">🕒</text> -->
|
|
|
|
|
- <text>统计日期:{{
|
|
|
|
|
- formatDate(
|
|
|
|
|
- new Date().setDate(new Date().getDate() - 1),
|
|
|
|
|
- "YYYY-MM-DD",
|
|
|
|
|
- ) || "--"
|
|
|
|
|
- }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <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)">
|
|
|
|
|
+ {{ tab.label }}
|
|
|
|
|
+ </view>
|
|
|
|
|
+ </view>
|
|
|
<view class="filter-wrap">
|
|
<view class="filter-wrap">
|
|
|
<view class="selector" @click.stop="toggleProvinceDropdown">
|
|
<view class="selector" @click.stop="toggleProvinceDropdown">
|
|
|
<text class="selector-text">{{
|
|
<text class="selector-text">{{
|
|
|
selectedProvince || "全部省份"
|
|
selectedProvince || "全部省份"
|
|
|
- }}</text>
|
|
|
|
|
|
|
+ }}</text>
|
|
|
<text class="selector-arrow" :class="{ open: dropdownProvinceOpen }"></text>
|
|
<text class="selector-arrow" :class="{ open: dropdownProvinceOpen }"></text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -43,33 +41,53 @@
|
|
|
<scroll-view class="list-scroll" scroll-y="true" refresher-enabled :refresher-triggered="isRefreshing"
|
|
<scroll-view class="list-scroll" scroll-y="true" refresher-enabled :refresher-triggered="isRefreshing"
|
|
|
@refresherrefresh="onRefresh">
|
|
@refresherrefresh="onRefresh">
|
|
|
<view class="list-container">
|
|
<view class="list-container">
|
|
|
- <view class="card-item" v-for="(item, index) in rows" :key="index" @click="toDetail(item)">
|
|
|
|
|
- <view class="card-header">
|
|
|
|
|
- <view class="header-left">
|
|
|
|
|
- <text class="index-num">{{ index + 1 }}</text>
|
|
|
|
|
- <text class="company-name">{{ item.customerName }}</text>
|
|
|
|
|
- <text class="level-tag" :class="getLevelClass(item.customerLevel)">
|
|
|
|
|
- {{ item.customerLevel }}
|
|
|
|
|
- </text>
|
|
|
|
|
- </view>
|
|
|
|
|
- <view class="header-right">
|
|
|
|
|
- <text class="alert-count">{{ item.totalWarningAmount }}次预警</text>
|
|
|
|
|
|
|
+ <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)">
|
|
|
|
|
+ <text v-if="isGroupFullySelected(groupItem)">✓</text>
|
|
|
|
|
+ <text v-else-if="isGroupPartiallySelected(groupItem)">-</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="date-label">{{ groupItem.date }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
|
|
|
- <view class="card-body">
|
|
|
|
|
- <view class="info-grid">
|
|
|
|
|
- <view class="info-item">
|
|
|
|
|
- <text class="label">省份</text>
|
|
|
|
|
- <text class="value">{{ item.customerProvinceName ?? '--' }}</text>
|
|
|
|
|
|
|
+ <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)">
|
|
|
|
|
+ <text v-if="isCompanySelected(item)">✓</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <text class="index-num">{{ index + 1 }}</text>
|
|
|
|
|
+ <text class="company-name">{{ item.customerName }}</text>
|
|
|
|
|
+ <text class="level-tag" :class="getLevelClass(item.customerLevel)">
|
|
|
|
|
+ {{ item.customerLevel }}
|
|
|
|
|
+ </text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-item">
|
|
|
|
|
- <text class="label">责任人</text>
|
|
|
|
|
- <text class="value">{{ item.responsibleManager }}</text>
|
|
|
|
|
|
|
+ <view class="header-right">
|
|
|
|
|
+ <text class="alert-count">{{ item.totalWarningAmount }}次预警</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="info-item">
|
|
|
|
|
- <text class="label">性质</text>
|
|
|
|
|
- <text class="value">{{ item.customerCategory }}</text>
|
|
|
|
|
|
|
+ </view>
|
|
|
|
|
+
|
|
|
|
|
+ <view class="card-body">
|
|
|
|
|
+ <view class="info-grid">
|
|
|
|
|
+ <view class="info-item">
|
|
|
|
|
+ <text class="label">省份</text>
|
|
|
|
|
+ <text class="value">{{ item.customerProvinceName ?? '--' }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-item">
|
|
|
|
|
+ <text class="label">责任人</text>
|
|
|
|
|
+ <text class="value">{{ item.responsibleManager }}</text>
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="info-item">
|
|
|
|
|
+ <text class="label">性质</text>
|
|
|
|
|
+ <text class="value">{{ item.customerCategory }}</text>
|
|
|
|
|
+ </view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -83,9 +101,6 @@
|
|
|
|
|
|
|
|
<!-- 底部按钮区 -->
|
|
<!-- 底部按钮区 -->
|
|
|
<view class="footer-btn-area">
|
|
<view class="footer-btn-area">
|
|
|
- <button class="action-btn history-btn" @click="handleHistory">
|
|
|
|
|
- 历史记录
|
|
|
|
|
- </button>
|
|
|
|
|
<button class="action-btn export-btn" @click="handleExport">
|
|
<button class="action-btn export-btn" @click="handleExport">
|
|
|
导出至邮箱
|
|
导出至邮箱
|
|
|
</button>
|
|
</button>
|
|
@@ -139,16 +154,19 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
|
|
+ <BottomScrollTip :text="'下滑动查看更多内容'" :bottom="'140rpx'" />
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
import EmptyView from "../../../wigets/empty.vue";
|
|
import EmptyView from "../../../wigets/empty.vue";
|
|
|
import request from "../../../request/index.js";
|
|
import request from "../../../request/index.js";
|
|
|
-import { formatDate } from "../../../utils/utils.js";
|
|
|
|
|
|
|
+import BottomScrollTip from "../../../wigets/BottomScrollTip.vue";
|
|
|
|
|
+import { formatDate, guid } from "../../../utils/utils.js";
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
|
components: {
|
|
components: {
|
|
|
EmptyView,
|
|
EmptyView,
|
|
|
|
|
+ BottomScrollTip
|
|
|
},
|
|
},
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
@@ -160,12 +178,21 @@ export default {
|
|
|
provinceSearchText: "",
|
|
provinceSearchText: "",
|
|
|
provinceList: [""],
|
|
provinceList: [""],
|
|
|
selectedProvince: "",
|
|
selectedProvince: "",
|
|
|
|
|
+ currentFilter: "all",
|
|
|
|
|
+ timeFilters: [
|
|
|
|
|
+ { label: "全部", value: "all" },
|
|
|
|
|
+ { label: "近7天", value: "7" },
|
|
|
|
|
+ { label: "近15天", value: "15" },
|
|
|
|
|
+ { label: "近30天", value: "30" },
|
|
|
|
|
+ ],
|
|
|
totalCount: 0,
|
|
totalCount: 0,
|
|
|
emailModalOpen: false,
|
|
emailModalOpen: false,
|
|
|
emailForm: {
|
|
emailForm: {
|
|
|
email: "",
|
|
email: "",
|
|
|
},
|
|
},
|
|
|
emailError: false,
|
|
emailError: false,
|
|
|
|
|
+ // 多选导出选择状态:存每条记录的唯一 __selectId
|
|
|
|
|
+ selectedCompanyKeys: [],
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
|
created() {
|
|
created() {
|
|
@@ -177,6 +204,78 @@ export default {
|
|
|
methods: {
|
|
methods: {
|
|
|
formatDate,
|
|
formatDate,
|
|
|
|
|
|
|
|
|
|
+ switchFilter(value) {
|
|
|
|
|
+ if (this.currentFilter === value) return;
|
|
|
|
|
+ this.currentFilter = value;
|
|
|
|
|
+ this.resetFetch();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 选择的唯一 key(由列表接口注入 __selectId)
|
|
|
|
|
+ getCompanyKey(item = {}) {
|
|
|
|
|
+ return String(item.__selectId || "");
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ isCompanySelected(item) {
|
|
|
|
|
+ const key = this.getCompanyKey(item);
|
|
|
|
|
+ if (!key) return false;
|
|
|
|
|
+ return (this.selectedCompanyKeys || []).includes(key);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ toggleCompanySelection(item) {
|
|
|
|
|
+ const key = this.getCompanyKey(item);
|
|
|
|
|
+ if (!key) return;
|
|
|
|
|
+ const has = this.isCompanySelected(item);
|
|
|
|
|
+ if (has) {
|
|
|
|
|
+ this.selectedCompanyKeys = (this.selectedCompanyKeys || []).filter(
|
|
|
|
|
+ (k) => k !== key,
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.selectedCompanyKeys = [
|
|
|
|
|
+ ...(this.selectedCompanyKeys || []),
|
|
|
|
|
+ key,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ isGroupFullySelected(groupItem = {}) {
|
|
|
|
|
+ const list = Array.isArray(groupItem.list) ? groupItem.list : [];
|
|
|
|
|
+ if (!list.length) return false;
|
|
|
|
|
+ return list.every((it) => this.isCompanySelected(it));
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ isGroupPartiallySelected(groupItem = {}) {
|
|
|
|
|
+ const list = Array.isArray(groupItem.list) ? groupItem.list : [];
|
|
|
|
|
+ if (!list.length) return false;
|
|
|
|
|
+ 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);
|
|
|
|
|
+ if (!groupKeys.length) return;
|
|
|
|
|
+
|
|
|
|
|
+ const allSelected = groupKeys.every((k) =>
|
|
|
|
|
+ (this.selectedCompanyKeys || []).includes(k),
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (allSelected) {
|
|
|
|
|
+ this.selectedCompanyKeys = (this.selectedCompanyKeys || []).filter(
|
|
|
|
|
+ (k) => !groupKeys.includes(k),
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const merged = new Set([...(this.selectedCompanyKeys || []), ...groupKeys]);
|
|
|
|
|
+ this.selectedCompanyKeys = Array.from(merged);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ getUpdatedDate(fullTime) {
|
|
|
|
|
+ const t = String(fullTime || "");
|
|
|
|
|
+ if (!t) return "未知日期";
|
|
|
|
|
+ return t.split(" ")[0] || t.split("T")[0] || "未知日期";
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
getProviceList() {
|
|
getProviceList() {
|
|
|
request("/common/getProviceList", {
|
|
request("/common/getProviceList", {
|
|
|
path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
@@ -199,15 +298,19 @@ export default {
|
|
|
if (this.loading) return;
|
|
if (this.loading) return;
|
|
|
this.loading = true;
|
|
this.loading = true;
|
|
|
|
|
|
|
|
|
|
+ const days = this.currentFilter === "all" ? -1 : this.currentFilter;
|
|
|
request(
|
|
request(
|
|
|
- `/report/ganmaoling/list?days=1`,
|
|
|
|
|
|
|
+ `/report/ganmaoling/list?days=${days}`,
|
|
|
{
|
|
{
|
|
|
path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
|
},
|
|
},
|
|
|
"get",
|
|
"get",
|
|
|
).then((res) => {
|
|
).then((res) => {
|
|
|
if (res.code == 200) {
|
|
if (res.code == 200) {
|
|
|
- this.allRows = res.data || [];
|
|
|
|
|
|
|
+ this.allRows = (res.data || []).map((it) => ({
|
|
|
|
|
+ ...it,
|
|
|
|
|
+ __selectId: it?.__selectId || guid("glm_"),
|
|
|
|
|
+ }));
|
|
|
this.applyFilter();
|
|
this.applyFilter();
|
|
|
}
|
|
}
|
|
|
this.loading = false;
|
|
this.loading = false;
|
|
@@ -222,6 +325,7 @@ export default {
|
|
|
|
|
|
|
|
resetFetch() {
|
|
resetFetch() {
|
|
|
this.rows = [];
|
|
this.rows = [];
|
|
|
|
|
+ this.selectedCompanyKeys = [];
|
|
|
this.fetchList();
|
|
this.fetchList();
|
|
|
},
|
|
},
|
|
|
|
|
|
|
@@ -232,6 +336,8 @@ export default {
|
|
|
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;
|
|
this.totalCount = this.rows.length;
|
|
|
|
|
+ // 切换筛选条件后清空已选企业,避免脏选中
|
|
|
|
|
+ this.selectedCompanyKeys = [];
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
toggleProvinceDropdown() {
|
|
toggleProvinceDropdown() {
|
|
@@ -255,9 +361,9 @@ export default {
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
handleExport() {
|
|
handleExport() {
|
|
|
- if (this.rows.length == 0) {
|
|
|
|
|
|
|
+ if ((this.selectedCompanyKeys || []).length === 0) {
|
|
|
uni.showToast({
|
|
uni.showToast({
|
|
|
- title: '暂无数据...',
|
|
|
|
|
|
|
+ title: '请选择要导出的企业',
|
|
|
icon: 'none'
|
|
icon: 'none'
|
|
|
})
|
|
})
|
|
|
return
|
|
return
|
|
@@ -270,49 +376,73 @@ export default {
|
|
|
this.emailModalOpen = false;
|
|
this.emailModalOpen = false;
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
- handleSendEmail() {
|
|
|
|
|
|
|
+ async handleSendEmail() {
|
|
|
if (!this.emailForm.email) {
|
|
if (!this.emailForm.email) {
|
|
|
this.emailError = true;
|
|
this.emailError = true;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
- uni.showLoading({ title: "发送中..." });
|
|
|
|
|
|
|
+ const selectedRows = (this.rows || []).filter((r) =>
|
|
|
|
|
+ (this.selectedCompanyKeys || []).includes(this.getCompanyKey(r)),
|
|
|
|
|
+ );
|
|
|
|
|
+ const selectedDates = Array.from(
|
|
|
|
|
+ new Set(selectedRows.map((r) => this.getUpdatedDate(r.updatedTime))),
|
|
|
|
|
+ ).filter(Boolean);
|
|
|
|
|
|
|
|
- const yesterday = new Date();
|
|
|
|
|
- yesterday.setDate(yesterday.getDate() - 1);
|
|
|
|
|
- const dateStr = this.formatDate(yesterday, "YYYY-MM-DD");
|
|
|
|
|
|
|
+ if (!selectedDates.length) {
|
|
|
|
|
+ uni.showToast({ title: "未找到可导出的日期", icon: "none" });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- request(
|
|
|
|
|
- `/report/ganmaoling/sendemail`,
|
|
|
|
|
- {
|
|
|
|
|
- updatedTime: dateStr,
|
|
|
|
|
- emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
|
|
- path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
|
|
|
- },
|
|
|
|
|
- "post",
|
|
|
|
|
- ).then((res) => {
|
|
|
|
|
- uni.hideLoading();
|
|
|
|
|
- if (res.code == 200) {
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: "发送成功",
|
|
|
|
|
- icon: "success",
|
|
|
|
|
- });
|
|
|
|
|
- this.closeEmailModal();
|
|
|
|
|
- } else {
|
|
|
|
|
- uni.showToast({
|
|
|
|
|
- title: res.msg || "发送失败",
|
|
|
|
|
- icon: "none",
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ uni.showLoading({ title: "发送中..." });
|
|
|
|
|
+ try {
|
|
|
|
|
+ for (let i = 0; i < selectedDates.length; i++) {
|
|
|
|
|
+ const dateStr = selectedDates[i];
|
|
|
|
|
+ const res = await request(
|
|
|
|
|
+ `/report/ganmaoling/sendemail`,
|
|
|
|
|
+ {
|
|
|
|
|
+ updatedTime: dateStr,
|
|
|
|
|
+ emailAddress: this.emailForm.email + "@999.com.cn",
|
|
|
|
|
+ path: "traceabilityReport/pages/ganmaoling/index.vue",
|
|
|
|
|
+ },
|
|
|
|
|
+ "post",
|
|
|
|
|
+ );
|
|
|
|
|
+ if (res?.code != 200) {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ uni.showToast({
|
|
|
|
|
+ title: res?.msg || "发送失败",
|
|
|
|
|
+ icon: "none",
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- });
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
- handleHistory() {
|
|
|
|
|
- uni.navigateTo({
|
|
|
|
|
- url: "/traceCodePackages/traceabilityReport/pages/ganmaoling/history/index",
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ uni.showToast({ title: "发送成功", icon: "success" });
|
|
|
|
|
+ this.closeEmailModal();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ uni.hideLoading();
|
|
|
|
|
+ uni.showToast({ title: "发送失败", icon: "none" });
|
|
|
|
|
+ }
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
computed: {
|
|
computed: {
|
|
|
|
|
+ groupedRows() {
|
|
|
|
|
+ const groups = {};
|
|
|
|
|
+ (this.rows || []).forEach((item) => {
|
|
|
|
|
+ const date = this.getUpdatedDate(item.updatedTime);
|
|
|
|
|
+ if (!groups[date]) groups[date] = [];
|
|
|
|
|
+ groups[date].push(item);
|
|
|
|
|
+ });
|
|
|
|
|
+ return Object.keys(groups)
|
|
|
|
|
+ .sort(
|
|
|
|
|
+ (a, b) =>
|
|
|
|
|
+ new Date(String(b).replace(/-/g, "/")).getTime() -
|
|
|
|
|
+ new Date(String(a).replace(/-/g, "/")).getTime(),
|
|
|
|
|
+ )
|
|
|
|
|
+ .map((date) => ({
|
|
|
|
|
+ date,
|
|
|
|
|
+ list: groups[date],
|
|
|
|
|
+ }));
|
|
|
|
|
+ },
|
|
|
filteredProvinceList() {
|
|
filteredProvinceList() {
|
|
|
if (!this.provinceSearchText) {
|
|
if (!this.provinceSearchText) {
|
|
|
return this.provinceList;
|
|
return this.provinceList;
|
|
@@ -415,6 +545,7 @@ export default {
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
position: relative;
|
|
position: relative;
|
|
|
z-index: 3;
|
|
z-index: 3;
|
|
|
|
|
+ gap: 20rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.update-tip {
|
|
.update-tip {
|
|
@@ -470,6 +601,107 @@ export default {
|
|
|
transform: rotate(180deg);
|
|
transform: rotate(180deg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* Header date filter tabs */
|
|
|
|
|
+.filter-tabs {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ background: rgba(255, 255, 255, 0.2);
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ padding: 6rpx 6rpx;
|
|
|
|
|
+ z-index: 30;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ max-width: 420rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tab-item {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ font-size: 24rpx;
|
|
|
|
|
+ padding: 10rpx 0;
|
|
|
|
|
+ border-radius: 12rpx;
|
|
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
|
|
+ transition: all 0.3s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.tab-item.active {
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ color: #2b32b2;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Date-group (history style) */
|
|
|
|
|
+.date-group {
|
|
|
|
|
+ margin-bottom: 40rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.date-group-card {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: flex-start;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ padding: 16rpx 22rpx;
|
|
|
|
|
+ border-radius: 16rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.03);
|
|
|
|
|
+ border-left: 6rpx solid #1488cc;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.group-left {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.date-label {
|
|
|
|
|
+ font-size: 28rpx;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.group-select-btn {
|
|
|
|
|
+ width: 36rpx;
|
|
|
|
|
+ height: 36rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ border: 2rpx solid #1488cc;
|
|
|
|
|
+ color: #1488cc;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ background: rgba(20, 136, 204, 0.06);
|
|
|
|
|
+ margin-right: 14rpx;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.group-select-btn.selected {
|
|
|
|
|
+ background: #1488cc;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.group-select-btn.partial {
|
|
|
|
|
+ background: rgba(20, 136, 204, 0.15);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.company-select-btn {
|
|
|
|
|
+ width: 36rpx;
|
|
|
|
|
+ height: 36rpx;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ border: 2rpx solid #d0d7e2;
|
|
|
|
|
+ color: #d0d7e2;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ margin-right: 12rpx;
|
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
|
+ background: #fff;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.company-select-btn.selected {
|
|
|
|
|
+ border-color: #1488cc;
|
|
|
|
|
+ color: #1488cc;
|
|
|
|
|
+ background: rgba(20, 136, 204, 0.08);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* Dropdown Layer (Absolute on top of everything) */
|
|
/* Dropdown Layer (Absolute on top of everything) */
|
|
|
.dropdown-layer {
|
|
.dropdown-layer {
|
|
|
position: absolute;
|
|
position: absolute;
|
|
@@ -556,8 +788,8 @@ export default {
|
|
|
.card-item {
|
|
.card-item {
|
|
|
background: #fff;
|
|
background: #fff;
|
|
|
border-radius: 20rpx;
|
|
border-radius: 20rpx;
|
|
|
- padding: 30rpx;
|
|
|
|
|
- margin-bottom: 24rpx;
|
|
|
|
|
|
|
+ padding: 26rpx 22rpx;
|
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.05);
|
|
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.05);
|
|
|
transition: transform 0.2s;
|
|
transition: transform 0.2s;
|
|
|
}
|
|
}
|
|
@@ -569,23 +801,25 @@ export default {
|
|
|
.card-header {
|
|
.card-header {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
justify-content: space-between;
|
|
|
- align-items: flex-start;
|
|
|
|
|
- margin-bottom: 24rpx;
|
|
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ margin-bottom: 16rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.header-left {
|
|
.header-left {
|
|
|
flex: 1;
|
|
flex: 1;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- flex-wrap: wrap;
|
|
|
|
|
|
|
+ flex-wrap: nowrap;
|
|
|
margin-right: 20rpx;
|
|
margin-right: 20rpx;
|
|
|
- gap: 12rpx;
|
|
|
|
|
|
|
+ gap: 0;
|
|
|
|
|
+ min-width: 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.index-num {
|
|
.index-num {
|
|
|
font-size: 24rpx;
|
|
font-size: 24rpx;
|
|
|
color: #999;
|
|
color: #999;
|
|
|
font-family: monospace;
|
|
font-family: monospace;
|
|
|
|
|
+ margin-right: 12rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.company-name {
|
|
.company-name {
|
|
@@ -594,6 +828,7 @@ export default {
|
|
|
color: #096dd9;
|
|
color: #096dd9;
|
|
|
line-height: 1.4;
|
|
line-height: 1.4;
|
|
|
text-decoration: underline;
|
|
text-decoration: underline;
|
|
|
|
|
+ margin-right: 8rpx;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.level-tag {
|
|
.level-tag {
|