|
|
@@ -5,15 +5,17 @@
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
|
<title>质保卡</title>
|
|
|
+ <script>window.API_URL = location.port === '3003' ? '/api/proxy' : (location.origin + '/yos/rest/index');</script>
|
|
|
<script src="./file/axios.min.js"></script>
|
|
|
<script src="./file/vue.min.js"></script>
|
|
|
<link rel="stylesheet" href="./file/index.css">
|
|
|
<script src="./file/vant.min.js"></script>
|
|
|
<link rel="stylesheet" href="./file/style.css">
|
|
|
+ <script src="./file/login-auth.js"></script>
|
|
|
<style>
|
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
|
body {
|
|
|
- background-color: #f5f5f5;
|
|
|
+ background-color: #f5f6fa;
|
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', sans-serif;
|
|
|
color: #333;
|
|
|
}
|
|
|
@@ -21,6 +23,7 @@
|
|
|
max-width: 750px;
|
|
|
margin: 0 auto;
|
|
|
min-height: 100vh;
|
|
|
+ background-color: #f5f6fa;
|
|
|
}
|
|
|
/* 顶部导航 */
|
|
|
.nav-bar {
|
|
|
@@ -48,10 +51,49 @@
|
|
|
height: 20px;
|
|
|
fill: #333;
|
|
|
}
|
|
|
+ .nav-bar .nav-right {
|
|
|
+ gap: 16px;
|
|
|
+ }
|
|
|
.nav-bar .nav-title {
|
|
|
font-size: 17px;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
+ /* 搜索栏 */
|
|
|
+ .search-bar {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px 12px;
|
|
|
+ background-color: #fff;
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ }
|
|
|
+ .search-input-wrap {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 6px 10px;
|
|
|
+ }
|
|
|
+ .search-input-wrap svg {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ fill: #999;
|
|
|
+ margin-right: 6px;
|
|
|
+ }
|
|
|
+ .search-input-wrap input {
|
|
|
+ flex: 1;
|
|
|
+ border: none;
|
|
|
+ background: transparent;
|
|
|
+ outline: none;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ .search-cancel {
|
|
|
+ margin-left: 12px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #1989fa;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
/* 标签页 */
|
|
|
.tabs {
|
|
|
display: flex;
|
|
|
@@ -61,6 +103,7 @@
|
|
|
border-bottom: 1px solid #eee;
|
|
|
}
|
|
|
.tab-item {
|
|
|
+ flex:1;
|
|
|
height: 44px;
|
|
|
line-height: 44px;
|
|
|
font-size: 16px;
|
|
|
@@ -68,6 +111,7 @@
|
|
|
margin-right: 30px;
|
|
|
cursor: pointer;
|
|
|
position: relative;
|
|
|
+ text-align: center;
|
|
|
}
|
|
|
.tab-item.active {
|
|
|
color: #1989fa;
|
|
|
@@ -84,19 +128,116 @@
|
|
|
background: #1989fa;
|
|
|
border-radius: 2px;
|
|
|
}
|
|
|
- .search-icon {
|
|
|
- margin-left: auto;
|
|
|
- padding-left: 16px;
|
|
|
+ /* 筛选弹窗 */
|
|
|
+ .filter-mask {
|
|
|
+ position: fixed;
|
|
|
+ top: 0; left: 0; right: 0; bottom: 0;
|
|
|
+ background: rgba(0,0,0,0.5);
|
|
|
+ z-index: 999;
|
|
|
}
|
|
|
- .search-icon svg {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- fill: #666;
|
|
|
+ .filter-panel {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ width: 85%;
|
|
|
+ max-width: 350px;
|
|
|
+ background: #fff;
|
|
|
+ box-shadow: -2px 0 8px rgba(0,0,0,0.1);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ z-index: 1000;
|
|
|
+ transform: translateX(100%);
|
|
|
+ transition: transform 0.3s ease;
|
|
|
+ }
|
|
|
+ .filter-panel.show {
|
|
|
+ transform: translateX(0);
|
|
|
+ }
|
|
|
+ .filter-header {
|
|
|
+ padding: 16px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ }
|
|
|
+ .filter-header span { font-size: 17px; font-weight: 600; }
|
|
|
+ .filter-close { font-size: 24px; color: #999; cursor: pointer; }
|
|
|
+ .filter-body {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 16px;
|
|
|
+ }
|
|
|
+ .filter-section {
|
|
|
+ margin-bottom: 24px;
|
|
|
+ }
|
|
|
+ .filter-section-title {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ }
|
|
|
+ .filter-tags {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 10px;
|
|
|
+ }
|
|
|
+ .tag-item {
|
|
|
+ padding: 8px 16px;
|
|
|
+ background: #f5f5f5;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .tag-item.active {
|
|
|
+ background: #1989fa;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ .filter-date-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+ }
|
|
|
+ .filter-date-row input {
|
|
|
+ flex: 1;
|
|
|
+ padding: 10px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ .filter-date-row span { color: #999; }
|
|
|
+ .filter-footer {
|
|
|
+ display: flex;
|
|
|
+ padding: 16px;
|
|
|
+ gap: 12px;
|
|
|
+ border-top: 1px solid #eee;
|
|
|
+ }
|
|
|
+ .btn-reset {
|
|
|
+ flex: 1;
|
|
|
+ text-align: center;
|
|
|
+ padding: 12px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #1989fa;
|
|
|
+ font-size: 15px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .btn-confirm {
|
|
|
+ flex: 1;
|
|
|
+ text-align: center;
|
|
|
+ padding: 12px;
|
|
|
+ background: #1989fa;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 15px;
|
|
|
+ cursor: pointer;
|
|
|
}
|
|
|
/* 列表内容 */
|
|
|
.list-container {
|
|
|
padding: 12px;
|
|
|
- background: #f5f5f5;
|
|
|
+ background: #f5f6fa;
|
|
|
min-height: calc(100vh - 88px);
|
|
|
}
|
|
|
.card {
|
|
|
@@ -104,7 +245,7 @@
|
|
|
border-radius: 8px;
|
|
|
padding: 16px;
|
|
|
margin-bottom: 12px;
|
|
|
- box-shadow: 0 1px 4px rgba(0,0,0,0.03);
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
|
|
}
|
|
|
.card-header {
|
|
|
display: flex;
|
|
|
@@ -138,10 +279,12 @@
|
|
|
}
|
|
|
.card-info-label {
|
|
|
flex-shrink: 0;
|
|
|
+ width: 70px;
|
|
|
}
|
|
|
.card-info-value {
|
|
|
color: #333;
|
|
|
word-break: break-all;
|
|
|
+ flex: 1;
|
|
|
}
|
|
|
.card-info-value.blue {
|
|
|
color: #1989fa;
|
|
|
@@ -149,6 +292,13 @@
|
|
|
.card-info-value.phone {
|
|
|
color: #1989fa;
|
|
|
margin-left: 10px;
|
|
|
+ text-decoration: none;
|
|
|
+ }
|
|
|
+ .empty-state {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40px 0;
|
|
|
+ color: #999;
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
</style>
|
|
|
</head>
|
|
|
@@ -162,17 +312,24 @@
|
|
|
</div>
|
|
|
<div class="nav-title">质保卡</div>
|
|
|
<div class="nav-right">
|
|
|
- <svg viewBox="0 0 24 24"><path d="M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></svg>
|
|
|
+ <svg @click="showSearch = true" viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
|
|
+ <svg @click="showFilter = true" viewBox="0 0 24 24"><path d="M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z"/></svg>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 标签页 -->
|
|
|
- <div class="tabs">
|
|
|
- <div class="tab-item" :class="{ active: activeTab === 'active' }" @click="activeTab = 'active'">生效中</div>
|
|
|
- <div class="tab-item" :class="{ active: activeTab === 'expired' }" @click="activeTab = 'expired'">已到期</div>
|
|
|
- <div class="search-icon">
|
|
|
+ <!-- 搜索栏 -->
|
|
|
+ <div class="search-bar" v-show="showSearch">
|
|
|
+ <div class="search-input-wrap">
|
|
|
<svg viewBox="0 0 24 24"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>
|
|
|
+ <input type="text" v-model="searchKey" placeholder="请输入关键词搜索" @keyup.enter="onSearch" />
|
|
|
</div>
|
|
|
+ <div class="search-cancel" @click="showSearch = false; searchKey = ''; getData();">取消</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 标签页 -->
|
|
|
+ <div class="tabs">
|
|
|
+ <div class="tab-item" :class="{ active: activeTab === 'active' }" @click="changeTab('active')">生效中</div>
|
|
|
+ <div class="tab-item" :class="{ active: activeTab === 'expired' }" @click="changeTab('expired')">已到期</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 列表容器 -->
|
|
|
@@ -180,7 +337,7 @@
|
|
|
<!-- 质保卡列表 -->
|
|
|
<div class="card" v-for="(item, index) in filteredList" :key="index">
|
|
|
<div class="card-header">
|
|
|
- <span class="card-id">{{ item.billno }}</span>
|
|
|
+ <span class="card-id">{{ item.cardno }}</span>
|
|
|
<span class="card-status" :class="{ active: item.status === '生效中', expired: item.status === '已到期' }">{{ item.status }}</span>
|
|
|
</div>
|
|
|
<div class="card-info-row">
|
|
|
@@ -196,19 +353,62 @@
|
|
|
<span class="card-info-value">{{ item.province }}{{ item.city }}{{ item.county }}</span>
|
|
|
</div>
|
|
|
<div class="card-info-row">
|
|
|
- <span class="card-info-label">来源工单号:</span>
|
|
|
- <span class="card-info-value">{{ item.sourceOrder }}</span>
|
|
|
+ <span class="card-info-label">来源工单:</span>
|
|
|
+ <span class="card-info-value">{{ item.billno }}</span>
|
|
|
</div>
|
|
|
<div class="card-info-row">
|
|
|
<span class="card-info-label">服务人员:</span>
|
|
|
- <span class="card-info-value">{{ item.serviceName }}</span>
|
|
|
- <span class="card-info-value phone" v-if="item.phone">{{ item.phone }}</span>
|
|
|
+ <span class="card-info-value">{{ item.leadername }} <a :href="'tel:' + item.leaderphonenumber" class="card-info-value phone" v-if="item.leaderphonenumber">{{ item.leaderphonenumber }}</a></span>
|
|
|
</div>
|
|
|
+ <!-- <div class="card-info-row">
|
|
|
+ <span class="card-info-label">经销商:</span>
|
|
|
+ <span class="card-info-value">{{ item.enterprisename }}</span>
|
|
|
+ </div> -->
|
|
|
</div>
|
|
|
|
|
|
<!-- 空状态 -->
|
|
|
<div v-if="filteredList.length === 0" class="empty-state">暂无质保卡数据</div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- 筛选弹窗 -->
|
|
|
+ <div class="filter-mask" v-show="showFilter" @click="showFilter = false">
|
|
|
+ <div class="filter-panel" :class="{ show: showFilter }" @click.stop>
|
|
|
+ <div class="filter-header">
|
|
|
+ <span>筛选条件</span>
|
|
|
+ <div class="filter-close" @click="showFilter = false">×</div>
|
|
|
+ </div>
|
|
|
+ <div class="filter-body">
|
|
|
+ <div class="filter-section">
|
|
|
+ <div class="filter-section-title">状态</div>
|
|
|
+ <div class="filter-tags">
|
|
|
+ <div class="tag-item" :class="{ active: filters.status === '' }" @click="filters.status = ''">全部</div>
|
|
|
+ <div class="tag-item" :class="{ active: filters.status === '生效中' }" @click="filters.status = '生效中'">生效中</div>
|
|
|
+ <div class="tag-item" :class="{ active: filters.status === '已到期' }" @click="filters.status = '已到期'">已到期</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="filter-section">
|
|
|
+ <div class="filter-section-title">生成时间</div>
|
|
|
+ <div class="filter-date-row">
|
|
|
+ <input type="date" v-model="filters.begdate" placeholder="开始日期" />
|
|
|
+ <span>—</span>
|
|
|
+ <input type="date" v-model="filters.enddate" placeholder="结束日期" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="filter-section">
|
|
|
+ <div class="filter-section-title">到期时间</div>
|
|
|
+ <div class="filter-date-row">
|
|
|
+ <input type="date" v-model="filters.begdate2" placeholder="开始日期" />
|
|
|
+ <span>—</span>
|
|
|
+ <input type="date" v-model="filters.enddate2" placeholder="结束日期" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="filter-footer">
|
|
|
+ <div class="btn-reset" @click="resetFilter">重置</div>
|
|
|
+ <div class="btn-confirm" @click="applyFilter">确定</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -218,41 +418,30 @@ var app6 = new Vue({
|
|
|
data () {
|
|
|
return {
|
|
|
activeTab: 'active',
|
|
|
- dataList: [
|
|
|
- // 模拟数据,实际开发中替换为接口请求
|
|
|
- {
|
|
|
- billno: 'ZBK202601010001',
|
|
|
- status: '生效中',
|
|
|
- createdate: '2026-01-01 10:00:00',
|
|
|
- enddate: '2027-01-01 10:00:00',
|
|
|
- province: '浙江省',
|
|
|
- city: '嘉兴市',
|
|
|
- county: '海盐县',
|
|
|
- sourceOrder: 'GD202512010001',
|
|
|
- serviceName: '张伟',
|
|
|
- phone: '18745693025'
|
|
|
- },
|
|
|
- {
|
|
|
- billno: 'ZBK202601010002',
|
|
|
- status: '已到期',
|
|
|
- createdate: '2025-01-01 10:00:00',
|
|
|
- enddate: '2026-01-01 10:00:00',
|
|
|
- province: '浙江省',
|
|
|
- city: '嘉兴市',
|
|
|
- county: '海盐县',
|
|
|
- sourceOrder: 'GD202501010001',
|
|
|
- serviceName: '张伟',
|
|
|
- phone: '18745693025'
|
|
|
- }
|
|
|
- ]
|
|
|
+ dataList: [],
|
|
|
+ showSearch: false,
|
|
|
+ searchKey: '',
|
|
|
+ showFilter: false,
|
|
|
+ filters: {
|
|
|
+ status: '',
|
|
|
+ begdate: '',
|
|
|
+ enddate: '',
|
|
|
+ begdate2: '',
|
|
|
+ enddate2: ''
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
filteredList () {
|
|
|
- if (this.activeTab === 'active') {
|
|
|
- return this.dataList.filter(item => item.status === '生效中');
|
|
|
+ return this.dataList;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ showFilter (val) {
|
|
|
+ if (val) {
|
|
|
+ document.body.classList.add('van-overflow-hidden');
|
|
|
} else {
|
|
|
- return this.dataList.filter(item => item.status === '已到期');
|
|
|
+ document.body.classList.remove('van-overflow-hidden');
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
@@ -260,14 +449,63 @@ var app6 = new Vue({
|
|
|
goback () {
|
|
|
window.location.href = "javascript:history.go(-1)";
|
|
|
},
|
|
|
- // 获取质保卡列表数据
|
|
|
- getWarrantyList () {
|
|
|
- // TODO: 实现接口请求逻辑
|
|
|
- // axios.post('/api/proxy', { ... }).then(res => { ... })
|
|
|
+ changeTab (tab) {
|
|
|
+ this.activeTab = tab;
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ onSearch () {
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ resetFilter () {
|
|
|
+ this.filters = { status: '', begdate: '', enddate: '', begdate2: '', enddate2: '' };
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ applyFilter () {
|
|
|
+ this.showFilter = false;
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ getData () {
|
|
|
+ var self = this;
|
|
|
+ var login = window.H5Login || {};
|
|
|
+
|
|
|
+ // 根据 activeTab 确定 status 参数
|
|
|
+ var status = '';
|
|
|
+ if (this.activeTab === 'active') {
|
|
|
+ status = '生效中';
|
|
|
+ } else if (this.activeTab === 'expired') {
|
|
|
+ status = '已到期';
|
|
|
+ }
|
|
|
+
|
|
|
+ axios.post(window.API_URL, {
|
|
|
+ id: 2026052914363302,
|
|
|
+ content: {
|
|
|
+ phonenumber: login.phone || '',
|
|
|
+ where: {
|
|
|
+ condition: this.searchKey || '',
|
|
|
+ status: this.filters.status || status,
|
|
|
+ begdate: this.filters.begdate || '',
|
|
|
+ enddate: this.filters.enddate || '',
|
|
|
+ begdate2: this.filters.begdate2 || '',
|
|
|
+ enddate2: this.filters.enddate2 || ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ accesstoken: login.token || ''
|
|
|
+ }).then(function (res) {
|
|
|
+ var data = res.data;
|
|
|
+ if (data.code === 1) {
|
|
|
+ self.dataList = data.data || [];
|
|
|
+ }
|
|
|
+ }).catch(function () {
|
|
|
+ self.dataList = [];
|
|
|
+ });
|
|
|
}
|
|
|
},
|
|
|
mounted () {
|
|
|
- this.getWarrantyList();
|
|
|
+ var self = this;
|
|
|
+ this.getData();
|
|
|
+ window.addEventListener('h5:login', function () {
|
|
|
+ self.getData();
|
|
|
+ });
|
|
|
}
|
|
|
});
|
|
|
</script>
|