Commit ffd6aaca8c3edc72e935969e05e966b97e0fe262
1 parent
d64f9fbd
最新
Showing
13 changed files
with
2930 additions
and
110 deletions
antis-ncc-admin/src/views/statisticsList/form12.vue
| @@ -42,23 +42,6 @@ | @@ -42,23 +42,6 @@ | ||
| 42 | </el-form-item> | 42 | </el-form-item> |
| 43 | </el-col> | 43 | </el-col> |
| 44 | <el-col :span="6"> | 44 | <el-col :span="6"> |
| 45 | - <el-form-item label="开单门店"> | ||
| 46 | - <el-select | ||
| 47 | - v-model="query.BillingStoreId" | ||
| 48 | - placeholder="请选择开单门店" | ||
| 49 | - filterable | ||
| 50 | - clearable | ||
| 51 | - :style='{"width":"100%"}'> | ||
| 52 | - <el-option | ||
| 53 | - v-for="item in storeOptions" | ||
| 54 | - :key="item.id" | ||
| 55 | - :label="item.dm" | ||
| 56 | - :value="item.id"> | ||
| 57 | - </el-option> | ||
| 58 | - </el-select> | ||
| 59 | - </el-form-item> | ||
| 60 | - </el-col> | ||
| 61 | - <el-col :span="6"> | ||
| 62 | <el-form-item label="开单人"> | 45 | <el-form-item label="开单人"> |
| 63 | <userSelect v-model="query.BillingUserId" placeholder="请选择开单人" clearable /> | 46 | <userSelect v-model="query.BillingUserId" placeholder="请选择开单人" clearable /> |
| 64 | </el-form-item> | 47 | </el-form-item> |
| @@ -132,6 +115,71 @@ | @@ -132,6 +115,71 @@ | ||
| 132 | </el-form-item> | 115 | </el-form-item> |
| 133 | </el-col> | 116 | </el-col> |
| 134 | <el-col :span="6"> | 117 | <el-col :span="6"> |
| 118 | + <el-form-item label="当前部门月份"> | ||
| 119 | + <el-date-picker | ||
| 120 | + v-model="query.month" | ||
| 121 | + type="month" | ||
| 122 | + value-format="yyyyMM" | ||
| 123 | + format="yyyy年MM月" | ||
| 124 | + placeholder="请选择当前部门月份" | ||
| 125 | + :style='{"width":"100%"}' | ||
| 126 | + @change="handleMonthChange"> | ||
| 127 | + </el-date-picker> | ||
| 128 | + </el-form-item> | ||
| 129 | + </el-col> | ||
| 130 | + <el-col :span="6"> | ||
| 131 | + <el-form-item label="组织类型"> | ||
| 132 | + <el-select | ||
| 133 | + v-model="query.organizationType" | ||
| 134 | + placeholder="请选择组织类型" | ||
| 135 | + filterable | ||
| 136 | + clearable | ||
| 137 | + @change="handleOrganizationTypeChange" | ||
| 138 | + :style='{"width":"100%"}'> | ||
| 139 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 140 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 141 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 142 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 143 | + </el-select> | ||
| 144 | + </el-form-item> | ||
| 145 | + </el-col> | ||
| 146 | + <el-col :span="6"> | ||
| 147 | + <el-form-item label="部门"> | ||
| 148 | + <el-select | ||
| 149 | + v-model="query.departmentId" | ||
| 150 | + placeholder="请选择部门" | ||
| 151 | + filterable | ||
| 152 | + clearable | ||
| 153 | + @change="handleDepartmentChange" | ||
| 154 | + :style='{"width":"100%"}'> | ||
| 155 | + <el-option | ||
| 156 | + v-for="dept in departmentOptions" | ||
| 157 | + :key="dept.Id || dept.id" | ||
| 158 | + :label="dept.FullName || dept.fullName" | ||
| 159 | + :value="dept.Id || dept.id"> | ||
| 160 | + </el-option> | ||
| 161 | + </el-select> | ||
| 162 | + </el-form-item> | ||
| 163 | + </el-col> | ||
| 164 | + <el-col :span="12"> | ||
| 165 | + <el-form-item label="开单门店"> | ||
| 166 | + <el-select | ||
| 167 | + v-model="query.BillingStoreIds" | ||
| 168 | + placeholder="请选择开单门店" | ||
| 169 | + multiple | ||
| 170 | + filterable | ||
| 171 | + clearable | ||
| 172 | + :style='{"width":"100%"}'> | ||
| 173 | + <el-option | ||
| 174 | + v-for="item in storeOptions" | ||
| 175 | + :key="item.id" | ||
| 176 | + :label="item.dm" | ||
| 177 | + :value="item.id"> | ||
| 178 | + </el-option> | ||
| 179 | + </el-select> | ||
| 180 | + </el-form-item> | ||
| 181 | + </el-col> | ||
| 182 | + <el-col :span="6"> | ||
| 135 | <el-form-item> | 183 | <el-form-item> |
| 136 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | 184 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 137 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | 185 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| @@ -242,7 +290,10 @@ export default { | @@ -242,7 +290,10 @@ export default { | ||
| 242 | query: { | 290 | query: { |
| 243 | MemberId: undefined, | 291 | MemberId: undefined, |
| 244 | BelongStoreId: undefined, | 292 | BelongStoreId: undefined, |
| 245 | - BillingStoreId: undefined, | 293 | + month: undefined, |
| 294 | + organizationType: undefined, | ||
| 295 | + departmentId: undefined, | ||
| 296 | + BillingStoreIds: [], | ||
| 246 | BillingUserId: undefined, | 297 | BillingUserId: undefined, |
| 247 | PurchaseItemId: undefined, | 298 | PurchaseItemId: undefined, |
| 248 | GiftItemId: undefined, | 299 | GiftItemId: undefined, |
| @@ -252,6 +303,7 @@ export default { | @@ -252,6 +303,7 @@ export default { | ||
| 252 | memberOptions: [], | 303 | memberOptions: [], |
| 253 | memberLoading: false, | 304 | memberLoading: false, |
| 254 | storeOptions: [], | 305 | storeOptions: [], |
| 306 | + departmentOptions: [], | ||
| 255 | itemOptions: [], | 307 | itemOptions: [], |
| 256 | memberTypeOptions: [], | 308 | memberTypeOptions: [], |
| 257 | list: [], | 309 | list: [], |
| @@ -266,15 +318,32 @@ export default { | @@ -266,15 +318,32 @@ export default { | ||
| 266 | } | 318 | } |
| 267 | }, | 319 | }, |
| 268 | created() { | 320 | created() { |
| 269 | - this.initStoreOptions() | 321 | + this.setDefaultMonth() |
| 322 | + this.loadAllStores() | ||
| 270 | this.initItemOptions() | 323 | this.initItemOptions() |
| 271 | this.initMemberOptions() | 324 | this.initMemberOptions() |
| 272 | this.getMemberTypeOptions() | 325 | this.getMemberTypeOptions() |
| 273 | this.search() | 326 | this.search() |
| 274 | }, | 327 | }, |
| 328 | + watch: { | ||
| 329 | + // 监听年月变化,重新加载门店列表 | ||
| 330 | + 'query.month'() { | ||
| 331 | + this.$nextTick(() => { | ||
| 332 | + this.initStoreOptions() | ||
| 333 | + }) | ||
| 334 | + } | ||
| 335 | + }, | ||
| 275 | methods: { | 336 | methods: { |
| 276 | - // 初始化门店选项 | ||
| 277 | - initStoreOptions() { | 337 | + // 设置默认年月(当前年月) |
| 338 | + setDefaultMonth() { | ||
| 339 | + const now = new Date() | ||
| 340 | + const year = now.getFullYear() | ||
| 341 | + const month = String(now.getMonth() + 1).padStart(2, '0') | ||
| 342 | + this.query.month = `${year}${month}` | ||
| 343 | + }, | ||
| 344 | + | ||
| 345 | + // 加载全部门店(当没有选择部门时) | ||
| 346 | + loadAllStores() { | ||
| 278 | request({ | 347 | request({ |
| 279 | url: '/api/Extend/LqMdxx', | 348 | url: '/api/Extend/LqMdxx', |
| 280 | method: 'GET', | 349 | method: 'GET', |
| @@ -291,6 +360,112 @@ export default { | @@ -291,6 +360,112 @@ export default { | ||
| 291 | }) | 360 | }) |
| 292 | }, | 361 | }, |
| 293 | 362 | ||
| 363 | + // 获取部门选项(根据组织类型) | ||
| 364 | + loadDepartmentOptions() { | ||
| 365 | + if (!this.query.organizationType) { | ||
| 366 | + this.departmentOptions = [] | ||
| 367 | + return | ||
| 368 | + } | ||
| 369 | + | ||
| 370 | + request({ | ||
| 371 | + url: '/api/Extend/Organize/GetByName', | ||
| 372 | + method: 'GET', | ||
| 373 | + data: { | ||
| 374 | + organizeName: this.query.organizationType | ||
| 375 | + } | ||
| 376 | + }).then(res => { | ||
| 377 | + this.departmentOptions = res.data || [] | ||
| 378 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 379 | + if (this.query.departmentId) { | ||
| 380 | + const exists = this.departmentOptions.some( | ||
| 381 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 382 | + ) | ||
| 383 | + if (!exists) { | ||
| 384 | + this.query.departmentId = undefined | ||
| 385 | + this.query.BillingStoreIds = [] | ||
| 386 | + this.storeOptions = [] | ||
| 387 | + } | ||
| 388 | + } | ||
| 389 | + }).catch(() => { | ||
| 390 | + this.departmentOptions = [] | ||
| 391 | + }) | ||
| 392 | + }, | ||
| 393 | + | ||
| 394 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 395 | + initStoreOptions() { | ||
| 396 | + // 如果没有选择部门,加载全部门店 | ||
| 397 | + if (!this.query.departmentId) { | ||
| 398 | + this.loadAllStores() | ||
| 399 | + return | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + // 如果缺少必要参数,不加载门店列表 | ||
| 403 | + if (!this.query.organizationType || !this.query.month) { | ||
| 404 | + this.storeOptions = [] | ||
| 405 | + return | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + request({ | ||
| 409 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 410 | + method: 'POST', | ||
| 411 | + data: { | ||
| 412 | + month: this.query.month, | ||
| 413 | + organizationType: this.query.organizationType, | ||
| 414 | + departmentId: this.query.departmentId | ||
| 415 | + } | ||
| 416 | + }).then(res => { | ||
| 417 | + if (res.data && Array.isArray(res.data)) { | ||
| 418 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 419 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 420 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 421 | + this.storeOptions = res.data.map(store => ({ | ||
| 422 | + id: store.StoreId, | ||
| 423 | + dm: store.StoreName | ||
| 424 | + })) | ||
| 425 | + // 默认选中所有获取到的门店 | ||
| 426 | + this.query.BillingStoreIds = this.storeOptions.map(store => store.id) | ||
| 427 | + } else { | ||
| 428 | + this.storeOptions = [] | ||
| 429 | + this.query.BillingStoreIds = [] | ||
| 430 | + } | ||
| 431 | + }).catch(err => { | ||
| 432 | + console.error('获取门店列表失败:', err) | ||
| 433 | + this.$message({ | ||
| 434 | + type: 'error', | ||
| 435 | + message: '获取门店列表失败', | ||
| 436 | + duration: 1500 | ||
| 437 | + }) | ||
| 438 | + this.storeOptions = [] | ||
| 439 | + this.query.BillingStoreIds = [] | ||
| 440 | + }) | ||
| 441 | + }, | ||
| 442 | + | ||
| 443 | + // 处理年月变化 | ||
| 444 | + handleMonthChange() { | ||
| 445 | + this.$nextTick(() => { | ||
| 446 | + this.initStoreOptions() | ||
| 447 | + }) | ||
| 448 | + }, | ||
| 449 | + | ||
| 450 | + // 处理组织类型变化 | ||
| 451 | + handleOrganizationTypeChange() { | ||
| 452 | + // 清空部门和门店 | ||
| 453 | + this.query.departmentId = undefined | ||
| 454 | + this.query.BillingStoreIds = [] | ||
| 455 | + // 重新加载部门选项 | ||
| 456 | + this.loadDepartmentOptions() | ||
| 457 | + // 加载全部门店(因为部门已清空) | ||
| 458 | + this.loadAllStores() | ||
| 459 | + }, | ||
| 460 | + | ||
| 461 | + // 处理部门变化 | ||
| 462 | + handleDepartmentChange() { | ||
| 463 | + // 清空门店选择 | ||
| 464 | + this.query.BillingStoreIds = [] | ||
| 465 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 466 | + this.initStoreOptions() | ||
| 467 | + }, | ||
| 468 | + | ||
| 294 | // 初始化品项选项 | 469 | // 初始化品项选项 |
| 295 | initItemOptions() { | 470 | initItemOptions() { |
| 296 | request({ | 471 | request({ |
| @@ -562,13 +737,20 @@ export default { | @@ -562,13 +737,20 @@ export default { | ||
| 562 | this.query = { | 737 | this.query = { |
| 563 | MemberId: undefined, | 738 | MemberId: undefined, |
| 564 | BelongStoreId: undefined, | 739 | BelongStoreId: undefined, |
| 565 | - BillingStoreId: undefined, | 740 | + month: undefined, |
| 741 | + organizationType: undefined, | ||
| 742 | + departmentId: undefined, | ||
| 743 | + BillingStoreIds: [], | ||
| 566 | BillingUserId: undefined, | 744 | BillingUserId: undefined, |
| 567 | PurchaseItemId: undefined, | 745 | PurchaseItemId: undefined, |
| 568 | GiftItemId: undefined, | 746 | GiftItemId: undefined, |
| 569 | ExperienceItemId: undefined, | 747 | ExperienceItemId: undefined, |
| 570 | memberType: undefined | 748 | memberType: undefined |
| 571 | } | 749 | } |
| 750 | + this.setDefaultMonth() | ||
| 751 | + this.departmentOptions = [] | ||
| 752 | + // 重置后加载全部门店 | ||
| 753 | + this.loadAllStores() | ||
| 572 | this.listQuery.currentPage = 1 | 754 | this.listQuery.currentPage = 1 |
| 573 | this.listQuery.pageSize = 20 | 755 | this.listQuery.pageSize = 20 |
| 574 | this.list = [] | 756 | this.list = [] |
antis-ncc-admin/src/views/statisticsList/form13.vue
| @@ -111,10 +111,45 @@ | @@ -111,10 +111,45 @@ | ||
| 111 | </el-form-item> | 111 | </el-form-item> |
| 112 | </el-col> | 112 | </el-col> |
| 113 | <el-col :span="6"> | 113 | <el-col :span="6"> |
| 114 | + <el-form-item label="组织类型"> | ||
| 115 | + <el-select | ||
| 116 | + v-model="query.organizationType" | ||
| 117 | + placeholder="请选择组织类型" | ||
| 118 | + filterable | ||
| 119 | + clearable | ||
| 120 | + @change="handleOrganizationTypeChange" | ||
| 121 | + :style='{"width":"100%"}'> | ||
| 122 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 123 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 124 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 125 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 126 | + </el-select> | ||
| 127 | + </el-form-item> | ||
| 128 | + </el-col> | ||
| 129 | + <el-col :span="6"> | ||
| 130 | + <el-form-item label="部门"> | ||
| 131 | + <el-select | ||
| 132 | + v-model="query.departmentId" | ||
| 133 | + placeholder="请选择部门" | ||
| 134 | + filterable | ||
| 135 | + clearable | ||
| 136 | + @change="handleDepartmentChange" | ||
| 137 | + :style='{"width":"100%"}'> | ||
| 138 | + <el-option | ||
| 139 | + v-for="dept in departmentOptions" | ||
| 140 | + :key="dept.Id || dept.id" | ||
| 141 | + :label="dept.FullName || dept.fullName" | ||
| 142 | + :value="dept.Id || dept.id"> | ||
| 143 | + </el-option> | ||
| 144 | + </el-select> | ||
| 145 | + </el-form-item> | ||
| 146 | + </el-col> | ||
| 147 | + <el-col :span="12"> | ||
| 114 | <el-form-item label="门店"> | 148 | <el-form-item label="门店"> |
| 115 | <el-select | 149 | <el-select |
| 116 | - v-model="query.storeId" | 150 | + v-model="query.storeIds" |
| 117 | placeholder="请选择门店" | 151 | placeholder="请选择门店" |
| 152 | + multiple | ||
| 118 | filterable | 153 | filterable |
| 119 | clearable | 154 | clearable |
| 120 | :style='{"width":"100%"}'> | 155 | :style='{"width":"100%"}'> |
| @@ -255,7 +290,9 @@ export default { | @@ -255,7 +290,9 @@ export default { | ||
| 255 | memberId: undefined, | 290 | memberId: undefined, |
| 256 | itemType: undefined, | 291 | itemType: undefined, |
| 257 | SourceType: undefined, | 292 | SourceType: undefined, |
| 258 | - storeId: undefined | 293 | + organizationType: undefined, |
| 294 | + departmentId: undefined, | ||
| 295 | + storeIds: [] | ||
| 259 | }, | 296 | }, |
| 260 | activityOptions: [], | 297 | activityOptions: [], |
| 261 | itemOptions: [], | 298 | itemOptions: [], |
| @@ -263,6 +300,7 @@ export default { | @@ -263,6 +300,7 @@ export default { | ||
| 263 | memberOptions: [], | 300 | memberOptions: [], |
| 264 | memberLoading: false, | 301 | memberLoading: false, |
| 265 | storeOptions: [], | 302 | storeOptions: [], |
| 303 | + departmentOptions: [], | ||
| 266 | list: [], | 304 | list: [], |
| 267 | listLoading: false, | 305 | listLoading: false, |
| 268 | total: 0, | 306 | total: 0, |
| @@ -278,9 +316,17 @@ export default { | @@ -278,9 +316,17 @@ export default { | ||
| 278 | this.initItemOptions() | 316 | this.initItemOptions() |
| 279 | this.initItemTypeOptions() | 317 | this.initItemTypeOptions() |
| 280 | this.initMemberOptions() | 318 | this.initMemberOptions() |
| 281 | - this.initStoreOptions() | 319 | + this.loadAllStores() |
| 282 | this.search() | 320 | this.search() |
| 283 | }, | 321 | }, |
| 322 | + watch: { | ||
| 323 | + // 监听开始时间变化,重新加载门店列表 | ||
| 324 | + 'query.StartBillingTime'() { | ||
| 325 | + this.$nextTick(() => { | ||
| 326 | + this.initStoreOptions() | ||
| 327 | + }) | ||
| 328 | + } | ||
| 329 | + }, | ||
| 284 | methods: { | 330 | methods: { |
| 285 | // 设置默认时间范围(本月1号到现在) | 331 | // 设置默认时间范围(本月1号到现在) |
| 286 | setDefaultTimeRange() { | 332 | setDefaultTimeRange() { |
| @@ -289,6 +335,13 @@ export default { | @@ -289,6 +335,13 @@ export default { | ||
| 289 | 335 | ||
| 290 | this.query.StartBillingTime = this.formatDate(firstDayOfMonth) | 336 | this.query.StartBillingTime = this.formatDate(firstDayOfMonth) |
| 291 | this.query.EndBillingTime = this.formatDate(now) | 337 | this.query.EndBillingTime = this.formatDate(now) |
| 338 | + | ||
| 339 | + // 时间设置后,如果有组织类型和部门,重新加载门店列表 | ||
| 340 | + if (this.query.organizationType && this.query.departmentId) { | ||
| 341 | + this.$nextTick(() => { | ||
| 342 | + this.initStoreOptions() | ||
| 343 | + }) | ||
| 344 | + } | ||
| 292 | }, | 345 | }, |
| 293 | 346 | ||
| 294 | // 初始化开单活动选项 | 347 | // 初始化开单活动选项 |
| @@ -364,8 +417,8 @@ export default { | @@ -364,8 +417,8 @@ export default { | ||
| 364 | }) | 417 | }) |
| 365 | }, | 418 | }, |
| 366 | 419 | ||
| 367 | - // 初始化门店选项 | ||
| 368 | - initStoreOptions() { | 420 | + // 加载全部门店(当没有选择部门时) |
| 421 | + loadAllStores() { | ||
| 369 | request({ | 422 | request({ |
| 370 | url: '/api/Extend/LqMdxx', | 423 | url: '/api/Extend/LqMdxx', |
| 371 | method: 'GET', | 424 | method: 'GET', |
| @@ -382,6 +435,116 @@ export default { | @@ -382,6 +435,116 @@ export default { | ||
| 382 | }) | 435 | }) |
| 383 | }, | 436 | }, |
| 384 | 437 | ||
| 438 | + // 获取部门选项(根据组织类型) | ||
| 439 | + loadDepartmentOptions() { | ||
| 440 | + if (!this.query.organizationType) { | ||
| 441 | + this.departmentOptions = [] | ||
| 442 | + return | ||
| 443 | + } | ||
| 444 | + | ||
| 445 | + request({ | ||
| 446 | + url: '/api/Extend/Organize/GetByName', | ||
| 447 | + method: 'GET', | ||
| 448 | + data: { | ||
| 449 | + organizeName: this.query.organizationType | ||
| 450 | + } | ||
| 451 | + }).then(res => { | ||
| 452 | + this.departmentOptions = res.data || [] | ||
| 453 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 454 | + if (this.query.departmentId) { | ||
| 455 | + const exists = this.departmentOptions.some( | ||
| 456 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 457 | + ) | ||
| 458 | + if (!exists) { | ||
| 459 | + this.query.departmentId = undefined | ||
| 460 | + this.query.storeIds = [] | ||
| 461 | + this.storeOptions = [] | ||
| 462 | + } | ||
| 463 | + } | ||
| 464 | + }).catch(() => { | ||
| 465 | + this.departmentOptions = [] | ||
| 466 | + }) | ||
| 467 | + }, | ||
| 468 | + | ||
| 469 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 470 | + initStoreOptions() { | ||
| 471 | + // 如果没有选择部门,加载全部门店 | ||
| 472 | + if (!this.query.departmentId) { | ||
| 473 | + this.loadAllStores() | ||
| 474 | + return | ||
| 475 | + } | ||
| 476 | + | ||
| 477 | + // 如果缺少必要参数,不加载门店列表 | ||
| 478 | + if (!this.query.organizationType || !this.query.StartBillingTime) { | ||
| 479 | + this.storeOptions = [] | ||
| 480 | + return | ||
| 481 | + } | ||
| 482 | + | ||
| 483 | + // 从开始时间提取年月(格式:YYYYMM) | ||
| 484 | + // StartBillingTime 格式为 yyyy-MM-dd | ||
| 485 | + const dateStr = this.query.StartBillingTime | ||
| 486 | + if (!dateStr) { | ||
| 487 | + this.storeOptions = [] | ||
| 488 | + return | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + // 提取年月,格式:YYYYMM | ||
| 492 | + const monthStr = dateStr.substring(0, 4) + dateStr.substring(5, 7) | ||
| 493 | + | ||
| 494 | + request({ | ||
| 495 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 496 | + method: 'POST', | ||
| 497 | + data: { | ||
| 498 | + month: monthStr, | ||
| 499 | + organizationType: this.query.organizationType, | ||
| 500 | + departmentId: this.query.departmentId | ||
| 501 | + } | ||
| 502 | + }).then(res => { | ||
| 503 | + if (res.data && Array.isArray(res.data)) { | ||
| 504 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 505 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 506 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 507 | + this.storeOptions = res.data.map(store => ({ | ||
| 508 | + id: store.StoreId, | ||
| 509 | + dm: store.StoreName | ||
| 510 | + })) | ||
| 511 | + // 默认选中所有获取到的门店 | ||
| 512 | + this.query.storeIds = this.storeOptions.map(store => store.id) | ||
| 513 | + } else { | ||
| 514 | + this.storeOptions = [] | ||
| 515 | + this.query.storeIds = [] | ||
| 516 | + } | ||
| 517 | + }).catch(err => { | ||
| 518 | + console.error('获取门店列表失败:', err) | ||
| 519 | + this.$message({ | ||
| 520 | + type: 'error', | ||
| 521 | + message: '获取门店列表失败', | ||
| 522 | + duration: 1500 | ||
| 523 | + }) | ||
| 524 | + this.storeOptions = [] | ||
| 525 | + this.query.storeIds = [] | ||
| 526 | + }) | ||
| 527 | + }, | ||
| 528 | + | ||
| 529 | + // 处理组织类型变化 | ||
| 530 | + handleOrganizationTypeChange() { | ||
| 531 | + // 清空部门和门店 | ||
| 532 | + this.query.departmentId = undefined | ||
| 533 | + this.query.storeIds = [] | ||
| 534 | + // 重新加载部门选项 | ||
| 535 | + this.loadDepartmentOptions() | ||
| 536 | + // 加载全部门店(因为部门已清空) | ||
| 537 | + this.loadAllStores() | ||
| 538 | + }, | ||
| 539 | + | ||
| 540 | + // 处理部门变化 | ||
| 541 | + handleDepartmentChange() { | ||
| 542 | + // 清空门店选择 | ||
| 543 | + this.query.storeIds = [] | ||
| 544 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 545 | + this.initStoreOptions() | ||
| 546 | + }, | ||
| 547 | + | ||
| 385 | // 会员远程搜索 | 548 | // 会员远程搜索 |
| 386 | remoteMemberMethod(query) { | 549 | remoteMemberMethod(query) { |
| 387 | if (query !== '') { | 550 | if (query !== '') { |
| @@ -445,8 +608,8 @@ export default { | @@ -445,8 +608,8 @@ export default { | ||
| 445 | if (this.query.SourceType) { | 608 | if (this.query.SourceType) { |
| 446 | params.SourceType = this.query.SourceType | 609 | params.SourceType = this.query.SourceType |
| 447 | } | 610 | } |
| 448 | - if (this.query.storeId) { | ||
| 449 | - params.StoreId = this.query.storeId | 611 | + if (this.query.storeIds && this.query.storeIds.length > 0) { |
| 612 | + params.StoreIds = this.query.storeIds | ||
| 450 | } | 613 | } |
| 451 | 614 | ||
| 452 | request({ | 615 | request({ |
| @@ -485,9 +648,14 @@ export default { | @@ -485,9 +648,14 @@ export default { | ||
| 485 | memberId: undefined, | 648 | memberId: undefined, |
| 486 | itemType: undefined, | 649 | itemType: undefined, |
| 487 | SourceType: undefined, | 650 | SourceType: undefined, |
| 488 | - storeId: undefined | 651 | + organizationType: undefined, |
| 652 | + departmentId: undefined, | ||
| 653 | + storeIds: [] | ||
| 489 | } | 654 | } |
| 490 | this.setDefaultTimeRange() | 655 | this.setDefaultTimeRange() |
| 656 | + this.departmentOptions = [] | ||
| 657 | + // 重置后加载全部门店 | ||
| 658 | + this.loadAllStores() | ||
| 491 | this.listQuery.currentPage = 1 | 659 | this.listQuery.currentPage = 1 |
| 492 | this.listQuery.pageSize = 20 | 660 | this.listQuery.pageSize = 20 |
| 493 | this.list = [] | 661 | this.list = [] |
antis-ncc-admin/src/views/statisticsList/form14.vue
| @@ -94,10 +94,45 @@ | @@ -94,10 +94,45 @@ | ||
| 94 | </el-form-item> | 94 | </el-form-item> |
| 95 | </el-col> | 95 | </el-col> |
| 96 | <el-col :span="6"> | 96 | <el-col :span="6"> |
| 97 | + <el-form-item label="组织类型"> | ||
| 98 | + <el-select | ||
| 99 | + v-model="query.organizationType" | ||
| 100 | + placeholder="请选择组织类型" | ||
| 101 | + filterable | ||
| 102 | + clearable | ||
| 103 | + @change="handleOrganizationTypeChange" | ||
| 104 | + :style='{"width":"100%"}'> | ||
| 105 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 106 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 107 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 108 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 109 | + </el-select> | ||
| 110 | + </el-form-item> | ||
| 111 | + </el-col> | ||
| 112 | + <el-col :span="6"> | ||
| 113 | + <el-form-item label="部门"> | ||
| 114 | + <el-select | ||
| 115 | + v-model="query.departmentId" | ||
| 116 | + placeholder="请选择部门" | ||
| 117 | + filterable | ||
| 118 | + clearable | ||
| 119 | + @change="handleDepartmentChange" | ||
| 120 | + :style='{"width":"100%"}'> | ||
| 121 | + <el-option | ||
| 122 | + v-for="dept in departmentOptions" | ||
| 123 | + :key="dept.Id || dept.id" | ||
| 124 | + :label="dept.FullName || dept.fullName" | ||
| 125 | + :value="dept.Id || dept.id"> | ||
| 126 | + </el-option> | ||
| 127 | + </el-select> | ||
| 128 | + </el-form-item> | ||
| 129 | + </el-col> | ||
| 130 | + <el-col :span="12"> | ||
| 97 | <el-form-item label="门店"> | 131 | <el-form-item label="门店"> |
| 98 | <el-select | 132 | <el-select |
| 99 | - v-model="query.StoreId" | 133 | + v-model="query.StoreIds" |
| 100 | placeholder="请选择门店" | 134 | placeholder="请选择门店" |
| 135 | + multiple | ||
| 101 | filterable | 136 | filterable |
| 102 | clearable | 137 | clearable |
| 103 | :style='{"width":"100%"}'> | 138 | :style='{"width":"100%"}'> |
| @@ -222,13 +257,16 @@ export default { | @@ -222,13 +257,16 @@ export default { | ||
| 222 | MemberId: undefined, | 257 | MemberId: undefined, |
| 223 | ItemType: undefined, | 258 | ItemType: undefined, |
| 224 | SourceType: undefined, | 259 | SourceType: undefined, |
| 225 | - StoreId: undefined | 260 | + organizationType: undefined, |
| 261 | + departmentId: undefined, | ||
| 262 | + StoreIds: [] | ||
| 226 | }, | 263 | }, |
| 227 | itemOptions: [], | 264 | itemOptions: [], |
| 228 | itemTypeOptions: [], | 265 | itemTypeOptions: [], |
| 229 | memberOptions: [], | 266 | memberOptions: [], |
| 230 | memberLoading: false, | 267 | memberLoading: false, |
| 231 | storeOptions: [], | 268 | storeOptions: [], |
| 269 | + departmentOptions: [], | ||
| 232 | list: [], | 270 | list: [], |
| 233 | listLoading: false, | 271 | listLoading: false, |
| 234 | total: 0, | 272 | total: 0, |
| @@ -243,9 +281,17 @@ export default { | @@ -243,9 +281,17 @@ export default { | ||
| 243 | this.initItemOptions() | 281 | this.initItemOptions() |
| 244 | this.initItemTypeOptions() | 282 | this.initItemTypeOptions() |
| 245 | this.initMemberOptions() | 283 | this.initMemberOptions() |
| 246 | - this.initStoreOptions() | 284 | + this.loadAllStores() |
| 247 | this.search() | 285 | this.search() |
| 248 | }, | 286 | }, |
| 287 | + watch: { | ||
| 288 | + // 监听开始时间变化,重新加载门店列表 | ||
| 289 | + 'query.StartConsumeTime'() { | ||
| 290 | + this.$nextTick(() => { | ||
| 291 | + this.initStoreOptions() | ||
| 292 | + }) | ||
| 293 | + } | ||
| 294 | + }, | ||
| 249 | methods: { | 295 | methods: { |
| 250 | // 设置默认时间范围(本月1号到现在) | 296 | // 设置默认时间范围(本月1号到现在) |
| 251 | setDefaultTimeRange() { | 297 | setDefaultTimeRange() { |
| @@ -254,6 +300,13 @@ export default { | @@ -254,6 +300,13 @@ export default { | ||
| 254 | 300 | ||
| 255 | this.query.StartConsumeTime = this.formatDate(firstDayOfMonth) | 301 | this.query.StartConsumeTime = this.formatDate(firstDayOfMonth) |
| 256 | this.query.EndConsumeTime = this.formatDate(now) | 302 | this.query.EndConsumeTime = this.formatDate(now) |
| 303 | + | ||
| 304 | + // 时间设置后,如果有组织类型和部门,重新加载门店列表 | ||
| 305 | + if (this.query.organizationType && this.query.departmentId) { | ||
| 306 | + this.$nextTick(() => { | ||
| 307 | + this.initStoreOptions() | ||
| 308 | + }) | ||
| 309 | + } | ||
| 257 | }, | 310 | }, |
| 258 | 311 | ||
| 259 | // 初始化品项选项 | 312 | // 初始化品项选项 |
| @@ -311,8 +364,8 @@ export default { | @@ -311,8 +364,8 @@ export default { | ||
| 311 | }) | 364 | }) |
| 312 | }, | 365 | }, |
| 313 | 366 | ||
| 314 | - // 初始化门店选项 | ||
| 315 | - initStoreOptions() { | 367 | + // 加载全部门店(当没有选择部门时) |
| 368 | + loadAllStores() { | ||
| 316 | request({ | 369 | request({ |
| 317 | url: '/api/Extend/LqMdxx', | 370 | url: '/api/Extend/LqMdxx', |
| 318 | method: 'GET', | 371 | method: 'GET', |
| @@ -329,6 +382,116 @@ export default { | @@ -329,6 +382,116 @@ export default { | ||
| 329 | }) | 382 | }) |
| 330 | }, | 383 | }, |
| 331 | 384 | ||
| 385 | + // 获取部门选项(根据组织类型) | ||
| 386 | + loadDepartmentOptions() { | ||
| 387 | + if (!this.query.organizationType) { | ||
| 388 | + this.departmentOptions = [] | ||
| 389 | + return | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + request({ | ||
| 393 | + url: '/api/Extend/Organize/GetByName', | ||
| 394 | + method: 'GET', | ||
| 395 | + data: { | ||
| 396 | + organizeName: this.query.organizationType | ||
| 397 | + } | ||
| 398 | + }).then(res => { | ||
| 399 | + this.departmentOptions = res.data || [] | ||
| 400 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 401 | + if (this.query.departmentId) { | ||
| 402 | + const exists = this.departmentOptions.some( | ||
| 403 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 404 | + ) | ||
| 405 | + if (!exists) { | ||
| 406 | + this.query.departmentId = undefined | ||
| 407 | + this.query.StoreIds = [] | ||
| 408 | + this.storeOptions = [] | ||
| 409 | + } | ||
| 410 | + } | ||
| 411 | + }).catch(() => { | ||
| 412 | + this.departmentOptions = [] | ||
| 413 | + }) | ||
| 414 | + }, | ||
| 415 | + | ||
| 416 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 417 | + initStoreOptions() { | ||
| 418 | + // 如果没有选择部门,加载全部门店 | ||
| 419 | + if (!this.query.departmentId) { | ||
| 420 | + this.loadAllStores() | ||
| 421 | + return | ||
| 422 | + } | ||
| 423 | + | ||
| 424 | + // 如果缺少必要参数,不加载门店列表 | ||
| 425 | + if (!this.query.organizationType || !this.query.StartConsumeTime) { | ||
| 426 | + this.storeOptions = [] | ||
| 427 | + return | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + // 从开始时间提取年月(格式:YYYYMM) | ||
| 431 | + // StartConsumeTime 格式为 yyyy-MM-dd | ||
| 432 | + const dateStr = this.query.StartConsumeTime | ||
| 433 | + if (!dateStr) { | ||
| 434 | + this.storeOptions = [] | ||
| 435 | + return | ||
| 436 | + } | ||
| 437 | + | ||
| 438 | + // 提取年月,格式:YYYYMM | ||
| 439 | + const monthStr = dateStr.substring(0, 4) + dateStr.substring(5, 7) | ||
| 440 | + | ||
| 441 | + request({ | ||
| 442 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 443 | + method: 'POST', | ||
| 444 | + data: { | ||
| 445 | + month: monthStr, | ||
| 446 | + organizationType: this.query.organizationType, | ||
| 447 | + departmentId: this.query.departmentId | ||
| 448 | + } | ||
| 449 | + }).then(res => { | ||
| 450 | + if (res.data && Array.isArray(res.data)) { | ||
| 451 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 452 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 453 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 454 | + this.storeOptions = res.data.map(store => ({ | ||
| 455 | + id: store.StoreId, | ||
| 456 | + dm: store.StoreName | ||
| 457 | + })) | ||
| 458 | + // 默认选中所有获取到的门店 | ||
| 459 | + this.query.StoreIds = this.storeOptions.map(store => store.id) | ||
| 460 | + } else { | ||
| 461 | + this.storeOptions = [] | ||
| 462 | + this.query.StoreIds = [] | ||
| 463 | + } | ||
| 464 | + }).catch(err => { | ||
| 465 | + console.error('获取门店列表失败:', err) | ||
| 466 | + this.$message({ | ||
| 467 | + type: 'error', | ||
| 468 | + message: '获取门店列表失败', | ||
| 469 | + duration: 1500 | ||
| 470 | + }) | ||
| 471 | + this.storeOptions = [] | ||
| 472 | + this.query.StoreIds = [] | ||
| 473 | + }) | ||
| 474 | + }, | ||
| 475 | + | ||
| 476 | + // 处理组织类型变化 | ||
| 477 | + handleOrganizationTypeChange() { | ||
| 478 | + // 清空部门和门店 | ||
| 479 | + this.query.departmentId = undefined | ||
| 480 | + this.query.StoreIds = [] | ||
| 481 | + // 重新加载部门选项 | ||
| 482 | + this.loadDepartmentOptions() | ||
| 483 | + // 加载全部门店(因为部门已清空) | ||
| 484 | + this.loadAllStores() | ||
| 485 | + }, | ||
| 486 | + | ||
| 487 | + // 处理部门变化 | ||
| 488 | + handleDepartmentChange() { | ||
| 489 | + // 清空门店选择 | ||
| 490 | + this.query.StoreIds = [] | ||
| 491 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 492 | + this.initStoreOptions() | ||
| 493 | + }, | ||
| 494 | + | ||
| 332 | // 会员远程搜索 | 495 | // 会员远程搜索 |
| 333 | remoteMemberMethod(query) { | 496 | remoteMemberMethod(query) { |
| 334 | if (query !== '') { | 497 | if (query !== '') { |
| @@ -390,8 +553,8 @@ export default { | @@ -390,8 +553,8 @@ export default { | ||
| 390 | params.SourceType = this.query.SourceType | 553 | params.SourceType = this.query.SourceType |
| 391 | } | 554 | } |
| 392 | 555 | ||
| 393 | - if (this.query.StoreId) { | ||
| 394 | - params.StoreId = this.query.StoreId | 556 | + if (this.query.StoreIds && this.query.StoreIds.length > 0) { |
| 557 | + params.StoreIds = this.query.StoreIds | ||
| 395 | } | 558 | } |
| 396 | 559 | ||
| 397 | request({ | 560 | request({ |
| @@ -429,9 +592,14 @@ export default { | @@ -429,9 +592,14 @@ export default { | ||
| 429 | MemberId: undefined, | 592 | MemberId: undefined, |
| 430 | ItemType: undefined, | 593 | ItemType: undefined, |
| 431 | SourceType: undefined, | 594 | SourceType: undefined, |
| 432 | - StoreId: undefined | 595 | + organizationType: undefined, |
| 596 | + departmentId: undefined, | ||
| 597 | + StoreIds: [] | ||
| 433 | } | 598 | } |
| 434 | this.setDefaultTimeRange() | 599 | this.setDefaultTimeRange() |
| 600 | + this.departmentOptions = [] | ||
| 601 | + // 重置后加载全部门店 | ||
| 602 | + this.loadAllStores() | ||
| 435 | this.listQuery.currentPage = 1 | 603 | this.listQuery.currentPage = 1 |
| 436 | this.listQuery.pageSize = 10 | 604 | this.listQuery.pageSize = 10 |
| 437 | this.list = [] | 605 | this.list = [] |
antis-ncc-admin/src/views/statisticsList/form17.vue
| @@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
| 4 | <!-- 筛选条件 --> | 4 | <!-- 筛选条件 --> |
| 5 | <el-row class="NCC-common-search-box" :gutter="16"> | 5 | <el-row class="NCC-common-search-box" :gutter="16"> |
| 6 | <el-form @submit.native.prevent> | 6 | <el-form @submit.native.prevent> |
| 7 | - <el-col :span="6"> | 7 | + <el-col :span="4.8"> |
| 8 | <el-form-item label="会员"> | 8 | <el-form-item label="会员"> |
| 9 | <el-select | 9 | <el-select |
| 10 | v-model="query.memberIds" | 10 | v-model="query.memberIds" |
| @@ -25,7 +25,7 @@ | @@ -25,7 +25,7 @@ | ||
| 25 | </el-select> | 25 | </el-select> |
| 26 | </el-form-item> | 26 | </el-form-item> |
| 27 | </el-col> | 27 | </el-col> |
| 28 | - <el-col :span="6"> | 28 | + <el-col :span="4.8"> |
| 29 | <el-form-item label="是否升医美"> | 29 | <el-form-item label="是否升医美"> |
| 30 | <el-select | 30 | <el-select |
| 31 | v-model="query.hasUpgradeMedicalBeauty" | 31 | v-model="query.hasUpgradeMedicalBeauty" |
| @@ -37,7 +37,7 @@ | @@ -37,7 +37,7 @@ | ||
| 37 | </el-select> | 37 | </el-select> |
| 38 | </el-form-item> | 38 | </el-form-item> |
| 39 | </el-col> | 39 | </el-col> |
| 40 | - <el-col :span="6"> | 40 | + <el-col :span="4.8"> |
| 41 | <el-form-item label="是否升科美"> | 41 | <el-form-item label="是否升科美"> |
| 42 | <el-select | 42 | <el-select |
| 43 | v-model="query.hasUpgradeTechBeauty" | 43 | v-model="query.hasUpgradeTechBeauty" |
| @@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
| 49 | </el-select> | 49 | </el-select> |
| 50 | </el-form-item> | 50 | </el-form-item> |
| 51 | </el-col> | 51 | </el-col> |
| 52 | - <el-col :span="6"> | 52 | + <el-col :span="4.8"> |
| 53 | <el-form-item label="是否升生美"> | 53 | <el-form-item label="是否升生美"> |
| 54 | <el-select | 54 | <el-select |
| 55 | v-model="query.hasUpgradeLifeBeauty" | 55 | v-model="query.hasUpgradeLifeBeauty" |
| @@ -61,7 +61,72 @@ | @@ -61,7 +61,72 @@ | ||
| 61 | </el-select> | 61 | </el-select> |
| 62 | </el-form-item> | 62 | </el-form-item> |
| 63 | </el-col> | 63 | </el-col> |
| 64 | - <el-col :span="6"> | 64 | + <el-col :span="4.8"> |
| 65 | + <el-form-item label="当前部门月份"> | ||
| 66 | + <el-date-picker | ||
| 67 | + v-model="query.month" | ||
| 68 | + type="month" | ||
| 69 | + value-format="yyyyMM" | ||
| 70 | + format="yyyy年MM月" | ||
| 71 | + placeholder="请选择当前部门月份" | ||
| 72 | + :style='{"width":"100%"}' | ||
| 73 | + @change="handleMonthChange"> | ||
| 74 | + </el-date-picker> | ||
| 75 | + </el-form-item> | ||
| 76 | + </el-col> | ||
| 77 | + <el-col :span="4.8"> | ||
| 78 | + <el-form-item label="组织类型"> | ||
| 79 | + <el-select | ||
| 80 | + v-model="query.organizationType" | ||
| 81 | + placeholder="请选择组织类型" | ||
| 82 | + filterable | ||
| 83 | + clearable | ||
| 84 | + @change="handleOrganizationTypeChange" | ||
| 85 | + :style='{"width":"100%"}'> | ||
| 86 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 87 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 88 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 89 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 90 | + </el-select> | ||
| 91 | + </el-form-item> | ||
| 92 | + </el-col> | ||
| 93 | + <el-col :span="4.8"> | ||
| 94 | + <el-form-item label="部门"> | ||
| 95 | + <el-select | ||
| 96 | + v-model="query.departmentId" | ||
| 97 | + placeholder="请选择部门" | ||
| 98 | + filterable | ||
| 99 | + clearable | ||
| 100 | + @change="handleDepartmentChange" | ||
| 101 | + :style='{"width":"100%"}'> | ||
| 102 | + <el-option | ||
| 103 | + v-for="dept in departmentOptions" | ||
| 104 | + :key="dept.Id || dept.id" | ||
| 105 | + :label="dept.FullName || dept.fullName" | ||
| 106 | + :value="dept.Id || dept.id"> | ||
| 107 | + </el-option> | ||
| 108 | + </el-select> | ||
| 109 | + </el-form-item> | ||
| 110 | + </el-col> | ||
| 111 | + <el-col :span="12"> | ||
| 112 | + <el-form-item label="门店"> | ||
| 113 | + <el-select | ||
| 114 | + v-model="query.storeIds" | ||
| 115 | + placeholder="请选择门店" | ||
| 116 | + multiple | ||
| 117 | + filterable | ||
| 118 | + clearable | ||
| 119 | + :style='{"width":"100%"}'> | ||
| 120 | + <el-option | ||
| 121 | + v-for="store in storeOptions" | ||
| 122 | + :key="store.id" | ||
| 123 | + :label="store.dm" | ||
| 124 | + :value="store.id"> | ||
| 125 | + </el-option> | ||
| 126 | + </el-select> | ||
| 127 | + </el-form-item> | ||
| 128 | + </el-col> | ||
| 129 | + <el-col :span="4.8"> | ||
| 65 | <el-form-item> | 130 | <el-form-item> |
| 66 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | 131 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 67 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | 132 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| @@ -146,10 +211,16 @@ export default { | @@ -146,10 +211,16 @@ export default { | ||
| 146 | memberIds: [], | 211 | memberIds: [], |
| 147 | hasUpgradeMedicalBeauty: null, | 212 | hasUpgradeMedicalBeauty: null, |
| 148 | hasUpgradeTechBeauty: null, | 213 | hasUpgradeTechBeauty: null, |
| 149 | - hasUpgradeLifeBeauty: null | 214 | + hasUpgradeLifeBeauty: null, |
| 215 | + month: undefined, | ||
| 216 | + organizationType: undefined, | ||
| 217 | + departmentId: undefined, | ||
| 218 | + storeIds: [] | ||
| 150 | }, | 219 | }, |
| 151 | memberOptions: [], | 220 | memberOptions: [], |
| 152 | memberLoading: false, | 221 | memberLoading: false, |
| 222 | + storeOptions: [], | ||
| 223 | + departmentOptions: [], | ||
| 153 | list: [], | 224 | list: [], |
| 154 | listLoading: false, | 225 | listLoading: false, |
| 155 | total: 0, | 226 | total: 0, |
| @@ -160,10 +231,152 @@ export default { | @@ -160,10 +231,152 @@ export default { | ||
| 160 | } | 231 | } |
| 161 | }, | 232 | }, |
| 162 | created() { | 233 | created() { |
| 234 | + this.setDefaultMonth() | ||
| 235 | + this.loadAllStores() | ||
| 163 | this.initMemberOptions() | 236 | this.initMemberOptions() |
| 164 | this.search() | 237 | this.search() |
| 165 | }, | 238 | }, |
| 239 | + watch: { | ||
| 240 | + // 监听年月变化,重新加载门店列表 | ||
| 241 | + 'query.month'() { | ||
| 242 | + this.$nextTick(() => { | ||
| 243 | + this.initStoreOptions() | ||
| 244 | + }) | ||
| 245 | + } | ||
| 246 | + }, | ||
| 166 | methods: { | 247 | methods: { |
| 248 | + // 设置默认年月(当前年月) | ||
| 249 | + setDefaultMonth() { | ||
| 250 | + const now = new Date() | ||
| 251 | + const year = now.getFullYear() | ||
| 252 | + const month = String(now.getMonth() + 1).padStart(2, '0') | ||
| 253 | + this.query.month = `${year}${month}` | ||
| 254 | + }, | ||
| 255 | + | ||
| 256 | + // 加载全部门店(当没有选择部门时) | ||
| 257 | + loadAllStores() { | ||
| 258 | + request({ | ||
| 259 | + url: '/api/Extend/LqMdxx', | ||
| 260 | + method: 'GET', | ||
| 261 | + data: { | ||
| 262 | + currentPage: 1, | ||
| 263 | + pageSize: 1000 | ||
| 264 | + } | ||
| 265 | + }).then(res => { | ||
| 266 | + if (res.data && res.data.list) { | ||
| 267 | + this.storeOptions = res.data.list | ||
| 268 | + } | ||
| 269 | + }).catch(() => { | ||
| 270 | + this.storeOptions = [] | ||
| 271 | + }) | ||
| 272 | + }, | ||
| 273 | + | ||
| 274 | + // 获取部门选项(根据组织类型) | ||
| 275 | + loadDepartmentOptions() { | ||
| 276 | + if (!this.query.organizationType) { | ||
| 277 | + this.departmentOptions = [] | ||
| 278 | + return | ||
| 279 | + } | ||
| 280 | + | ||
| 281 | + request({ | ||
| 282 | + url: '/api/Extend/Organize/GetByName', | ||
| 283 | + method: 'GET', | ||
| 284 | + data: { | ||
| 285 | + organizeName: this.query.organizationType | ||
| 286 | + } | ||
| 287 | + }).then(res => { | ||
| 288 | + this.departmentOptions = res.data || [] | ||
| 289 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 290 | + if (this.query.departmentId) { | ||
| 291 | + const exists = this.departmentOptions.some( | ||
| 292 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 293 | + ) | ||
| 294 | + if (!exists) { | ||
| 295 | + this.query.departmentId = undefined | ||
| 296 | + this.query.storeIds = [] | ||
| 297 | + this.storeOptions = [] | ||
| 298 | + } | ||
| 299 | + } | ||
| 300 | + }).catch(() => { | ||
| 301 | + this.departmentOptions = [] | ||
| 302 | + }) | ||
| 303 | + }, | ||
| 304 | + | ||
| 305 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 306 | + initStoreOptions() { | ||
| 307 | + // 如果没有选择部门,加载全部门店 | ||
| 308 | + if (!this.query.departmentId) { | ||
| 309 | + this.loadAllStores() | ||
| 310 | + return | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + // 如果缺少必要参数,不加载门店列表 | ||
| 314 | + if (!this.query.organizationType || !this.query.month) { | ||
| 315 | + this.storeOptions = [] | ||
| 316 | + return | ||
| 317 | + } | ||
| 318 | + | ||
| 319 | + request({ | ||
| 320 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 321 | + method: 'POST', | ||
| 322 | + data: { | ||
| 323 | + month: this.query.month, | ||
| 324 | + organizationType: this.query.organizationType, | ||
| 325 | + departmentId: this.query.departmentId | ||
| 326 | + } | ||
| 327 | + }).then(res => { | ||
| 328 | + if (res.data && Array.isArray(res.data)) { | ||
| 329 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 330 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 331 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 332 | + this.storeOptions = res.data.map(store => ({ | ||
| 333 | + id: store.StoreId, | ||
| 334 | + dm: store.StoreName | ||
| 335 | + })) | ||
| 336 | + // 默认选中所有获取到的门店 | ||
| 337 | + this.query.storeIds = this.storeOptions.map(store => store.id) | ||
| 338 | + } else { | ||
| 339 | + this.storeOptions = [] | ||
| 340 | + this.query.storeIds = [] | ||
| 341 | + } | ||
| 342 | + }).catch(err => { | ||
| 343 | + console.error('获取门店列表失败:', err) | ||
| 344 | + this.$message({ | ||
| 345 | + type: 'error', | ||
| 346 | + message: '获取门店列表失败', | ||
| 347 | + duration: 1500 | ||
| 348 | + }) | ||
| 349 | + this.storeOptions = [] | ||
| 350 | + this.query.storeIds = [] | ||
| 351 | + }) | ||
| 352 | + }, | ||
| 353 | + | ||
| 354 | + // 处理年月变化 | ||
| 355 | + handleMonthChange() { | ||
| 356 | + this.$nextTick(() => { | ||
| 357 | + this.initStoreOptions() | ||
| 358 | + }) | ||
| 359 | + }, | ||
| 360 | + | ||
| 361 | + // 处理组织类型变化 | ||
| 362 | + handleOrganizationTypeChange() { | ||
| 363 | + // 清空部门和门店 | ||
| 364 | + this.query.departmentId = undefined | ||
| 365 | + this.query.storeIds = [] | ||
| 366 | + // 重新加载部门选项 | ||
| 367 | + this.loadDepartmentOptions() | ||
| 368 | + // 加载全部门店(因为部门已清空) | ||
| 369 | + this.loadAllStores() | ||
| 370 | + }, | ||
| 371 | + | ||
| 372 | + // 处理部门变化 | ||
| 373 | + handleDepartmentChange() { | ||
| 374 | + // 清空门店选择 | ||
| 375 | + this.query.storeIds = [] | ||
| 376 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 377 | + this.initStoreOptions() | ||
| 378 | + }, | ||
| 379 | + | ||
| 167 | // 初始化会员选项(加载前10个) | 380 | // 初始化会员选项(加载前10个) |
| 168 | initMemberOptions() { | 381 | initMemberOptions() { |
| 169 | request({ | 382 | request({ |
| @@ -244,6 +457,10 @@ export default { | @@ -244,6 +457,10 @@ export default { | ||
| 244 | params.hasUpgradeLifeBeauty = this.query.hasUpgradeLifeBeauty | 457 | params.hasUpgradeLifeBeauty = this.query.hasUpgradeLifeBeauty |
| 245 | } | 458 | } |
| 246 | 459 | ||
| 460 | + if (this.query.storeIds && this.query.storeIds.length > 0) { | ||
| 461 | + params.storeIds = this.query.storeIds | ||
| 462 | + } | ||
| 463 | + | ||
| 247 | request({ | 464 | request({ |
| 248 | url: '/api/Extend/lqstatistics/get-member-upgrade-statistics-list', | 465 | url: '/api/Extend/lqstatistics/get-member-upgrade-statistics-list', |
| 249 | method: 'POST', | 466 | method: 'POST', |
| @@ -283,8 +500,16 @@ export default { | @@ -283,8 +500,16 @@ export default { | ||
| 283 | memberIds: [], | 500 | memberIds: [], |
| 284 | hasUpgradeMedicalBeauty: null, | 501 | hasUpgradeMedicalBeauty: null, |
| 285 | hasUpgradeTechBeauty: null, | 502 | hasUpgradeTechBeauty: null, |
| 286 | - hasUpgradeLifeBeauty: null | 503 | + hasUpgradeLifeBeauty: null, |
| 504 | + month: undefined, | ||
| 505 | + organizationType: undefined, | ||
| 506 | + departmentId: undefined, | ||
| 507 | + storeIds: [] | ||
| 287 | } | 508 | } |
| 509 | + this.setDefaultMonth() | ||
| 510 | + this.departmentOptions = [] | ||
| 511 | + // 重置后加载全部门店 | ||
| 512 | + this.loadAllStores() | ||
| 288 | this.listQuery.pageIndex = 1 | 513 | this.listQuery.pageIndex = 1 |
| 289 | this.listQuery.pageSize = 10 | 514 | this.listQuery.pageSize = 10 |
| 290 | this.list = [] | 515 | this.list = [] |
antis-ncc-admin/src/views/statisticsList/form18.vue
| @@ -5,23 +5,6 @@ | @@ -5,23 +5,6 @@ | ||
| 5 | <el-row class="NCC-common-search-box" :gutter="16"> | 5 | <el-row class="NCC-common-search-box" :gutter="16"> |
| 6 | <el-form @submit.native.prevent> | 6 | <el-form @submit.native.prevent> |
| 7 | <el-col :span="6"> | 7 | <el-col :span="6"> |
| 8 | - <el-form-item label="门店"> | ||
| 9 | - <el-select | ||
| 10 | - v-model="query.StoreId" | ||
| 11 | - placeholder="请选择门店" | ||
| 12 | - filterable | ||
| 13 | - clearable | ||
| 14 | - :style='{"width":"100%"}'> | ||
| 15 | - <el-option | ||
| 16 | - v-for="store in storeOptions" | ||
| 17 | - :key="store.id" | ||
| 18 | - :label="store.dm" | ||
| 19 | - :value="store.id"> | ||
| 20 | - </el-option> | ||
| 21 | - </el-select> | ||
| 22 | - </el-form-item> | ||
| 23 | - </el-col> | ||
| 24 | - <el-col :span="6"> | ||
| 25 | <el-form-item label="开始日期"> | 8 | <el-form-item label="开始日期"> |
| 26 | <el-date-picker | 9 | <el-date-picker |
| 27 | v-model="query.StartTime" | 10 | v-model="query.StartTime" |
| @@ -30,6 +13,7 @@ | @@ -30,6 +13,7 @@ | ||
| 30 | format="yyyy-MM-dd" | 13 | format="yyyy-MM-dd" |
| 31 | placeholder="开始日期" | 14 | placeholder="开始日期" |
| 32 | :style='{"width":"100%"}' | 15 | :style='{"width":"100%"}' |
| 16 | + @change="handleStartTimeChange" | ||
| 33 | /> | 17 | /> |
| 34 | </el-form-item> | 18 | </el-form-item> |
| 35 | </el-col> | 19 | </el-col> |
| @@ -104,6 +88,58 @@ | @@ -104,6 +88,58 @@ | ||
| 104 | </el-form-item> | 88 | </el-form-item> |
| 105 | </el-col> | 89 | </el-col> |
| 106 | <el-col :span="6"> | 90 | <el-col :span="6"> |
| 91 | + <el-form-item label="组织类型"> | ||
| 92 | + <el-select | ||
| 93 | + v-model="query.organizationType" | ||
| 94 | + placeholder="请选择组织类型" | ||
| 95 | + filterable | ||
| 96 | + clearable | ||
| 97 | + @change="handleOrganizationTypeChange" | ||
| 98 | + :style='{"width":"100%"}'> | ||
| 99 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 100 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 101 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 102 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 103 | + </el-select> | ||
| 104 | + </el-form-item> | ||
| 105 | + </el-col> | ||
| 106 | + <el-col :span="6"> | ||
| 107 | + <el-form-item label="部门"> | ||
| 108 | + <el-select | ||
| 109 | + v-model="query.departmentId" | ||
| 110 | + placeholder="请选择部门" | ||
| 111 | + filterable | ||
| 112 | + clearable | ||
| 113 | + @change="handleDepartmentChange" | ||
| 114 | + :style='{"width":"100%"}'> | ||
| 115 | + <el-option | ||
| 116 | + v-for="dept in departmentOptions" | ||
| 117 | + :key="dept.Id || dept.id" | ||
| 118 | + :label="dept.FullName || dept.fullName" | ||
| 119 | + :value="dept.Id || dept.id"> | ||
| 120 | + </el-option> | ||
| 121 | + </el-select> | ||
| 122 | + </el-form-item> | ||
| 123 | + </el-col> | ||
| 124 | + <el-col :span="12"> | ||
| 125 | + <el-form-item label="门店"> | ||
| 126 | + <el-select | ||
| 127 | + v-model="query.StoreIds" | ||
| 128 | + placeholder="请选择门店" | ||
| 129 | + multiple | ||
| 130 | + filterable | ||
| 131 | + clearable | ||
| 132 | + :style='{"width":"100%"}'> | ||
| 133 | + <el-option | ||
| 134 | + v-for="store in storeOptions" | ||
| 135 | + :key="store.id" | ||
| 136 | + :label="store.dm" | ||
| 137 | + :value="store.id"> | ||
| 138 | + </el-option> | ||
| 139 | + </el-select> | ||
| 140 | + </el-form-item> | ||
| 141 | + </el-col> | ||
| 142 | + <el-col :span="6"> | ||
| 107 | <el-form-item> | 143 | <el-form-item> |
| 108 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | 144 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 109 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | 145 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| @@ -238,7 +274,9 @@ export default { | @@ -238,7 +274,9 @@ export default { | ||
| 238 | data() { | 274 | data() { |
| 239 | return { | 275 | return { |
| 240 | query: { | 276 | query: { |
| 241 | - StoreId: undefined, | 277 | + organizationType: undefined, |
| 278 | + departmentId: undefined, | ||
| 279 | + StoreIds: [], | ||
| 242 | StartTime: undefined, | 280 | StartTime: undefined, |
| 243 | EndTime: undefined, | 281 | EndTime: undefined, |
| 244 | ItemId: undefined, | 282 | ItemId: undefined, |
| @@ -247,6 +285,7 @@ export default { | @@ -247,6 +285,7 @@ export default { | ||
| 247 | MaxAmount: undefined | 285 | MaxAmount: undefined |
| 248 | }, | 286 | }, |
| 249 | storeOptions: [], | 287 | storeOptions: [], |
| 288 | + departmentOptions: [], | ||
| 250 | itemOptions: [], | 289 | itemOptions: [], |
| 251 | itemCategoryOptions: [], | 290 | itemCategoryOptions: [], |
| 252 | list: [], | 291 | list: [], |
| @@ -285,11 +324,19 @@ export default { | @@ -285,11 +324,19 @@ export default { | ||
| 285 | }, | 324 | }, |
| 286 | created() { | 325 | created() { |
| 287 | this.setDefaultTimeRange() | 326 | this.setDefaultTimeRange() |
| 288 | - this.initStoreOptions() | 327 | + this.loadAllStores() |
| 289 | this.initItemOptions() | 328 | this.initItemOptions() |
| 290 | this.initItemCategoryOptions() | 329 | this.initItemCategoryOptions() |
| 291 | this.search() | 330 | this.search() |
| 292 | }, | 331 | }, |
| 332 | + watch: { | ||
| 333 | + // 监听开始时间变化,重新加载门店列表 | ||
| 334 | + 'query.StartTime'() { | ||
| 335 | + this.$nextTick(() => { | ||
| 336 | + this.initStoreOptions() | ||
| 337 | + }) | ||
| 338 | + } | ||
| 339 | + }, | ||
| 293 | methods: { | 340 | methods: { |
| 294 | // 设置默认时间范围(本月1号到现在) | 341 | // 设置默认时间范围(本月1号到现在) |
| 295 | setDefaultTimeRange() { | 342 | setDefaultTimeRange() { |
| @@ -297,10 +344,17 @@ export default { | @@ -297,10 +344,17 @@ export default { | ||
| 297 | const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1) | 344 | const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1) |
| 298 | this.query.StartTime = this.formatDate(firstDayOfMonth) | 345 | this.query.StartTime = this.formatDate(firstDayOfMonth) |
| 299 | this.query.EndTime = this.formatDate(now) | 346 | this.query.EndTime = this.formatDate(now) |
| 347 | + | ||
| 348 | + // 时间设置后,如果有组织类型和部门,重新加载门店列表 | ||
| 349 | + if (this.query.organizationType && this.query.departmentId) { | ||
| 350 | + this.$nextTick(() => { | ||
| 351 | + this.initStoreOptions() | ||
| 352 | + }) | ||
| 353 | + } | ||
| 300 | }, | 354 | }, |
| 301 | 355 | ||
| 302 | - // 初始化门店选项 | ||
| 303 | - initStoreOptions() { | 356 | + // 加载全部门店(当没有选择部门时) |
| 357 | + loadAllStores() { | ||
| 304 | request({ | 358 | request({ |
| 305 | url: '/api/Extend/LqMdxx', | 359 | url: '/api/Extend/LqMdxx', |
| 306 | method: 'GET', | 360 | method: 'GET', |
| @@ -317,6 +371,123 @@ export default { | @@ -317,6 +371,123 @@ export default { | ||
| 317 | }) | 371 | }) |
| 318 | }, | 372 | }, |
| 319 | 373 | ||
| 374 | + // 获取部门选项(根据组织类型) | ||
| 375 | + loadDepartmentOptions() { | ||
| 376 | + if (!this.query.organizationType) { | ||
| 377 | + this.departmentOptions = [] | ||
| 378 | + return | ||
| 379 | + } | ||
| 380 | + | ||
| 381 | + request({ | ||
| 382 | + url: '/api/Extend/Organize/GetByName', | ||
| 383 | + method: 'GET', | ||
| 384 | + data: { | ||
| 385 | + organizeName: this.query.organizationType | ||
| 386 | + } | ||
| 387 | + }).then(res => { | ||
| 388 | + this.departmentOptions = res.data || [] | ||
| 389 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 390 | + if (this.query.departmentId) { | ||
| 391 | + const exists = this.departmentOptions.some( | ||
| 392 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 393 | + ) | ||
| 394 | + if (!exists) { | ||
| 395 | + this.query.departmentId = undefined | ||
| 396 | + this.query.StoreIds = [] | ||
| 397 | + this.storeOptions = [] | ||
| 398 | + } | ||
| 399 | + } | ||
| 400 | + }).catch(() => { | ||
| 401 | + this.departmentOptions = [] | ||
| 402 | + }) | ||
| 403 | + }, | ||
| 404 | + | ||
| 405 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 406 | + initStoreOptions() { | ||
| 407 | + // 如果没有选择部门,加载全部门店 | ||
| 408 | + if (!this.query.departmentId) { | ||
| 409 | + this.loadAllStores() | ||
| 410 | + return | ||
| 411 | + } | ||
| 412 | + | ||
| 413 | + // 如果缺少必要参数,不加载门店列表 | ||
| 414 | + if (!this.query.organizationType || !this.query.StartTime) { | ||
| 415 | + this.storeOptions = [] | ||
| 416 | + return | ||
| 417 | + } | ||
| 418 | + | ||
| 419 | + // 从开始时间提取年月(格式:YYYYMM) | ||
| 420 | + // StartTime 格式为 yyyy-MM-dd | ||
| 421 | + const dateStr = this.query.StartTime | ||
| 422 | + if (!dateStr) { | ||
| 423 | + this.storeOptions = [] | ||
| 424 | + return | ||
| 425 | + } | ||
| 426 | + | ||
| 427 | + // 提取年月,格式:YYYYMM | ||
| 428 | + const monthStr = dateStr.substring(0, 4) + dateStr.substring(5, 7) | ||
| 429 | + | ||
| 430 | + request({ | ||
| 431 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 432 | + method: 'POST', | ||
| 433 | + data: { | ||
| 434 | + month: monthStr, | ||
| 435 | + organizationType: this.query.organizationType, | ||
| 436 | + departmentId: this.query.departmentId | ||
| 437 | + } | ||
| 438 | + }).then(res => { | ||
| 439 | + if (res.data && Array.isArray(res.data)) { | ||
| 440 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 441 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 442 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 443 | + this.storeOptions = res.data.map(store => ({ | ||
| 444 | + id: store.StoreId, | ||
| 445 | + dm: store.StoreName | ||
| 446 | + })) | ||
| 447 | + // 默认选中所有获取到的门店 | ||
| 448 | + this.query.StoreIds = this.storeOptions.map(store => store.id) | ||
| 449 | + } else { | ||
| 450 | + this.storeOptions = [] | ||
| 451 | + this.query.StoreIds = [] | ||
| 452 | + } | ||
| 453 | + }).catch(err => { | ||
| 454 | + console.error('获取门店列表失败:', err) | ||
| 455 | + this.$message({ | ||
| 456 | + type: 'error', | ||
| 457 | + message: '获取门店列表失败', | ||
| 458 | + duration: 1500 | ||
| 459 | + }) | ||
| 460 | + this.storeOptions = [] | ||
| 461 | + this.query.StoreIds = [] | ||
| 462 | + }) | ||
| 463 | + }, | ||
| 464 | + | ||
| 465 | + // 处理开始时间变化 | ||
| 466 | + handleStartTimeChange() { | ||
| 467 | + this.$nextTick(() => { | ||
| 468 | + this.initStoreOptions() | ||
| 469 | + }) | ||
| 470 | + }, | ||
| 471 | + | ||
| 472 | + // 处理组织类型变化 | ||
| 473 | + handleOrganizationTypeChange() { | ||
| 474 | + // 清空部门和门店 | ||
| 475 | + this.query.departmentId = undefined | ||
| 476 | + this.query.StoreIds = [] | ||
| 477 | + // 重新加载部门选项 | ||
| 478 | + this.loadDepartmentOptions() | ||
| 479 | + // 加载全部门店(因为部门已清空) | ||
| 480 | + this.loadAllStores() | ||
| 481 | + }, | ||
| 482 | + | ||
| 483 | + // 处理部门变化 | ||
| 484 | + handleDepartmentChange() { | ||
| 485 | + // 清空门店选择 | ||
| 486 | + this.query.StoreIds = [] | ||
| 487 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 488 | + this.initStoreOptions() | ||
| 489 | + }, | ||
| 490 | + | ||
| 320 | // 初始化品项选项 | 491 | // 初始化品项选项 |
| 321 | initItemOptions() { | 492 | initItemOptions() { |
| 322 | request({ | 493 | request({ |
| @@ -367,8 +538,8 @@ export default { | @@ -367,8 +538,8 @@ export default { | ||
| 367 | params.ItemId = this.query.ItemId | 538 | params.ItemId = this.query.ItemId |
| 368 | } | 539 | } |
| 369 | 540 | ||
| 370 | - if (this.query.StoreId) { | ||
| 371 | - params.StoreId = this.query.StoreId | 541 | + if (this.query.StoreIds && this.query.StoreIds.length > 0) { |
| 542 | + params.StoreIds = this.query.StoreIds | ||
| 372 | } | 543 | } |
| 373 | 544 | ||
| 374 | if (this.query.StartTime) { | 545 | if (this.query.StartTime) { |
| @@ -427,7 +598,9 @@ export default { | @@ -427,7 +598,9 @@ export default { | ||
| 427 | // 重置查询条件 | 598 | // 重置查询条件 |
| 428 | reset() { | 599 | reset() { |
| 429 | this.query = { | 600 | this.query = { |
| 430 | - StoreId: undefined, | 601 | + organizationType: undefined, |
| 602 | + departmentId: undefined, | ||
| 603 | + StoreIds: [], | ||
| 431 | StartTime: undefined, | 604 | StartTime: undefined, |
| 432 | EndTime: undefined, | 605 | EndTime: undefined, |
| 433 | ItemId: undefined, | 606 | ItemId: undefined, |
| @@ -436,6 +609,9 @@ export default { | @@ -436,6 +609,9 @@ export default { | ||
| 436 | MaxAmount: undefined | 609 | MaxAmount: undefined |
| 437 | } | 610 | } |
| 438 | this.setDefaultTimeRange() | 611 | this.setDefaultTimeRange() |
| 612 | + this.departmentOptions = [] | ||
| 613 | + // 重置后加载全部门店 | ||
| 614 | + this.loadAllStores() | ||
| 439 | this.listQuery.currentPage = 1 | 615 | this.listQuery.currentPage = 1 |
| 440 | this.listQuery.pageSize = 10 | 616 | this.listQuery.pageSize = 10 |
| 441 | this.list = [] | 617 | this.list = [] |
antis-ncc-admin/src/views/statisticsList/form20.vue
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | <div class="NCC-common-layout-center"> | 3 | <div class="NCC-common-layout-center"> |
| 4 | <!-- 筛选条件 --> | 4 | <!-- 筛选条件 --> |
| 5 | <el-row class="NCC-common-search-box" :gutter="16"> | 5 | <el-row class="NCC-common-search-box" :gutter="16"> |
| 6 | - <el-form @submit.native.prevent label-width="80px"> | 6 | + <el-form @submit.native.prevent > |
| 7 | <el-col :span="6"> | 7 | <el-col :span="6"> |
| 8 | <el-form-item label="选择月份"> | 8 | <el-form-item label="选择月份"> |
| 9 | <el-date-picker | 9 | <el-date-picker |
| @@ -17,6 +17,23 @@ | @@ -17,6 +17,23 @@ | ||
| 17 | </el-form-item> | 17 | </el-form-item> |
| 18 | </el-col> | 18 | </el-col> |
| 19 | <el-col :span="6"> | 19 | <el-col :span="6"> |
| 20 | + <el-form-item label="部门"> | ||
| 21 | + <el-select | ||
| 22 | + v-model="query.departmentId" | ||
| 23 | + placeholder="请选择部门" | ||
| 24 | + filterable | ||
| 25 | + clearable | ||
| 26 | + style="width: 100%;"> | ||
| 27 | + <el-option | ||
| 28 | + v-for="dept in departmentOptions" | ||
| 29 | + :key="dept.Id || dept.id" | ||
| 30 | + :label="dept.FullName || dept.fullName" | ||
| 31 | + :value="dept.Id || dept.id"> | ||
| 32 | + </el-option> | ||
| 33 | + </el-select> | ||
| 34 | + </el-form-item> | ||
| 35 | + </el-col> | ||
| 36 | + <el-col :span="6"> | ||
| 20 | <el-form-item label-width="0"> | 37 | <el-form-item label-width="0"> |
| 21 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | 38 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 22 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | 39 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| @@ -139,14 +156,16 @@ export default { | @@ -139,14 +156,16 @@ export default { | ||
| 139 | data() { | 156 | data() { |
| 140 | return { | 157 | return { |
| 141 | query: { | 158 | query: { |
| 142 | - month: '' | 159 | + month: '', |
| 160 | + departmentId: '' | ||
| 143 | }, | 161 | }, |
| 144 | list: [], | 162 | list: [], |
| 145 | originalList: [], // 保存原始数据,用于取消排序时恢复 | 163 | originalList: [], // 保存原始数据,用于取消排序时恢复 |
| 146 | listLoading: false, | 164 | listLoading: false, |
| 147 | summaryData: null, | 165 | summaryData: null, |
| 148 | sortProp: '', | 166 | sortProp: '', |
| 149 | - sortOrder: '' | 167 | + sortOrder: '', |
| 168 | + departmentOptions: [] // 部门选项列表 | ||
| 150 | } | 169 | } |
| 151 | }, | 170 | }, |
| 152 | computed: { | 171 | computed: { |
| @@ -158,6 +177,7 @@ export default { | @@ -158,6 +177,7 @@ export default { | ||
| 158 | }, | 177 | }, |
| 159 | created() { | 178 | created() { |
| 160 | this.setDefaultMonth() | 179 | this.setDefaultMonth() |
| 180 | + this.loadDepartmentOptions() | ||
| 161 | this.search() | 181 | this.search() |
| 162 | }, | 182 | }, |
| 163 | methods: { | 183 | methods: { |
| @@ -190,6 +210,11 @@ export default { | @@ -190,6 +210,11 @@ export default { | ||
| 190 | Month: parseInt(month) | 210 | Month: parseInt(month) |
| 191 | } | 211 | } |
| 192 | 212 | ||
| 213 | + // 如果选择了部门,添加部门筛选参数 | ||
| 214 | + if (this.query.departmentId) { | ||
| 215 | + params.DepartmentId = this.query.departmentId | ||
| 216 | + } | ||
| 217 | + | ||
| 193 | request({ | 218 | request({ |
| 194 | url: '/api/Extend/lqtechteachersalary/statistics', | 219 | url: '/api/Extend/lqtechteachersalary/statistics', |
| 195 | method: 'GET', | 220 | method: 'GET', |
| @@ -306,6 +331,7 @@ export default { | @@ -306,6 +331,7 @@ export default { | ||
| 306 | // 重置查询条件 | 331 | // 重置查询条件 |
| 307 | reset() { | 332 | reset() { |
| 308 | this.setDefaultMonth() | 333 | this.setDefaultMonth() |
| 334 | + this.query.departmentId = '' | ||
| 309 | this.list = [] | 335 | this.list = [] |
| 310 | this.originalList = [] | 336 | this.originalList = [] |
| 311 | this.summaryData = null | 337 | this.summaryData = null |
| @@ -314,6 +340,21 @@ export default { | @@ -314,6 +340,21 @@ export default { | ||
| 314 | this.search() | 340 | this.search() |
| 315 | }, | 341 | }, |
| 316 | 342 | ||
| 343 | + // 加载部门选项(科技部) | ||
| 344 | + loadDepartmentOptions() { | ||
| 345 | + request({ | ||
| 346 | + url: '/api/Extend/Organize/GetByName', | ||
| 347 | + method: 'GET', | ||
| 348 | + data: { | ||
| 349 | + organizeName: '科技部' | ||
| 350 | + } | ||
| 351 | + }).then(res => { | ||
| 352 | + this.departmentOptions = res.data || [] | ||
| 353 | + }).catch(() => { | ||
| 354 | + this.departmentOptions = [] | ||
| 355 | + }) | ||
| 356 | + }, | ||
| 357 | + | ||
| 317 | // 格式化金额 | 358 | // 格式化金额 |
| 318 | formatMoney(amount) { | 359 | formatMoney(amount) { |
| 319 | if (amount === null || amount === undefined || amount === '') { | 360 | if (amount === null || amount === undefined || amount === '') { |
antis-ncc-admin/src/views/statisticsList/form21.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <div class="NCC-common-layout"> | ||
| 3 | + <div class="NCC-common-layout-center"> | ||
| 4 | + <!-- 筛选条件 --> | ||
| 5 | + <el-row class="NCC-common-search-box" :gutter="16"> | ||
| 6 | + <el-form @submit.native.prevent> | ||
| 7 | + <el-col :span="6"> | ||
| 8 | + <el-form-item label="会员"> | ||
| 9 | + <el-select | ||
| 10 | + v-model="query.memberId" | ||
| 11 | + placeholder="请选择会员" | ||
| 12 | + filterable | ||
| 13 | + remote | ||
| 14 | + :remote-method="remoteMemberMethod" | ||
| 15 | + :loading="memberLoading" | ||
| 16 | + clearable | ||
| 17 | + :style='{"width":"100%"}'> | ||
| 18 | + <el-option | ||
| 19 | + v-for="item in memberOptions" | ||
| 20 | + :key="item.id" | ||
| 21 | + :label="`${item.khmc || ''}(${item.sjh || ''})`" | ||
| 22 | + :value="item.id"> | ||
| 23 | + </el-option> | ||
| 24 | + </el-select> | ||
| 25 | + </el-form-item> | ||
| 26 | + </el-col> | ||
| 27 | + <el-col :span="6"> | ||
| 28 | + <el-form-item label="开始时间"> | ||
| 29 | + <el-date-picker | ||
| 30 | + v-model="query.startTime" | ||
| 31 | + type="datetime" | ||
| 32 | + value-format="yyyy-MM-dd HH:mm:ss" | ||
| 33 | + format="yyyy-MM-dd HH:mm:ss" | ||
| 34 | + placeholder="开始时间" | ||
| 35 | + :style='{"width":"100%"}' | ||
| 36 | + @change="handleStartTimeChange" /> | ||
| 37 | + </el-form-item> | ||
| 38 | + </el-col> | ||
| 39 | + <el-col :span="6"> | ||
| 40 | + <el-form-item label="结束时间"> | ||
| 41 | + <el-date-picker | ||
| 42 | + v-model="query.endTime" | ||
| 43 | + type="datetime" | ||
| 44 | + value-format="yyyy-MM-dd HH:mm:ss" | ||
| 45 | + format="yyyy-MM-dd HH:mm:ss" | ||
| 46 | + placeholder="结束时间" | ||
| 47 | + :style='{"width":"100%"}' /> | ||
| 48 | + </el-form-item> | ||
| 49 | + </el-col> | ||
| 50 | + <el-col :span="6"> | ||
| 51 | + <el-form-item label="品项"> | ||
| 52 | + <el-select | ||
| 53 | + v-model="query.itemId" | ||
| 54 | + placeholder="请选择品项" | ||
| 55 | + filterable | ||
| 56 | + clearable | ||
| 57 | + :style='{"width":"100%"}'> | ||
| 58 | + <el-option | ||
| 59 | + v-for="item in itemOptions" | ||
| 60 | + :key="item.id" | ||
| 61 | + :label="item.xmmc" | ||
| 62 | + :value="item.id"> | ||
| 63 | + </el-option> | ||
| 64 | + </el-select> | ||
| 65 | + </el-form-item> | ||
| 66 | + </el-col> | ||
| 67 | + <el-col :span="6"> | ||
| 68 | + <el-form-item label="业绩类型"> | ||
| 69 | + <el-select | ||
| 70 | + v-model="query.performanceType" | ||
| 71 | + placeholder="请选择业绩类型" | ||
| 72 | + filterable | ||
| 73 | + clearable | ||
| 74 | + :style='{"width":"100%"}'> | ||
| 75 | + <el-option | ||
| 76 | + v-for="item in performanceTypeOptions" | ||
| 77 | + :key="item.value" | ||
| 78 | + :label="item.label" | ||
| 79 | + :value="item.value"> | ||
| 80 | + </el-option> | ||
| 81 | + </el-select> | ||
| 82 | + </el-form-item> | ||
| 83 | + </el-col> | ||
| 84 | + <el-col :span="6"> | ||
| 85 | + <el-form-item label="科美类型"> | ||
| 86 | + <el-select | ||
| 87 | + v-model="query.beautyType" | ||
| 88 | + placeholder="请选择科美类型" | ||
| 89 | + filterable | ||
| 90 | + clearable | ||
| 91 | + :style='{"width":"100%"}'> | ||
| 92 | + <el-option | ||
| 93 | + v-for="item in beautyTypeOptions" | ||
| 94 | + :key="item.value" | ||
| 95 | + :label="item.label" | ||
| 96 | + :value="item.value"> | ||
| 97 | + </el-option> | ||
| 98 | + </el-select> | ||
| 99 | + </el-form-item> | ||
| 100 | + </el-col> | ||
| 101 | + <el-col :span="6"> | ||
| 102 | + <el-form-item label="来源类型"> | ||
| 103 | + <el-select | ||
| 104 | + v-model="query.sourceType" | ||
| 105 | + placeholder="请选择来源类型" | ||
| 106 | + clearable | ||
| 107 | + :style='{"width":"100%"}'> | ||
| 108 | + <el-option label="购买" value="购买" /> | ||
| 109 | + <el-option label="赠送" value="赠送" /> | ||
| 110 | + <el-option label="体验" value="体验" /> | ||
| 111 | + </el-select> | ||
| 112 | + </el-form-item> | ||
| 113 | + </el-col> | ||
| 114 | + <el-col :span="6"> | ||
| 115 | + <el-form-item label="品项分类"> | ||
| 116 | + <el-select | ||
| 117 | + v-model="query.itemCategory" | ||
| 118 | + placeholder="请选择品项分类" | ||
| 119 | + filterable | ||
| 120 | + clearable | ||
| 121 | + :style='{"width":"100%"}'> | ||
| 122 | + <el-option | ||
| 123 | + v-for="item in itemCategoryOptions" | ||
| 124 | + :key="item.value" | ||
| 125 | + :label="item.label" | ||
| 126 | + :value="item.value"> | ||
| 127 | + </el-option> | ||
| 128 | + </el-select> | ||
| 129 | + </el-form-item> | ||
| 130 | + </el-col> | ||
| 131 | + <el-col :span="6"> | ||
| 132 | + <el-form-item label="组织类型"> | ||
| 133 | + <el-select | ||
| 134 | + v-model="query.organizationType" | ||
| 135 | + placeholder="请选择组织类型" | ||
| 136 | + filterable | ||
| 137 | + clearable | ||
| 138 | + @change="handleOrganizationTypeChange" | ||
| 139 | + :style='{"width":"100%"}'> | ||
| 140 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 141 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 142 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 143 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 144 | + </el-select> | ||
| 145 | + </el-form-item> | ||
| 146 | + </el-col> | ||
| 147 | + <el-col :span="6"> | ||
| 148 | + <el-form-item label="部门"> | ||
| 149 | + <el-select | ||
| 150 | + v-model="query.departmentId" | ||
| 151 | + placeholder="请选择部门" | ||
| 152 | + filterable | ||
| 153 | + clearable | ||
| 154 | + @change="handleDepartmentChange" | ||
| 155 | + :style='{"width":"100%"}'> | ||
| 156 | + <el-option | ||
| 157 | + v-for="dept in departmentOptions" | ||
| 158 | + :key="dept.Id || dept.id" | ||
| 159 | + :label="dept.FullName || dept.fullName" | ||
| 160 | + :value="dept.Id || dept.id"> | ||
| 161 | + </el-option> | ||
| 162 | + </el-select> | ||
| 163 | + </el-form-item> | ||
| 164 | + </el-col> | ||
| 165 | + <el-col :span="12"> | ||
| 166 | + <el-form-item label="门店"> | ||
| 167 | + <el-select | ||
| 168 | + v-model="query.storeIds" | ||
| 169 | + placeholder="请选择门店" | ||
| 170 | + multiple | ||
| 171 | + filterable | ||
| 172 | + clearable | ||
| 173 | + :style='{"width":"100%"}'> | ||
| 174 | + <el-option | ||
| 175 | + v-for="store in storeOptions" | ||
| 176 | + :key="store.id" | ||
| 177 | + :label="store.dm" | ||
| 178 | + :value="store.id"> | ||
| 179 | + </el-option> | ||
| 180 | + </el-select> | ||
| 181 | + </el-form-item> | ||
| 182 | + </el-col> | ||
| 183 | + <el-col :span="6"> | ||
| 184 | + <el-form-item label-width="0"> | ||
| 185 | + <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | ||
| 186 | + <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | ||
| 187 | + <el-button icon="el-icon-download" @click="exportExcel()">导出Excel</el-button> | ||
| 188 | + </el-form-item> | ||
| 189 | + </el-col> | ||
| 190 | + </el-form> | ||
| 191 | + </el-row> | ||
| 192 | + | ||
| 193 | + <!-- 数据表格 --> | ||
| 194 | + <div class="NCC-common-layout-main NCC-flex-main"> | ||
| 195 | + <NCC-table | ||
| 196 | + v-loading="listLoading" | ||
| 197 | + :data="list" | ||
| 198 | + has-c | ||
| 199 | + @sort-change="handleSortChange"> | ||
| 200 | + <el-table-column prop="storeName" label="门店名称" min-width="120" sortable="custom"> | ||
| 201 | + <template slot-scope="scope"> | ||
| 202 | + <i class="el-icon-shop" style="margin-right: 4px; color: #409EFF;"></i> | ||
| 203 | + <span>{{ scope.row.storeName || '无' }}</span> | ||
| 204 | + </template> | ||
| 205 | + </el-table-column> | ||
| 206 | + <el-table-column prop="memberName" label="会员名称" min-width="120" sortable="custom"> | ||
| 207 | + <template slot-scope="scope"> | ||
| 208 | + <i class="el-icon-user" style="margin-right: 4px; color: #409EFF;"></i> | ||
| 209 | + <span>{{ scope.row.memberName || '无' }}</span> | ||
| 210 | + </template> | ||
| 211 | + </el-table-column> | ||
| 212 | + <el-table-column prop="memberPhone" label="会员电话" min-width="130" sortable="custom"> | ||
| 213 | + <template slot-scope="scope"> | ||
| 214 | + <i class="el-icon-phone" style="margin-right: 4px; color: #67C23A;"></i> | ||
| 215 | + <span>{{ scope.row.memberPhone || '无' }}</span> | ||
| 216 | + </template> | ||
| 217 | + </el-table-column> | ||
| 218 | + <el-table-column prop="refundTime" label="退卡时间" min-width="160" sortable="custom"> | ||
| 219 | + <template slot-scope="scope"> | ||
| 220 | + <i class="el-icon-time" style="margin-right: 4px; color: #909399;"></i> | ||
| 221 | + <span>{{ formatDateTime(scope.row.refundTime) || '无' }}</span> | ||
| 222 | + </template> | ||
| 223 | + </el-table-column> | ||
| 224 | + <el-table-column prop="itemName" label="退卡品项名称" min-width="150" sortable="custom"> | ||
| 225 | + <template slot-scope="scope"> | ||
| 226 | + <i class="el-icon-goods" style="margin-right: 4px; color: #E6A23C;"></i> | ||
| 227 | + <span>{{ scope.row.itemName || '无' }}</span> | ||
| 228 | + </template> | ||
| 229 | + </el-table-column> | ||
| 230 | + <el-table-column prop="refundQuantity" label="退卡数量" width="100" sortable="custom"> | ||
| 231 | + <template slot-scope="scope"> | ||
| 232 | + <span>{{ scope.row.refundQuantity || 0 }}</span> | ||
| 233 | + </template> | ||
| 234 | + </el-table-column> | ||
| 235 | + <el-table-column prop="unitPrice" label="单价" min-width="100" sortable="custom"> | ||
| 236 | + <template slot-scope="scope"> | ||
| 237 | + <span class="amount-value">¥{{ formatMoney(scope.row.unitPrice) }}</span> | ||
| 238 | + </template> | ||
| 239 | + </el-table-column> | ||
| 240 | + <el-table-column prop="totalPrice" label="总价" min-width="120" sortable="custom"> | ||
| 241 | + <template slot-scope="scope"> | ||
| 242 | + <span class="amount-value">¥{{ formatMoney(scope.row.totalPrice) }}</span> | ||
| 243 | + </template> | ||
| 244 | + </el-table-column> | ||
| 245 | + <el-table-column prop="performanceType" label="业绩类型" min-width="100"> | ||
| 246 | + <template slot-scope="scope"> | ||
| 247 | + <span>{{ scope.row.performanceType || '无' }}</span> | ||
| 248 | + </template> | ||
| 249 | + </el-table-column> | ||
| 250 | + <el-table-column prop="beautyType" label="科美类型" min-width="100"> | ||
| 251 | + <template slot-scope="scope"> | ||
| 252 | + <span>{{ scope.row.beautyType || '无' }}</span> | ||
| 253 | + </template> | ||
| 254 | + </el-table-column> | ||
| 255 | + <el-table-column prop="sourceType" label="来源类型" min-width="100"> | ||
| 256 | + <template slot-scope="scope"> | ||
| 257 | + <el-tag | ||
| 258 | + :type="getSourceTypeTagType(scope.row.sourceType)" | ||
| 259 | + size="small"> | ||
| 260 | + {{ scope.row.sourceType || '无' }} | ||
| 261 | + </el-tag> | ||
| 262 | + </template> | ||
| 263 | + </el-table-column> | ||
| 264 | + <el-table-column prop="itemCategory" label="品项分类" min-width="100"> | ||
| 265 | + <template slot-scope="scope"> | ||
| 266 | + <el-tag | ||
| 267 | + :type="getItemCategoryType(scope.row.itemCategory)" | ||
| 268 | + size="small"> | ||
| 269 | + {{ scope.row.itemCategory || '无' }} | ||
| 270 | + </el-tag> | ||
| 271 | + </template> | ||
| 272 | + </el-table-column> | ||
| 273 | + </NCC-table> | ||
| 274 | + <pagination | ||
| 275 | + v-show="total > 0" | ||
| 276 | + :total="total" | ||
| 277 | + :page.sync="listQuery.currentPage" | ||
| 278 | + :limit.sync="listQuery.pageSize" | ||
| 279 | + @pagination="handlePagination" | ||
| 280 | + /> | ||
| 281 | + </div> | ||
| 282 | + </div> | ||
| 283 | + </div> | ||
| 284 | +</template> | ||
| 285 | + | ||
| 286 | +<script> | ||
| 287 | +import request from '@/utils/request' | ||
| 288 | +import Pagination from '@/components/Pagination' | ||
| 289 | +import { saveAs } from 'file-saver' | ||
| 290 | + | ||
| 291 | +export default { | ||
| 292 | + name: 'RefundDetailList', | ||
| 293 | + components: { | ||
| 294 | + Pagination | ||
| 295 | + }, | ||
| 296 | + data() { | ||
| 297 | + return { | ||
| 298 | + query: { | ||
| 299 | + organizationType: undefined, | ||
| 300 | + departmentId: undefined, | ||
| 301 | + storeIds: [], | ||
| 302 | + memberId: undefined, | ||
| 303 | + startTime: undefined, | ||
| 304 | + endTime: undefined, | ||
| 305 | + itemId: undefined, | ||
| 306 | + performanceType: undefined, | ||
| 307 | + beautyType: undefined, | ||
| 308 | + sourceType: undefined, | ||
| 309 | + itemCategory: undefined | ||
| 310 | + }, | ||
| 311 | + storeOptions: [], | ||
| 312 | + departmentOptions: [], | ||
| 313 | + memberOptions: [], | ||
| 314 | + memberLoading: false, | ||
| 315 | + itemOptions: [], | ||
| 316 | + performanceTypeOptions: [], | ||
| 317 | + beautyTypeOptions: [], | ||
| 318 | + itemCategoryOptions: [], | ||
| 319 | + list: [], | ||
| 320 | + listLoading: false, | ||
| 321 | + total: 0, | ||
| 322 | + listQuery: { | ||
| 323 | + currentPage: 1, | ||
| 324 | + pageSize: 20 | ||
| 325 | + }, | ||
| 326 | + sortProp: '', | ||
| 327 | + sortOrder: '' | ||
| 328 | + } | ||
| 329 | + }, | ||
| 330 | + created() { | ||
| 331 | + this.setDefaultTimeRange() | ||
| 332 | + this.loadAllStores() | ||
| 333 | + this.initMemberOptions() | ||
| 334 | + this.initItemOptions() | ||
| 335 | + this.initPerformanceTypeOptions() | ||
| 336 | + this.initBeautyTypeOptions() | ||
| 337 | + this.initItemCategoryOptions() | ||
| 338 | + this.search() | ||
| 339 | + }, | ||
| 340 | + watch: { | ||
| 341 | + // 监听开始时间变化,重新加载门店列表 | ||
| 342 | + 'query.startTime'() { | ||
| 343 | + this.$nextTick(() => { | ||
| 344 | + this.initStoreOptions() | ||
| 345 | + }) | ||
| 346 | + } | ||
| 347 | + }, | ||
| 348 | + methods: { | ||
| 349 | + // 设置默认时间范围(本月1号到现在) | ||
| 350 | + setDefaultTimeRange() { | ||
| 351 | + const now = new Date() | ||
| 352 | + const firstDayOfMonth = new Date(now.getFullYear(), now.getMonth(), 1) | ||
| 353 | + | ||
| 354 | + this.query.startTime = this.formatDateTime(firstDayOfMonth.getTime()) | ||
| 355 | + this.query.endTime = this.formatDateTime(now.getTime()) | ||
| 356 | + | ||
| 357 | + // 时间设置后,如果有组织类型和部门,重新加载门店列表 | ||
| 358 | + if (this.query.organizationType && this.query.departmentId) { | ||
| 359 | + this.$nextTick(() => { | ||
| 360 | + this.initStoreOptions() | ||
| 361 | + }) | ||
| 362 | + } | ||
| 363 | + }, | ||
| 364 | + | ||
| 365 | + // 格式化日期时间 | ||
| 366 | + formatDateTime(timestamp) { | ||
| 367 | + if (!timestamp) return '' | ||
| 368 | + const date = new Date(timestamp) | ||
| 369 | + const year = date.getFullYear() | ||
| 370 | + const month = String(date.getMonth() + 1).padStart(2, '0') | ||
| 371 | + const day = String(date.getDate()).padStart(2, '0') | ||
| 372 | + const hours = String(date.getHours()).padStart(2, '0') | ||
| 373 | + const minutes = String(date.getMinutes()).padStart(2, '0') | ||
| 374 | + const seconds = String(date.getSeconds()).padStart(2, '0') | ||
| 375 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` | ||
| 376 | + }, | ||
| 377 | + | ||
| 378 | + // 加载全部门店(当没有选择部门时) | ||
| 379 | + loadAllStores() { | ||
| 380 | + request({ | ||
| 381 | + url: '/api/Extend/LqMdxx', | ||
| 382 | + method: 'GET', | ||
| 383 | + data: { | ||
| 384 | + currentPage: 1, | ||
| 385 | + pageSize: 1000 | ||
| 386 | + } | ||
| 387 | + }).then(res => { | ||
| 388 | + if (res.data && res.data.list) { | ||
| 389 | + this.storeOptions = res.data.list | ||
| 390 | + } | ||
| 391 | + }).catch(() => { | ||
| 392 | + this.storeOptions = [] | ||
| 393 | + }) | ||
| 394 | + }, | ||
| 395 | + | ||
| 396 | + // 获取部门选项(根据组织类型) | ||
| 397 | + loadDepartmentOptions() { | ||
| 398 | + if (!this.query.organizationType) { | ||
| 399 | + this.departmentOptions = [] | ||
| 400 | + return | ||
| 401 | + } | ||
| 402 | + | ||
| 403 | + request({ | ||
| 404 | + url: '/api/Extend/Organize/GetByName', | ||
| 405 | + method: 'GET', | ||
| 406 | + data: { | ||
| 407 | + organizeName: this.query.organizationType | ||
| 408 | + } | ||
| 409 | + }).then(res => { | ||
| 410 | + this.departmentOptions = res.data || [] | ||
| 411 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 412 | + if (this.query.departmentId) { | ||
| 413 | + const exists = this.departmentOptions.some( | ||
| 414 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 415 | + ) | ||
| 416 | + if (!exists) { | ||
| 417 | + this.query.departmentId = undefined | ||
| 418 | + this.query.storeIds = [] | ||
| 419 | + this.storeOptions = [] | ||
| 420 | + } | ||
| 421 | + } | ||
| 422 | + }).catch(() => { | ||
| 423 | + this.departmentOptions = [] | ||
| 424 | + }) | ||
| 425 | + }, | ||
| 426 | + | ||
| 427 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 428 | + initStoreOptions() { | ||
| 429 | + // 如果没有选择部门,加载全部门店 | ||
| 430 | + if (!this.query.departmentId) { | ||
| 431 | + this.loadAllStores() | ||
| 432 | + return | ||
| 433 | + } | ||
| 434 | + | ||
| 435 | + // 如果缺少必要参数,不加载门店列表 | ||
| 436 | + if (!this.query.organizationType || !this.query.startTime) { | ||
| 437 | + this.storeOptions = [] | ||
| 438 | + return | ||
| 439 | + } | ||
| 440 | + | ||
| 441 | + // 从开始时间提取年月(格式:YYYYMM) | ||
| 442 | + // startTime 格式为 yyyy-MM-dd HH:mm:ss | ||
| 443 | + const dateStr = this.query.startTime | ||
| 444 | + if (!dateStr) { | ||
| 445 | + this.storeOptions = [] | ||
| 446 | + return | ||
| 447 | + } | ||
| 448 | + | ||
| 449 | + // 提取年月,格式:YYYYMM | ||
| 450 | + const monthStr = dateStr.substring(0, 4) + dateStr.substring(5, 7) | ||
| 451 | + | ||
| 452 | + request({ | ||
| 453 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 454 | + method: 'POST', | ||
| 455 | + data: { | ||
| 456 | + month: monthStr, | ||
| 457 | + organizationType: this.query.organizationType, | ||
| 458 | + departmentId: this.query.departmentId | ||
| 459 | + } | ||
| 460 | + }).then(res => { | ||
| 461 | + if (res.data && Array.isArray(res.data)) { | ||
| 462 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 463 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 464 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 465 | + this.storeOptions = res.data.map(store => ({ | ||
| 466 | + id: store.StoreId, | ||
| 467 | + dm: store.StoreName | ||
| 468 | + })) | ||
| 469 | + // 默认选中所有获取到的门店 | ||
| 470 | + this.query.storeIds = this.storeOptions.map(store => store.id) | ||
| 471 | + } else { | ||
| 472 | + this.storeOptions = [] | ||
| 473 | + this.query.storeIds = [] | ||
| 474 | + } | ||
| 475 | + }).catch(err => { | ||
| 476 | + console.error('获取门店列表失败:', err) | ||
| 477 | + this.$message({ | ||
| 478 | + type: 'error', | ||
| 479 | + message: '获取门店列表失败', | ||
| 480 | + duration: 1500 | ||
| 481 | + }) | ||
| 482 | + this.storeOptions = [] | ||
| 483 | + this.query.storeIds = [] | ||
| 484 | + }) | ||
| 485 | + }, | ||
| 486 | + | ||
| 487 | + // 处理开始时间变化 | ||
| 488 | + handleStartTimeChange() { | ||
| 489 | + this.$nextTick(() => { | ||
| 490 | + this.initStoreOptions() | ||
| 491 | + }) | ||
| 492 | + }, | ||
| 493 | + | ||
| 494 | + // 处理组织类型变化 | ||
| 495 | + handleOrganizationTypeChange() { | ||
| 496 | + // 清空部门和门店 | ||
| 497 | + this.query.departmentId = undefined | ||
| 498 | + this.query.storeIds = [] | ||
| 499 | + // 重新加载部门选项 | ||
| 500 | + this.loadDepartmentOptions() | ||
| 501 | + // 加载全部门店(因为部门已清空) | ||
| 502 | + this.loadAllStores() | ||
| 503 | + }, | ||
| 504 | + | ||
| 505 | + // 处理部门变化 | ||
| 506 | + handleDepartmentChange() { | ||
| 507 | + // 清空门店选择 | ||
| 508 | + this.query.storeIds = [] | ||
| 509 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 510 | + this.initStoreOptions() | ||
| 511 | + }, | ||
| 512 | + | ||
| 513 | + // 初始化会员选项(加载前10个) | ||
| 514 | + initMemberOptions() { | ||
| 515 | + request({ | ||
| 516 | + url: '/api/Extend/LqKhxx', | ||
| 517 | + method: 'GET', | ||
| 518 | + data: { | ||
| 519 | + currentPage: 1, | ||
| 520 | + pageSize: 10 | ||
| 521 | + } | ||
| 522 | + }).then(res => { | ||
| 523 | + if (res.code == 200 && res.data && res.data.list) { | ||
| 524 | + this.memberOptions = res.data.list | ||
| 525 | + } else { | ||
| 526 | + this.memberOptions = [] | ||
| 527 | + } | ||
| 528 | + }).catch(() => { | ||
| 529 | + this.memberOptions = [] | ||
| 530 | + }) | ||
| 531 | + }, | ||
| 532 | + | ||
| 533 | + // 远程搜索会员 | ||
| 534 | + remoteMemberMethod(query) { | ||
| 535 | + if (query !== '') { | ||
| 536 | + this.memberLoading = true | ||
| 537 | + request({ | ||
| 538 | + url: '/api/Extend/LqKhxx', | ||
| 539 | + method: 'GET', | ||
| 540 | + data: { | ||
| 541 | + currentPage: 1, | ||
| 542 | + pageSize: 20, | ||
| 543 | + keyword: query | ||
| 544 | + } | ||
| 545 | + }).then(res => { | ||
| 546 | + this.memberLoading = false | ||
| 547 | + if (res.code == 200 && res.data && res.data.list) { | ||
| 548 | + this.memberOptions = res.data.list | ||
| 549 | + } else { | ||
| 550 | + this.memberOptions = [] | ||
| 551 | + } | ||
| 552 | + }).catch(() => { | ||
| 553 | + this.memberLoading = false | ||
| 554 | + this.memberOptions = [] | ||
| 555 | + }) | ||
| 556 | + } else { | ||
| 557 | + this.memberOptions = [] | ||
| 558 | + this.initMemberOptions() | ||
| 559 | + } | ||
| 560 | + }, | ||
| 561 | + | ||
| 562 | + // 初始化品项选项 | ||
| 563 | + initItemOptions() { | ||
| 564 | + request({ | ||
| 565 | + url: '/api/Extend/LqXmzl', | ||
| 566 | + method: 'GET', | ||
| 567 | + data: { | ||
| 568 | + currentPage: 1, | ||
| 569 | + pageSize: 1000 | ||
| 570 | + } | ||
| 571 | + }).then(res => { | ||
| 572 | + if (res.data && res.data.list) { | ||
| 573 | + this.itemOptions = res.data.list | ||
| 574 | + } | ||
| 575 | + }).catch(() => { | ||
| 576 | + this.itemOptions = [] | ||
| 577 | + }) | ||
| 578 | + }, | ||
| 579 | + | ||
| 580 | + // 初始化业绩类型选项(从品项表的fl3字段获取) | ||
| 581 | + initPerformanceTypeOptions() { | ||
| 582 | + request({ | ||
| 583 | + url: '/api/Extend/lqxmzl/GetDistinctFieldData', | ||
| 584 | + method: 'GET', | ||
| 585 | + data: { | ||
| 586 | + fieldName: 'fl3' | ||
| 587 | + } | ||
| 588 | + }).then(res => { | ||
| 589 | + if (res.code == 200 && res.data && res.data.values) { | ||
| 590 | + this.performanceTypeOptions = res.data.values.map(item => ({ | ||
| 591 | + label: item, | ||
| 592 | + value: item | ||
| 593 | + })) | ||
| 594 | + } else { | ||
| 595 | + this.performanceTypeOptions = [] | ||
| 596 | + } | ||
| 597 | + }).catch(() => { | ||
| 598 | + this.performanceTypeOptions = [] | ||
| 599 | + }) | ||
| 600 | + }, | ||
| 601 | + | ||
| 602 | + // 初始化科美类型选项(从品项表的beautyType字段获取) | ||
| 603 | + initBeautyTypeOptions() { | ||
| 604 | + request({ | ||
| 605 | + url: '/api/Extend/lqxmzl/GetDistinctFieldData', | ||
| 606 | + method: 'GET', | ||
| 607 | + data: { | ||
| 608 | + fieldName: 'beautyType' | ||
| 609 | + } | ||
| 610 | + }).then(res => { | ||
| 611 | + if (res.code == 200 && res.data && res.data.values) { | ||
| 612 | + this.beautyTypeOptions = res.data.values.map(item => ({ | ||
| 613 | + label: item, | ||
| 614 | + value: item | ||
| 615 | + })) | ||
| 616 | + } else { | ||
| 617 | + this.beautyTypeOptions = [] | ||
| 618 | + } | ||
| 619 | + }).catch(() => { | ||
| 620 | + this.beautyTypeOptions = [] | ||
| 621 | + }) | ||
| 622 | + }, | ||
| 623 | + | ||
| 624 | + // 初始化品项分类选项(从品项表的qt2字段获取) | ||
| 625 | + initItemCategoryOptions() { | ||
| 626 | + request({ | ||
| 627 | + url: '/api/Extend/lqxmzl/GetDistinctFieldData', | ||
| 628 | + method: 'GET', | ||
| 629 | + data: { | ||
| 630 | + fieldName: 'qt2' | ||
| 631 | + } | ||
| 632 | + }).then(res => { | ||
| 633 | + if (res.code == 200 && res.data && res.data.values) { | ||
| 634 | + this.itemCategoryOptions = res.data.values.map(item => ({ | ||
| 635 | + label: item, | ||
| 636 | + value: item | ||
| 637 | + })) | ||
| 638 | + } else { | ||
| 639 | + this.itemCategoryOptions = [] | ||
| 640 | + } | ||
| 641 | + }).catch(() => { | ||
| 642 | + this.itemCategoryOptions = [] | ||
| 643 | + }) | ||
| 644 | + }, | ||
| 645 | + | ||
| 646 | + // 查询数据 | ||
| 647 | + search() { | ||
| 648 | + this.listLoading = true | ||
| 649 | + | ||
| 650 | + const params = { | ||
| 651 | + currentPage: this.listQuery.currentPage, | ||
| 652 | + pageSize: this.listQuery.pageSize | ||
| 653 | + } | ||
| 654 | + | ||
| 655 | + if (this.query.storeIds && this.query.storeIds.length > 0) { | ||
| 656 | + params.storeIds = this.query.storeIds | ||
| 657 | + } | ||
| 658 | + | ||
| 659 | + if (this.query.memberId) { | ||
| 660 | + params.memberId = this.query.memberId | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + if (this.query.startTime) { | ||
| 664 | + params.startTime = this.query.startTime | ||
| 665 | + } | ||
| 666 | + | ||
| 667 | + if (this.query.endTime) { | ||
| 668 | + params.endTime = this.query.endTime | ||
| 669 | + } | ||
| 670 | + | ||
| 671 | + if (this.query.itemId) { | ||
| 672 | + params.itemId = this.query.itemId | ||
| 673 | + } | ||
| 674 | + | ||
| 675 | + if (this.query.performanceType) { | ||
| 676 | + params.performanceType = this.query.performanceType | ||
| 677 | + } | ||
| 678 | + | ||
| 679 | + if (this.query.beautyType) { | ||
| 680 | + params.beautyType = this.query.beautyType | ||
| 681 | + } | ||
| 682 | + | ||
| 683 | + if (this.query.sourceType) { | ||
| 684 | + params.sourceType = this.query.sourceType | ||
| 685 | + } | ||
| 686 | + | ||
| 687 | + if (this.query.itemCategory) { | ||
| 688 | + params.itemCategory = this.query.itemCategory | ||
| 689 | + } | ||
| 690 | + | ||
| 691 | + // 排序参数 | ||
| 692 | + if (this.sortProp) { | ||
| 693 | + params.sidx = this.sortProp | ||
| 694 | + params.sort = this.sortOrder === 'ascending' ? 'asc' : 'desc' | ||
| 695 | + } | ||
| 696 | + | ||
| 697 | + request({ | ||
| 698 | + url: '/api/Extend/LqHytkHytk/refund-detail-list', | ||
| 699 | + method: 'POST', | ||
| 700 | + data: params | ||
| 701 | + }).then(res => { | ||
| 702 | + if (res.data && res.data.list) { | ||
| 703 | + this.list = res.data.list | ||
| 704 | + this.total = (res.data.pagination && res.data.pagination.total) || res.data.list.length || 0 | ||
| 705 | + } else { | ||
| 706 | + this.list = [] | ||
| 707 | + this.total = 0 | ||
| 708 | + } | ||
| 709 | + this.listLoading = false | ||
| 710 | + }).catch(err => { | ||
| 711 | + console.error('查询失败:', err) | ||
| 712 | + this.$message({ | ||
| 713 | + type: 'error', | ||
| 714 | + message: '查询失败,请重试', | ||
| 715 | + duration: 1500 | ||
| 716 | + }) | ||
| 717 | + this.listLoading = false | ||
| 718 | + this.list = [] | ||
| 719 | + this.total = 0 | ||
| 720 | + }) | ||
| 721 | + }, | ||
| 722 | + | ||
| 723 | + // 处理排序变化 | ||
| 724 | + handleSortChange({ column, prop, order }) { | ||
| 725 | + this.sortProp = prop || '' | ||
| 726 | + this.sortOrder = order || '' | ||
| 727 | + this.listQuery.currentPage = 1 | ||
| 728 | + this.search() | ||
| 729 | + }, | ||
| 730 | + | ||
| 731 | + // 处理分页变化 | ||
| 732 | + handlePagination({ page, limit }) { | ||
| 733 | + this.listQuery.currentPage = page | ||
| 734 | + this.listQuery.pageSize = limit | ||
| 735 | + this.search() | ||
| 736 | + }, | ||
| 737 | + | ||
| 738 | + // 重置查询条件 | ||
| 739 | + reset() { | ||
| 740 | + this.query = { | ||
| 741 | + organizationType: undefined, | ||
| 742 | + departmentId: undefined, | ||
| 743 | + storeIds: [], | ||
| 744 | + memberId: undefined, | ||
| 745 | + startTime: undefined, | ||
| 746 | + endTime: undefined, | ||
| 747 | + itemId: undefined, | ||
| 748 | + performanceType: undefined, | ||
| 749 | + beautyType: undefined, | ||
| 750 | + sourceType: undefined, | ||
| 751 | + itemCategory: undefined | ||
| 752 | + } | ||
| 753 | + this.setDefaultTimeRange() | ||
| 754 | + this.departmentOptions = [] | ||
| 755 | + // 重置后加载全部门店 | ||
| 756 | + this.loadAllStores() | ||
| 757 | + this.sortProp = '' | ||
| 758 | + this.sortOrder = '' | ||
| 759 | + this.listQuery.currentPage = 1 | ||
| 760 | + this.listQuery.pageSize = 20 | ||
| 761 | + this.list = [] | ||
| 762 | + this.total = 0 | ||
| 763 | + this.search() | ||
| 764 | + }, | ||
| 765 | + | ||
| 766 | + // 格式化金额 | ||
| 767 | + formatMoney(amount) { | ||
| 768 | + if (amount === null || amount === undefined || amount === '') { | ||
| 769 | + return '0.00' | ||
| 770 | + } | ||
| 771 | + const num = parseFloat(amount) | ||
| 772 | + if (isNaN(num)) { | ||
| 773 | + return '0.00' | ||
| 774 | + } | ||
| 775 | + return num.toFixed(2) | ||
| 776 | + }, | ||
| 777 | + | ||
| 778 | + // 获取来源类型标签类型 | ||
| 779 | + getSourceTypeTagType(sourceType) { | ||
| 780 | + if (!sourceType) { | ||
| 781 | + return 'info' | ||
| 782 | + } | ||
| 783 | + if (sourceType === '购买') { | ||
| 784 | + return 'success' | ||
| 785 | + } else if (sourceType === '赠送') { | ||
| 786 | + return 'warning' | ||
| 787 | + } else if (sourceType === '体验') { | ||
| 788 | + return 'info' | ||
| 789 | + } | ||
| 790 | + return 'info' | ||
| 791 | + }, | ||
| 792 | + | ||
| 793 | + // 获取品项分类标签类型 | ||
| 794 | + getItemCategoryType(category) { | ||
| 795 | + if (!category) { | ||
| 796 | + return 'info' | ||
| 797 | + } | ||
| 798 | + const categoryMap = { | ||
| 799 | + '科美': 'success', | ||
| 800 | + '医美': 'warning', | ||
| 801 | + '生美': 'info', | ||
| 802 | + '产品': 'danger' | ||
| 803 | + } | ||
| 804 | + return categoryMap[category] || 'info' | ||
| 805 | + }, | ||
| 806 | + | ||
| 807 | + // 导出Excel | ||
| 808 | + async exportExcel() { | ||
| 809 | + if (!this.list || this.list.length === 0) { | ||
| 810 | + this.$message({ | ||
| 811 | + type: 'warning', | ||
| 812 | + message: '暂无数据可导出', | ||
| 813 | + duration: 1500 | ||
| 814 | + }) | ||
| 815 | + return | ||
| 816 | + } | ||
| 817 | + | ||
| 818 | + try { | ||
| 819 | + // 动态导入 xlsx 库 | ||
| 820 | + const XLSX = await import('xlsx') | ||
| 821 | + | ||
| 822 | + // 构建表头 | ||
| 823 | + const headers = [ | ||
| 824 | + '门店名称', | ||
| 825 | + '会员名称', | ||
| 826 | + '会员电话', | ||
| 827 | + '退卡时间', | ||
| 828 | + '退卡品项名称', | ||
| 829 | + '退卡数量', | ||
| 830 | + '单价', | ||
| 831 | + '总价', | ||
| 832 | + '业绩类型', | ||
| 833 | + '科美类型', | ||
| 834 | + '来源类型', | ||
| 835 | + '品项分类' | ||
| 836 | + ] | ||
| 837 | + | ||
| 838 | + // 构建数据行 | ||
| 839 | + const dataRows = this.list.map(row => [ | ||
| 840 | + row.storeName || '无', | ||
| 841 | + row.memberName || '无', | ||
| 842 | + row.memberPhone || '无', | ||
| 843 | + this.formatDateTime(row.refundTime) || '无', | ||
| 844 | + row.itemName || '无', | ||
| 845 | + row.refundQuantity || 0, | ||
| 846 | + this.formatMoney(row.unitPrice), | ||
| 847 | + this.formatMoney(row.totalPrice), | ||
| 848 | + row.performanceType || '无', | ||
| 849 | + row.beautyType || '无', | ||
| 850 | + row.sourceType || '无', | ||
| 851 | + row.itemCategory || '无' | ||
| 852 | + ]) | ||
| 853 | + | ||
| 854 | + // 合并表头和数据 | ||
| 855 | + const excelData = [headers, ...dataRows] | ||
| 856 | + | ||
| 857 | + // 创建工作簿 | ||
| 858 | + const ws = XLSX.utils.aoa_to_sheet(excelData) | ||
| 859 | + | ||
| 860 | + // 设置列宽 | ||
| 861 | + ws['!cols'] = [ | ||
| 862 | + { wch: 15 }, // 门店名称 | ||
| 863 | + { wch: 12 }, // 会员名称 | ||
| 864 | + { wch: 13 }, // 会员电话 | ||
| 865 | + { wch: 18 }, // 退卡时间 | ||
| 866 | + { wch: 20 }, // 退卡品项名称 | ||
| 867 | + { wch: 10 }, // 退卡数量 | ||
| 868 | + { wch: 12 }, // 单价 | ||
| 869 | + { wch: 12 }, // 总价 | ||
| 870 | + { wch: 12 }, // 业绩类型 | ||
| 871 | + { wch: 12 }, // 科美类型 | ||
| 872 | + { wch: 12 }, // 来源类型 | ||
| 873 | + { wch: 12 } // 品项分类 | ||
| 874 | + ] | ||
| 875 | + | ||
| 876 | + // 创建工作簿 | ||
| 877 | + const wb = XLSX.utils.book_new() | ||
| 878 | + XLSX.utils.book_append_sheet(wb, ws, '退卡品项明细表') | ||
| 879 | + | ||
| 880 | + // 生成文件名 | ||
| 881 | + const now = new Date() | ||
| 882 | + const fileName = `退卡品项明细表_${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}_${now.getTime()}.xlsx` | ||
| 883 | + | ||
| 884 | + // 导出文件 | ||
| 885 | + const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }) | ||
| 886 | + saveAs(new Blob([wbout], { type: 'application/octet-stream' }), fileName) | ||
| 887 | + | ||
| 888 | + this.$message({ | ||
| 889 | + type: 'success', | ||
| 890 | + message: '导出成功', | ||
| 891 | + duration: 1500 | ||
| 892 | + }) | ||
| 893 | + } catch (error) { | ||
| 894 | + console.error('导出失败:', error) | ||
| 895 | + if (error.message && error.message.includes('xlsx')) { | ||
| 896 | + this.$message({ | ||
| 897 | + type: 'error', | ||
| 898 | + message: '导出失败:请先安装 xlsx 库,运行命令: npm install xlsx --save', | ||
| 899 | + duration: 3000 | ||
| 900 | + }) | ||
| 901 | + } else { | ||
| 902 | + this.$message({ | ||
| 903 | + type: 'error', | ||
| 904 | + message: '导出失败:' + (error.message || '未知错误'), | ||
| 905 | + duration: 2000 | ||
| 906 | + }) | ||
| 907 | + } | ||
| 908 | + } | ||
| 909 | + } | ||
| 910 | + } | ||
| 911 | +} | ||
| 912 | +</script> | ||
| 913 | + | ||
| 914 | +<style lang="scss" scoped> | ||
| 915 | +.amount-value { | ||
| 916 | + color: #409EFF; | ||
| 917 | + font-weight: 500; | ||
| 918 | +} | ||
| 919 | +</style> | ||
| 920 | + |
antis-ncc-admin/src/views/statisticsList/form7.vue
| @@ -5,20 +5,6 @@ | @@ -5,20 +5,6 @@ | ||
| 5 | <el-row class="NCC-common-search-box" :gutter="16"> | 5 | <el-row class="NCC-common-search-box" :gutter="16"> |
| 6 | <el-form @submit.native.prevent> | 6 | <el-form @submit.native.prevent> |
| 7 | <el-col :span="6"> | 7 | <el-col :span="6"> |
| 8 | - <el-form-item label="门店"> | ||
| 9 | - <el-select v-model="query.storeId" placeholder="请选择门店" clearable filterable> | ||
| 10 | - <el-option v-for="store in storeOptions" :key="store.id" :label="store.dm" :value="store.id" /> | ||
| 11 | - </el-select> | ||
| 12 | - </el-form-item> | ||
| 13 | - </el-col> | ||
| 14 | - <el-col :span="6"> | ||
| 15 | - <el-form-item label="部门"> | ||
| 16 | - <el-select v-model="query.departmentId" placeholder="请选择部门" clearable filterable> | ||
| 17 | - <el-option v-for="dept in departmentOptions" :key="dept.id" :label="dept.fullName" :value="dept.id" /> | ||
| 18 | - </el-select> | ||
| 19 | - </el-form-item> | ||
| 20 | - </el-col> | ||
| 21 | - <el-col :span="6"> | ||
| 22 | <el-form-item label="开始时间"> | 8 | <el-form-item label="开始时间"> |
| 23 | <el-date-picker | 9 | <el-date-picker |
| 24 | v-model="query.startTime" | 10 | v-model="query.startTime" |
| @@ -41,6 +27,58 @@ | @@ -41,6 +27,58 @@ | ||
| 41 | </el-form-item> | 27 | </el-form-item> |
| 42 | </el-col> | 28 | </el-col> |
| 43 | <el-col :span="6"> | 29 | <el-col :span="6"> |
| 30 | + <el-form-item label="组织类型"> | ||
| 31 | + <el-select | ||
| 32 | + v-model="query.organizationType" | ||
| 33 | + placeholder="请选择组织类型" | ||
| 34 | + filterable | ||
| 35 | + clearable | ||
| 36 | + @change="handleOrganizationTypeChange" | ||
| 37 | + :style='{"width":"100%"}'> | ||
| 38 | + <el-option label="事业部" value="事业部"></el-option> | ||
| 39 | + <el-option label="科技部" value="科技部"></el-option> | ||
| 40 | + <el-option label="教育部" value="教育部"></el-option> | ||
| 41 | + <el-option label="大项目部" value="大项目部"></el-option> | ||
| 42 | + </el-select> | ||
| 43 | + </el-form-item> | ||
| 44 | + </el-col> | ||
| 45 | + <el-col :span="6"> | ||
| 46 | + <el-form-item label="部门"> | ||
| 47 | + <el-select | ||
| 48 | + v-model="query.departmentId" | ||
| 49 | + placeholder="请选择部门" | ||
| 50 | + filterable | ||
| 51 | + clearable | ||
| 52 | + @change="handleDepartmentChange" | ||
| 53 | + :style='{"width":"100%"}'> | ||
| 54 | + <el-option | ||
| 55 | + v-for="dept in departmentOptions" | ||
| 56 | + :key="dept.Id || dept.id" | ||
| 57 | + :label="dept.FullName || dept.fullName" | ||
| 58 | + :value="dept.Id || dept.id"> | ||
| 59 | + </el-option> | ||
| 60 | + </el-select> | ||
| 61 | + </el-form-item> | ||
| 62 | + </el-col> | ||
| 63 | + <el-col :span="12"> | ||
| 64 | + <el-form-item label="门店"> | ||
| 65 | + <el-select | ||
| 66 | + v-model="query.storeIds" | ||
| 67 | + placeholder="请选择门店" | ||
| 68 | + multiple | ||
| 69 | + filterable | ||
| 70 | + clearable | ||
| 71 | + :style='{"width":"100%"}'> | ||
| 72 | + <el-option | ||
| 73 | + v-for="store in storeOptions" | ||
| 74 | + :key="store.id" | ||
| 75 | + :label="store.dm" | ||
| 76 | + :value="store.id"> | ||
| 77 | + </el-option> | ||
| 78 | + </el-select> | ||
| 79 | + </el-form-item> | ||
| 80 | + </el-col> | ||
| 81 | + <el-col :span="6"> | ||
| 44 | <el-form-item> | 82 | <el-form-item> |
| 45 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> | 83 | <el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button> |
| 46 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> | 84 | <el-button icon="el-icon-refresh-right" @click="reset()">重置</el-button> |
| @@ -151,7 +189,7 @@ | @@ -151,7 +189,7 @@ | ||
| 151 | </div> | 189 | </div> |
| 152 | <div class="card-content"> | 190 | <div class="card-content"> |
| 153 | <div class="card-title">总人头数</div> | 191 | <div class="card-title">总人头数</div> |
| 154 | - <div class="card-value">{{ summaryData.totalHeadCount || 0 }}</div> | 192 | + <div class="card-value">{{ formatNumber(summaryData.totalHeadCount) }}</div> |
| 155 | </div> | 193 | </div> |
| 156 | </div> | 194 | </div> |
| 157 | </el-col> | 195 | </el-col> |
| @@ -162,7 +200,7 @@ | @@ -162,7 +200,7 @@ | ||
| 162 | </div> | 200 | </div> |
| 163 | <div class="card-content"> | 201 | <div class="card-content"> |
| 164 | <div class="card-title">总人次</div> | 202 | <div class="card-title">总人次</div> |
| 165 | - <div class="card-value">{{ summaryData.totalPersonCount || 0 }}</div> | 203 | + <div class="card-value">{{ formatNumber(summaryData.totalPersonCount) }}</div> |
| 166 | </div> | 204 | </div> |
| 167 | </div> | 205 | </div> |
| 168 | </el-col> | 206 | </el-col> |
| @@ -312,8 +350,9 @@ export default { | @@ -312,8 +350,9 @@ export default { | ||
| 312 | data() { | 350 | data() { |
| 313 | return { | 351 | return { |
| 314 | query: { | 352 | query: { |
| 315 | - storeId: undefined, | 353 | + organizationType: undefined, |
| 316 | departmentId: undefined, | 354 | departmentId: undefined, |
| 355 | + storeIds: [], | ||
| 317 | startTime: undefined, | 356 | startTime: undefined, |
| 318 | endTime: undefined, | 357 | endTime: undefined, |
| 319 | currentPage: 1, | 358 | currentPage: 1, |
| @@ -334,17 +373,25 @@ export default { | @@ -334,17 +373,25 @@ export default { | ||
| 334 | } else{ | 373 | } else{ |
| 335 | this.restoreQueryParams() | 374 | this.restoreQueryParams() |
| 336 | } | 375 | } |
| 337 | - this.initStoreOptions() | ||
| 338 | - this.initDepartmentOptions() | 376 | + this.loadAllStores() |
| 339 | this.search() | 377 | this.search() |
| 340 | }, | 378 | }, |
| 379 | + watch: { | ||
| 380 | + // 监听开始时间变化,重新加载门店列表 | ||
| 381 | + 'query.startTime'() { | ||
| 382 | + this.$nextTick(() => { | ||
| 383 | + this.initStoreOptions() | ||
| 384 | + }) | ||
| 385 | + } | ||
| 386 | + }, | ||
| 341 | methods: { | 387 | methods: { |
| 342 | // 保存筛选条件到 sessionStorage | 388 | // 保存筛选条件到 sessionStorage |
| 343 | saveQueryParams() { | 389 | saveQueryParams() { |
| 344 | try { | 390 | try { |
| 345 | const paramsToSave = { | 391 | const paramsToSave = { |
| 346 | - storeId: this.query.storeId, | 392 | + organizationType: this.query.organizationType, |
| 347 | departmentId: this.query.departmentId, | 393 | departmentId: this.query.departmentId, |
| 394 | + storeIds: this.query.storeIds, | ||
| 348 | startTime: this.query.startTime, | 395 | startTime: this.query.startTime, |
| 349 | endTime: this.query.endTime, | 396 | endTime: this.query.endTime, |
| 350 | currentPage: this.query.currentPage, | 397 | currentPage: this.query.currentPage, |
| @@ -364,8 +411,9 @@ export default { | @@ -364,8 +411,9 @@ export default { | ||
| 364 | if (savedParams) { | 411 | if (savedParams) { |
| 365 | const params = JSON.parse(savedParams) | 412 | const params = JSON.parse(savedParams) |
| 366 | // 恢复筛选条件 | 413 | // 恢复筛选条件 |
| 367 | - this.query.storeId = params.storeId || undefined | 414 | + this.query.organizationType = params.organizationType || undefined |
| 368 | this.query.departmentId = params.departmentId || undefined | 415 | this.query.departmentId = params.departmentId || undefined |
| 416 | + this.query.storeIds = params.storeIds || [] | ||
| 369 | this.query.startTime = params.startTime || undefined | 417 | this.query.startTime = params.startTime || undefined |
| 370 | this.query.endTime = params.endTime || undefined | 418 | this.query.endTime = params.endTime || undefined |
| 371 | this.query.currentPage = params.currentPage || 1 | 419 | this.query.currentPage = params.currentPage || 1 |
| @@ -375,6 +423,19 @@ export default { | @@ -375,6 +423,19 @@ export default { | ||
| 375 | if (!this.query.startTime || !this.query.endTime) { | 423 | if (!this.query.startTime || !this.query.endTime) { |
| 376 | this.setDefaultTimeRange() | 424 | this.setDefaultTimeRange() |
| 377 | } | 425 | } |
| 426 | + | ||
| 427 | + // 恢复部门选项和门店列表 | ||
| 428 | + if (this.query.organizationType) { | ||
| 429 | + this.loadDepartmentOptions() | ||
| 430 | + } | ||
| 431 | + if (this.query.departmentId && this.query.organizationType && this.query.startTime) { | ||
| 432 | + this.$nextTick(() => { | ||
| 433 | + this.initStoreOptions() | ||
| 434 | + }) | ||
| 435 | + } else { | ||
| 436 | + this.loadAllStores() | ||
| 437 | + } | ||
| 438 | + | ||
| 378 | sessionStorage.setItem('isshaixuan', false) | 439 | sessionStorage.setItem('isshaixuan', false) |
| 379 | } else { | 440 | } else { |
| 380 | // 没有保存的条件,设置默认时间范围 | 441 | // 没有保存的条件,设置默认时间范围 |
| @@ -394,10 +455,17 @@ export default { | @@ -394,10 +455,17 @@ export default { | ||
| 394 | 455 | ||
| 395 | this.query.startTime = this.formatDateTime(firstDayOfMonth.getTime()) | 456 | this.query.startTime = this.formatDateTime(firstDayOfMonth.getTime()) |
| 396 | this.query.endTime = this.formatDateTime(now.getTime()) | 457 | this.query.endTime = this.formatDateTime(now.getTime()) |
| 458 | + | ||
| 459 | + // 时间设置后,如果有组织类型和部门,重新加载门店列表 | ||
| 460 | + if (this.query.organizationType && this.query.departmentId) { | ||
| 461 | + this.$nextTick(() => { | ||
| 462 | + this.initStoreOptions() | ||
| 463 | + }) | ||
| 464 | + } | ||
| 397 | }, | 465 | }, |
| 398 | 466 | ||
| 399 | - // 初始化门店选项 | ||
| 400 | - initStoreOptions() { | 467 | + // 加载全部门店(当没有选择部门时) |
| 468 | + loadAllStores() { | ||
| 401 | request({ | 469 | request({ |
| 402 | url: '/api/Extend/LqMdxx', | 470 | url: '/api/Extend/LqMdxx', |
| 403 | method: 'GET', | 471 | method: 'GET', |
| @@ -409,25 +477,120 @@ export default { | @@ -409,25 +477,120 @@ export default { | ||
| 409 | this.storeOptions = res.data.list || [] | 477 | this.storeOptions = res.data.list || [] |
| 410 | }).catch(err => { | 478 | }).catch(err => { |
| 411 | console.error('获取门店列表失败:', err) | 479 | console.error('获取门店列表失败:', err) |
| 480 | + this.storeOptions = [] | ||
| 412 | }) | 481 | }) |
| 413 | }, | 482 | }, |
| 414 | 483 | ||
| 415 | - // 初始化部门选项 | ||
| 416 | - initDepartmentOptions() { | 484 | + // 获取部门选项(根据组织类型) |
| 485 | + loadDepartmentOptions() { | ||
| 486 | + if (!this.query.organizationType) { | ||
| 487 | + this.departmentOptions = [] | ||
| 488 | + return | ||
| 489 | + } | ||
| 490 | + | ||
| 417 | request({ | 491 | request({ |
| 418 | - url: '/api/permission/Organize/96240625-934F-490B-8AA6-0BC775B18468/Department', | ||
| 419 | - method: 'GET' | 492 | + url: '/api/Extend/Organize/GetByName', |
| 493 | + method: 'GET', | ||
| 494 | + data: { | ||
| 495 | + organizeName: this.query.organizationType | ||
| 496 | + } | ||
| 497 | + }).then(res => { | ||
| 498 | + this.departmentOptions = res.data || [] | ||
| 499 | + // 如果部门ID不在新列表中,清空部门ID | ||
| 500 | + if (this.query.departmentId) { | ||
| 501 | + const exists = this.departmentOptions.some( | ||
| 502 | + dept => (dept.Id || dept.id) === this.query.departmentId | ||
| 503 | + ) | ||
| 504 | + if (!exists) { | ||
| 505 | + this.query.departmentId = undefined | ||
| 506 | + this.query.storeIds = [] | ||
| 507 | + this.storeOptions = [] | ||
| 508 | + } | ||
| 509 | + } | ||
| 510 | + }).catch(() => { | ||
| 511 | + this.departmentOptions = [] | ||
| 512 | + }) | ||
| 513 | + }, | ||
| 514 | + | ||
| 515 | + // 初始化门店选项(根据组织类型、部门、年月) | ||
| 516 | + initStoreOptions() { | ||
| 517 | + // 如果没有选择部门,加载全部门店 | ||
| 518 | + if (!this.query.departmentId) { | ||
| 519 | + this.loadAllStores() | ||
| 520 | + return | ||
| 521 | + } | ||
| 522 | + | ||
| 523 | + // 如果缺少必要参数,不加载门店列表 | ||
| 524 | + if (!this.query.organizationType || !this.query.startTime) { | ||
| 525 | + this.storeOptions = [] | ||
| 526 | + return | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + // 从开始时间提取年月(格式:YYYYMM) | ||
| 530 | + // startTime 格式为 yyyy-MM-dd HH:mm:ss | ||
| 531 | + const dateStr = this.query.startTime | ||
| 532 | + if (!dateStr) { | ||
| 533 | + this.storeOptions = [] | ||
| 534 | + return | ||
| 535 | + } | ||
| 536 | + | ||
| 537 | + // 提取年月,格式:YYYYMM | ||
| 538 | + const monthStr = dateStr.substring(0, 4) + dateStr.substring(5, 7) | ||
| 539 | + | ||
| 540 | + request({ | ||
| 541 | + url: '/api/Extend/lqmdtarget/GetManagedStores', | ||
| 542 | + method: 'POST', | ||
| 543 | + data: { | ||
| 544 | + month: monthStr, | ||
| 545 | + organizationType: this.query.organizationType, | ||
| 546 | + departmentId: this.query.departmentId | ||
| 547 | + } | ||
| 420 | }).then(res => { | 548 | }).then(res => { |
| 421 | - // 将树形结构扁平化 | ||
| 422 | - this.departmentOptions = res.data.list.map(item => ({ | ||
| 423 | - id: item.id, | ||
| 424 | - fullName: item.fullName | ||
| 425 | - })) | 549 | + if (res.data && Array.isArray(res.data)) { |
| 550 | + // 将返回的数据格式转换为 storeOptions 需要的格式 | ||
| 551 | + // 返回格式: [{ StoreId: "...", StoreName: "..." }] | ||
| 552 | + // 需要格式: [{ id: "...", dm: "..." }] | ||
| 553 | + this.storeOptions = res.data.map(store => ({ | ||
| 554 | + id: store.StoreId, | ||
| 555 | + dm: store.StoreName | ||
| 556 | + })) | ||
| 557 | + // 默认选中所有获取到的门店 | ||
| 558 | + this.query.storeIds = this.storeOptions.map(store => store.id) | ||
| 559 | + } else { | ||
| 560 | + this.storeOptions = [] | ||
| 561 | + this.query.storeIds = [] | ||
| 562 | + } | ||
| 426 | }).catch(err => { | 563 | }).catch(err => { |
| 427 | - console.error('获取部门列表失败:', err) | 564 | + console.error('获取门店列表失败:', err) |
| 565 | + this.$message({ | ||
| 566 | + type: 'error', | ||
| 567 | + message: '获取门店列表失败', | ||
| 568 | + duration: 1500 | ||
| 569 | + }) | ||
| 570 | + this.storeOptions = [] | ||
| 571 | + this.query.storeIds = [] | ||
| 428 | }) | 572 | }) |
| 429 | }, | 573 | }, |
| 430 | 574 | ||
| 575 | + // 处理组织类型变化 | ||
| 576 | + handleOrganizationTypeChange() { | ||
| 577 | + // 清空部门和门店 | ||
| 578 | + this.query.departmentId = undefined | ||
| 579 | + this.query.storeIds = [] | ||
| 580 | + // 重新加载部门选项 | ||
| 581 | + this.loadDepartmentOptions() | ||
| 582 | + // 加载全部门店(因为部门已清空) | ||
| 583 | + this.loadAllStores() | ||
| 584 | + }, | ||
| 585 | + | ||
| 586 | + // 处理部门变化 | ||
| 587 | + handleDepartmentChange() { | ||
| 588 | + // 清空门店选择 | ||
| 589 | + this.query.storeIds = [] | ||
| 590 | + // 重新加载门店列表(如果有部门则加载部门管理的门店,否则加载全部门店) | ||
| 591 | + this.initStoreOptions() | ||
| 592 | + }, | ||
| 593 | + | ||
| 431 | 594 | ||
| 432 | 595 | ||
| 433 | // 查询数据 | 596 | // 查询数据 |
| @@ -441,8 +604,8 @@ export default { | @@ -441,8 +604,8 @@ export default { | ||
| 441 | pageSize: this.query.pageSize | 604 | pageSize: this.query.pageSize |
| 442 | } | 605 | } |
| 443 | 606 | ||
| 444 | - if (this.query.storeId) { | ||
| 445 | - params.StoreId = this.query.storeId | 607 | + if (this.query.storeIds && this.query.storeIds.length > 0) { |
| 608 | + params.StoreIds = this.query.storeIds | ||
| 446 | } | 609 | } |
| 447 | 610 | ||
| 448 | if (this.query.departmentId) { | 611 | if (this.query.departmentId) { |
| @@ -530,14 +693,18 @@ export default { | @@ -530,14 +693,18 @@ export default { | ||
| 530 | // 重置查询条件 | 693 | // 重置查询条件 |
| 531 | reset() { | 694 | reset() { |
| 532 | this.query = { | 695 | this.query = { |
| 533 | - storeId: undefined, | 696 | + organizationType: undefined, |
| 534 | departmentId: undefined, | 697 | departmentId: undefined, |
| 698 | + storeIds: [], | ||
| 535 | startTime: undefined, | 699 | startTime: undefined, |
| 536 | endTime: undefined, | 700 | endTime: undefined, |
| 537 | currentPage: 1, | 701 | currentPage: 1, |
| 538 | pageSize: 20 | 702 | pageSize: 20 |
| 539 | } | 703 | } |
| 540 | this.setDefaultTimeRange() | 704 | this.setDefaultTimeRange() |
| 705 | + this.departmentOptions = [] | ||
| 706 | + // 重置后加载全部门店 | ||
| 707 | + this.loadAllStores() | ||
| 541 | // 清除保存的筛选条件 | 708 | // 清除保存的筛选条件 |
| 542 | try { | 709 | try { |
| 543 | sessionStorage.removeItem('form7_query_params') | 710 | sessionStorage.removeItem('form7_query_params') |
| @@ -556,6 +723,14 @@ export default { | @@ -556,6 +723,14 @@ export default { | ||
| 556 | return Number(amount).toFixed(2) | 723 | return Number(amount).toFixed(2) |
| 557 | }, | 724 | }, |
| 558 | 725 | ||
| 726 | + // 格式化数字,保留两位小数 | ||
| 727 | + formatNumber(num) { | ||
| 728 | + if (num === null || num === undefined || num === '') return '0.00' | ||
| 729 | + const value = Number(num) | ||
| 730 | + if (isNaN(value)) return '0.00' | ||
| 731 | + return value.toFixed(2) | ||
| 732 | + }, | ||
| 733 | + | ||
| 559 | // 格式化百分比 | 734 | // 格式化百分比 |
| 560 | formatPercentage(ratio) { | 735 | formatPercentage(ratio) { |
| 561 | if (ratio === null || ratio === undefined) return '0.00%' | 736 | if (ratio === null || ratio === undefined) return '0.00%' |
绿纤uni-app/apis/modules/store.js
0 → 100644
| 1 | +import request from '@/service/request.js' | ||
| 2 | +import config from '@/common/config.js' | ||
| 3 | + | ||
| 4 | +export default { | ||
| 5 | + // 获取门店列表 | ||
| 6 | + getStoreList(params) { | ||
| 7 | + return request.get(`${config.getApiBaseUrl()}/api/Extend/LqMdxx`, params); | ||
| 8 | + }, | ||
| 9 | + | ||
| 10 | + // 获取门店详情 | ||
| 11 | + getStoreDetail(id) { | ||
| 12 | + return request.get(`${config.getApiBaseUrl()}/api/Extend/LqMdxx/${id}`); | ||
| 13 | + }, | ||
| 14 | + | ||
| 15 | + // 更新门店信息 | ||
| 16 | + updateStore(id, data) { | ||
| 17 | + return request.put(`${config.getApiBaseUrl()}/api/Extend/LqMdxx/${id}`, data); | ||
| 18 | + } | ||
| 19 | +} | ||
| 20 | + |
绿纤uni-app/common/config.js
| @@ -10,8 +10,8 @@ const ENV_CONFIG = { | @@ -10,8 +10,8 @@ const ENV_CONFIG = { | ||
| 10 | // 正式环境 | 10 | // 正式环境 |
| 11 | production: { | 11 | production: { |
| 12 | name: '正式环境', | 12 | name: '正式环境', |
| 13 | - // apiBaseUrl: 'http://erp_test.lvqianmeiye.com', | ||
| 14 | - apiBaseUrl: 'https://erp.lvqianmeiye.com', | 13 | + apiBaseUrl: 'http://erp_test.lvqianmeiye.com', |
| 14 | + // apiBaseUrl: 'https://erp.lvqianmeiye.com', | ||
| 15 | description: '生产环境服务器' | 15 | description: '生产环境服务器' |
| 16 | } | 16 | } |
| 17 | }; | 17 | }; |
绿纤uni-app/pages.json
| @@ -314,6 +314,13 @@ | @@ -314,6 +314,13 @@ | ||
| 314 | { | 314 | { |
| 315 | "navigationBarTitleText" : "报销审核详情" | 315 | "navigationBarTitleText" : "报销审核详情" |
| 316 | } | 316 | } |
| 317 | + }, | ||
| 318 | + { | ||
| 319 | + "path" : "pages/store-list/store-list", | ||
| 320 | + "style" : | ||
| 321 | + { | ||
| 322 | + "navigationBarTitleText" : "门店管理" | ||
| 323 | + } | ||
| 317 | } | 324 | } |
| 318 | ], | 325 | ], |
| 319 | "globalStyle": { | 326 | "globalStyle": { |
绿纤uni-app/pages/index/index.vue
| @@ -152,6 +152,12 @@ | @@ -152,6 +152,12 @@ | ||
| 152 | </view> | 152 | </view> |
| 153 | <view class="icon-label">毛巾记录</view> | 153 | <view class="icon-label">毛巾记录</view> |
| 154 | </view> | 154 | </view> |
| 155 | + <view class="icon-btn" @click="goToPage('/pages/store-list/store-list')"> | ||
| 156 | + <view class="icon"> | ||
| 157 | + <u-icon name="star" size="32" color="#43a047"></u-icon> | ||
| 158 | + </view> | ||
| 159 | + <view class="icon-label">门店管理</view> | ||
| 160 | + </view> | ||
| 155 | <view class="icon-btn" @click="goToPage('/pages/web/web')"> | 161 | <view class="icon-btn" @click="goToPage('/pages/web/web')"> |
| 156 | <view class="icon"> | 162 | <view class="icon"> |
| 157 | <u-icon name="kefu-ermai" size="32" color="#43a047"></u-icon> | 163 | <u-icon name="kefu-ermai" size="32" color="#43a047"></u-icon> |
绿纤uni-app/pages/store-list/store-list.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <view class="store-list-container"> | ||
| 3 | + <!-- 搜索卡片 --> | ||
| 4 | + <view class="search-card"> | ||
| 5 | + <u-search | ||
| 6 | + v-model="searchKeyword" | ||
| 7 | + placeholder="搜索门店名称" | ||
| 8 | + @search="onSearchInput" | ||
| 9 | + @clear="onSearchInput" | ||
| 10 | + @custom="onSearchInput" | ||
| 11 | + class="search-input"> | ||
| 12 | + </u-search> | ||
| 13 | + </view> | ||
| 14 | + | ||
| 15 | + <!-- 门店列表 --> | ||
| 16 | + <view class="store-list" v-if="storeList.length > 0"> | ||
| 17 | + <view | ||
| 18 | + v-for="(store, index) in storeList" | ||
| 19 | + :key="store.id" | ||
| 20 | + class="store-card" | ||
| 21 | + > | ||
| 22 | + <view class="store-header"> | ||
| 23 | + <view class="store-name">{{ store.dm || '无' }}</view> | ||
| 24 | + <view class="store-status" :class="store.zxzt === '开店' ? 'status-open' : store.zxzt === '闭店' ? 'status-closed' : ''"> | ||
| 25 | + {{ store.zxzt || '无' }} | ||
| 26 | + </view> | ||
| 27 | + </view> | ||
| 28 | + <view class="store-row"> | ||
| 29 | + <view class="store-item"> | ||
| 30 | + <text class="store-label">单据门店</text> | ||
| 31 | + <text class="store-value">{{ store.djmd || '无' }}</text> | ||
| 32 | + </view> | ||
| 33 | + <view class="store-item"> | ||
| 34 | + <text class="store-label">城市</text> | ||
| 35 | + <text class="store-value">{{ store.cs || '无' }}</text> | ||
| 36 | + </view> | ||
| 37 | + </view> | ||
| 38 | + <view class="store-row"> | ||
| 39 | + <view class="store-item"> | ||
| 40 | + <text class="store-label">联系人</text> | ||
| 41 | + <text class="store-value">{{ store.xm || '无' }}</text> | ||
| 42 | + </view> | ||
| 43 | + <view class="store-item"> | ||
| 44 | + <text class="store-label">联系电话</text> | ||
| 45 | + <text class="store-value">{{ store.dhhm || '无' }}</text> | ||
| 46 | + </view> | ||
| 47 | + </view> | ||
| 48 | + <view class="store-row"> | ||
| 49 | + <view class="store-item"> | ||
| 50 | + <text class="store-label">座机</text> | ||
| 51 | + <text class="store-value">{{ store.zj || '无' }}</text> | ||
| 52 | + </view> | ||
| 53 | + <view class="store-item"> | ||
| 54 | + <text class="store-label">在职人数</text> | ||
| 55 | + <text class="store-value">{{ store.zzrs || 0 }}人</text> | ||
| 56 | + </view> | ||
| 57 | + </view> | ||
| 58 | + <view class="store-row" v-if="store.kysj"> | ||
| 59 | + <view class="store-item full-width"> | ||
| 60 | + <text class="store-label">开业时间</text> | ||
| 61 | + <text class="store-value">{{ formatDate(store.kysj) }}</text> | ||
| 62 | + </view> | ||
| 63 | + </view> | ||
| 64 | + <view class="store-row" v-if="store.dz"> | ||
| 65 | + <view class="store-item full-width"> | ||
| 66 | + <text class="store-label">地址</text> | ||
| 67 | + <text class="store-value">{{ store.dz || '无' }}</text> | ||
| 68 | + </view> | ||
| 69 | + </view> | ||
| 70 | + <view class="store-actions"> | ||
| 71 | + <button class="edit-btn" @click.stop="openEditDialog(store)">修改在职人数</button> | ||
| 72 | + </view> | ||
| 73 | + </view> | ||
| 74 | + </view> | ||
| 75 | + | ||
| 76 | + <!-- 加载状态 --> | ||
| 77 | + <view v-if="isLoading" class="loading"> | ||
| 78 | + <u-loading-icon mode="circle" color="#43a047"></u-loading-icon> | ||
| 79 | + <text class="loading-text">正在加载门店数据...</text> | ||
| 80 | + </view> | ||
| 81 | + | ||
| 82 | + <!-- 加载更多 --> | ||
| 83 | + <view v-if="isLoadingMore" class="loading-more"> | ||
| 84 | + <u-loading-icon mode="circle" color="#43a047" size="16"></u-loading-icon> | ||
| 85 | + <text class="loading-more-text">正在加载更多...</text> | ||
| 86 | + </view> | ||
| 87 | + | ||
| 88 | + <!-- 无更多数据 --> | ||
| 89 | + <view v-if="!hasMoreData && storeList.length > 0" class="no-more-data"> | ||
| 90 | + 已加载全部数据 | ||
| 91 | + </view> | ||
| 92 | + | ||
| 93 | + <!-- 空状态 --> | ||
| 94 | + <view v-if="!isLoading && storeList.length === 0" class="empty-state"> | ||
| 95 | + <view class="empty-state-icon">🏪</view> | ||
| 96 | + <view class="empty-state-text">暂无门店数据</view> | ||
| 97 | + <view class="empty-state-subtext">请稍后再试或联系管理员</view> | ||
| 98 | + </view> | ||
| 99 | + | ||
| 100 | + <!-- 搜索空状态 --> | ||
| 101 | + <view v-if="!isLoading && storeList.length === 0 && isSearching" class="empty-state"> | ||
| 102 | + <view class="empty-state-icon">🔍</view> | ||
| 103 | + <view class="empty-state-text">未找到匹配的门店</view> | ||
| 104 | + <view class="empty-state-subtext">请尝试其他搜索关键词</view> | ||
| 105 | + </view> | ||
| 106 | + | ||
| 107 | + <!-- 编辑在职人数弹窗 --> | ||
| 108 | + <view v-if="showEditDialog" class="dialog-overlay" @click="closeEditDialog"> | ||
| 109 | + <view class="edit-dialog" @click.stop> | ||
| 110 | + <view class="dialog-header"> | ||
| 111 | + <text class="dialog-title">修改在职人数</text> | ||
| 112 | + </view> | ||
| 113 | + <view class="dialog-content"> | ||
| 114 | + <view class="form-item"> | ||
| 115 | + <text class="form-label">门店名称</text> | ||
| 116 | + <text class="form-value">{{ currentStore.dm || '无' }}</text> | ||
| 117 | + </view> | ||
| 118 | + <view class="form-item"> | ||
| 119 | + <text class="form-label">在职人数</text> | ||
| 120 | + <u-input | ||
| 121 | + v-model="editZzrs" | ||
| 122 | + type="number" | ||
| 123 | + placeholder="请输入在职人数" | ||
| 124 | + :clearable="true" | ||
| 125 | + /> | ||
| 126 | + </view> | ||
| 127 | + </view> | ||
| 128 | + <view class="dialog-buttons"> | ||
| 129 | + <button class="dialog-btn cancel-dialog-btn" @click="closeEditDialog">取消</button> | ||
| 130 | + <button | ||
| 131 | + class="dialog-btn confirm-dialog-btn" | ||
| 132 | + @click="submitEdit" | ||
| 133 | + :loading="submitLoading" | ||
| 134 | + > | ||
| 135 | + 确定 | ||
| 136 | + </button> | ||
| 137 | + </view> | ||
| 138 | + </view> | ||
| 139 | + </view> | ||
| 140 | + </view> | ||
| 141 | +</template> | ||
| 142 | + | ||
| 143 | +<script> | ||
| 144 | + import storeApi from '@/apis/modules/store.js' | ||
| 145 | + | ||
| 146 | + export default { | ||
| 147 | + data() { | ||
| 148 | + return { | ||
| 149 | + // 搜索相关 | ||
| 150 | + searchKeyword: '', | ||
| 151 | + searchTimeout: null, | ||
| 152 | + isSearching: false, | ||
| 153 | + | ||
| 154 | + // 列表相关 | ||
| 155 | + storeList: [], | ||
| 156 | + currentPage: 1, | ||
| 157 | + pageSize: 10, | ||
| 158 | + isLoading: false, | ||
| 159 | + isLoadingMore: false, | ||
| 160 | + hasMoreData: true, | ||
| 161 | + | ||
| 162 | + // 用户信息 | ||
| 163 | + userInfo: null, | ||
| 164 | + | ||
| 165 | + // 编辑相关 | ||
| 166 | + showEditDialog: false, | ||
| 167 | + currentStore: {}, | ||
| 168 | + editZzrs: '', | ||
| 169 | + submitLoading: false | ||
| 170 | + } | ||
| 171 | + }, | ||
| 172 | + onLoad() { | ||
| 173 | + this.initializePage(); | ||
| 174 | + }, | ||
| 175 | + onReachBottom() { | ||
| 176 | + this.loadMoreData(); | ||
| 177 | + }, | ||
| 178 | + methods: { | ||
| 179 | + // 初始化页面 | ||
| 180 | + async initializePage() { | ||
| 181 | + try { | ||
| 182 | + // 获取用户信息 | ||
| 183 | + this.userInfo = uni.getStorageSync('userInfo'); | ||
| 184 | + if (!this.userInfo || Object.keys(this.userInfo).length === 0) { | ||
| 185 | + uni.showToast({ | ||
| 186 | + title: '请先登录', | ||
| 187 | + icon: 'none' | ||
| 188 | + }); | ||
| 189 | + setTimeout(() => { | ||
| 190 | + uni.reLaunch({ | ||
| 191 | + url: '/pages/login/login' | ||
| 192 | + }); | ||
| 193 | + }, 1500); | ||
| 194 | + return; | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + await this.loadStoreData(true); | ||
| 198 | + } catch (error) { | ||
| 199 | + console.error('页面初始化失败:', error); | ||
| 200 | + uni.showToast({ | ||
| 201 | + title: '数据加载失败', | ||
| 202 | + icon: 'none' | ||
| 203 | + }); | ||
| 204 | + } | ||
| 205 | + }, | ||
| 206 | + | ||
| 207 | + // 搜索输入处理 | ||
| 208 | + onSearchInput() { | ||
| 209 | + // 清除之前的定时器 | ||
| 210 | + if (this.searchTimeout) { | ||
| 211 | + clearTimeout(this.searchTimeout); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + // 设置防抖,500ms后执行搜索 | ||
| 215 | + this.searchTimeout = setTimeout(() => { | ||
| 216 | + if (this.searchKeyword.trim()) { | ||
| 217 | + this.isSearching = true; | ||
| 218 | + } else { | ||
| 219 | + this.isSearching = false; | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + // 重置分页状态 | ||
| 223 | + this.currentPage = 1; | ||
| 224 | + this.hasMoreData = true; | ||
| 225 | + this.loadStoreData(true); | ||
| 226 | + }, 500); | ||
| 227 | + }, | ||
| 228 | + | ||
| 229 | + // 加载门店数据 | ||
| 230 | + async loadStoreData(isFirstLoad = false) { | ||
| 231 | + if (this.isLoading) return; | ||
| 232 | + | ||
| 233 | + try { | ||
| 234 | + this.isLoading = true; | ||
| 235 | + | ||
| 236 | + if (isFirstLoad) { | ||
| 237 | + this.isLoadingMore = false; | ||
| 238 | + } else { | ||
| 239 | + this.isLoadingMore = true; | ||
| 240 | + } | ||
| 241 | + | ||
| 242 | + const params = { | ||
| 243 | + currentPage: this.currentPage, | ||
| 244 | + pageSize: this.pageSize | ||
| 245 | + }; | ||
| 246 | + | ||
| 247 | + // 添加搜索参数 | ||
| 248 | + if (this.searchKeyword.trim()) { | ||
| 249 | + // 只按门店名称搜索 | ||
| 250 | + params.dm = this.searchKeyword.trim(); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + const result = await storeApi.getStoreList(params); | ||
| 254 | + | ||
| 255 | + if (result.code === 200 && result.data && result.data.list) { | ||
| 256 | + const stores = result.data.list.map(item => ({ | ||
| 257 | + id: item.id, | ||
| 258 | + mdbm: item.mdbm || '', | ||
| 259 | + djmdbh: item.djmdbh || '', | ||
| 260 | + djmd: item.djmd || '无', | ||
| 261 | + dm: item.dm || '无', | ||
| 262 | + cs: item.cs || '无', | ||
| 263 | + dz: item.dz || '', | ||
| 264 | + xm: item.xm || '无', | ||
| 265 | + dhhm: item.dhhm || '无', | ||
| 266 | + zj: item.zj || '', | ||
| 267 | + kysj: item.kysj, | ||
| 268 | + zxzt: item.zxzt || '', | ||
| 269 | + gsmc: item.gsmc || '', | ||
| 270 | + fr: item.fr || '', | ||
| 271 | + ywsb: item.ywsb || '', | ||
| 272 | + zzrs: item.zzrs || 0, | ||
| 273 | + storeCategory: item.storeCategory || '', | ||
| 274 | + storeType: item.storeType || '' | ||
| 275 | + })); | ||
| 276 | + | ||
| 277 | + if (isFirstLoad) { | ||
| 278 | + this.storeList = [...stores]; | ||
| 279 | + } else { | ||
| 280 | + this.storeList = [...this.storeList, ...stores]; | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + // 检查是否还有更多数据 | ||
| 284 | + this.hasMoreData = stores.length === this.pageSize; | ||
| 285 | + } else { | ||
| 286 | + if (isFirstLoad) { | ||
| 287 | + this.storeList = []; | ||
| 288 | + } | ||
| 289 | + this.hasMoreData = false; | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + this.currentPage++; | ||
| 293 | + } catch (error) { | ||
| 294 | + console.error('加载门店数据失败:', error); | ||
| 295 | + uni.showToast({ | ||
| 296 | + title: '加载失败,请重试', | ||
| 297 | + icon: 'none' | ||
| 298 | + }); | ||
| 299 | + if (isFirstLoad) { | ||
| 300 | + this.storeList = []; | ||
| 301 | + } | ||
| 302 | + this.hasMoreData = false; | ||
| 303 | + } finally { | ||
| 304 | + this.isLoading = false; | ||
| 305 | + this.isLoadingMore = false; | ||
| 306 | + } | ||
| 307 | + }, | ||
| 308 | + | ||
| 309 | + // 加载更多数据 | ||
| 310 | + async loadMoreData() { | ||
| 311 | + if (this.isLoading || !this.hasMoreData) return; | ||
| 312 | + await this.loadStoreData(false); | ||
| 313 | + }, | ||
| 314 | + | ||
| 315 | + // 格式化日期 | ||
| 316 | + formatDate(date) { | ||
| 317 | + if (!date) return '无'; | ||
| 318 | + if (typeof date === 'string') { | ||
| 319 | + return date; | ||
| 320 | + } | ||
| 321 | + if (date instanceof Date) { | ||
| 322 | + return date.toLocaleDateString('zh-CN'); | ||
| 323 | + } | ||
| 324 | + // 处理时间戳格式 | ||
| 325 | + if (typeof date === 'number') { | ||
| 326 | + const dateObj = new Date(date); | ||
| 327 | + return dateObj.toLocaleDateString('zh-CN'); | ||
| 328 | + } | ||
| 329 | + return '未知日期'; | ||
| 330 | + }, | ||
| 331 | + | ||
| 332 | + | ||
| 333 | + // 打开编辑弹窗 | ||
| 334 | + openEditDialog(store) { | ||
| 335 | + this.currentStore = store; | ||
| 336 | + this.editZzrs = store.zzrs || ''; | ||
| 337 | + this.showEditDialog = true; | ||
| 338 | + }, | ||
| 339 | + | ||
| 340 | + // 关闭编辑弹窗 | ||
| 341 | + closeEditDialog() { | ||
| 342 | + this.showEditDialog = false; | ||
| 343 | + this.currentStore = {}; | ||
| 344 | + this.editZzrs = ''; | ||
| 345 | + }, | ||
| 346 | + | ||
| 347 | + // 提交编辑 | ||
| 348 | + async submitEdit() { | ||
| 349 | + if (this.submitLoading) return; | ||
| 350 | + | ||
| 351 | + // 验证输入 | ||
| 352 | + if (!this.editZzrs && this.editZzrs !== 0) { | ||
| 353 | + uni.showToast({ | ||
| 354 | + title: '请输入在职人数', | ||
| 355 | + icon: 'none' | ||
| 356 | + }); | ||
| 357 | + return; | ||
| 358 | + } | ||
| 359 | + | ||
| 360 | + const zzrs = parseInt(this.editZzrs); | ||
| 361 | + if (isNaN(zzrs) || zzrs < 0) { | ||
| 362 | + uni.showToast({ | ||
| 363 | + title: '请输入有效的数字', | ||
| 364 | + icon: 'none' | ||
| 365 | + }); | ||
| 366 | + return; | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + this.submitLoading = true; | ||
| 370 | + try { | ||
| 371 | + // 先获取门店完整信息 | ||
| 372 | + const detailRes = await storeApi.getStoreDetail(this.currentStore.id); | ||
| 373 | + if (detailRes.code !== 200) { | ||
| 374 | + throw new Error(detailRes.msg || '获取门店信息失败'); | ||
| 375 | + } | ||
| 376 | + | ||
| 377 | + // 更新在职人数 | ||
| 378 | + const updateData = { | ||
| 379 | + ...detailRes.data, | ||
| 380 | + zzrs: zzrs | ||
| 381 | + }; | ||
| 382 | + | ||
| 383 | + const result = await storeApi.updateStore(this.currentStore.id, updateData); | ||
| 384 | + | ||
| 385 | + if (result.code === 200) { | ||
| 386 | + uni.showToast({ | ||
| 387 | + title: '修改成功', | ||
| 388 | + icon: 'success' | ||
| 389 | + }); | ||
| 390 | + | ||
| 391 | + // 更新列表中的数据 | ||
| 392 | + const index = this.storeList.findIndex(item => item.id === this.currentStore.id); | ||
| 393 | + if (index !== -1) { | ||
| 394 | + this.storeList[index].zzrs = zzrs; | ||
| 395 | + } | ||
| 396 | + | ||
| 397 | + this.closeEditDialog(); | ||
| 398 | + } else { | ||
| 399 | + uni.showToast({ | ||
| 400 | + title: result.msg || '修改失败', | ||
| 401 | + icon: 'none' | ||
| 402 | + }); | ||
| 403 | + } | ||
| 404 | + } catch (error) { | ||
| 405 | + console.error('修改在职人数失败:', error); | ||
| 406 | + uni.showToast({ | ||
| 407 | + title: '修改失败,请重试', | ||
| 408 | + icon: 'none' | ||
| 409 | + }); | ||
| 410 | + } finally { | ||
| 411 | + this.submitLoading = false; | ||
| 412 | + } | ||
| 413 | + } | ||
| 414 | + } | ||
| 415 | + } | ||
| 416 | +</script> | ||
| 417 | + | ||
| 418 | +<style lang="scss" scoped> | ||
| 419 | + .store-list-container { | ||
| 420 | + min-height: 100vh; | ||
| 421 | + background: linear-gradient(135deg, #e8f5e9 0%, #b2dfdb 100%); | ||
| 422 | + padding: 20rpx; | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + .search-card { | ||
| 426 | + background: #fff; | ||
| 427 | + border-radius: 32rpx; | ||
| 428 | + box-shadow: 0 8rpx 32rpx rgba(76, 175, 80, 0.1); | ||
| 429 | + padding: 40rpx; | ||
| 430 | + margin-bottom: 40rpx; | ||
| 431 | + } | ||
| 432 | + | ||
| 433 | + .store-list { | ||
| 434 | + margin-bottom: 40rpx; | ||
| 435 | + } | ||
| 436 | + | ||
| 437 | + .store-card { | ||
| 438 | + background: #fff; | ||
| 439 | + border-radius: 32rpx; | ||
| 440 | + box-shadow: 0 8rpx 40rpx 0 rgba(76, 175, 80, 0.12); | ||
| 441 | + border: 2rpx solid #e8f5e9; | ||
| 442 | + padding: 40rpx; | ||
| 443 | + margin-bottom: 32rpx; | ||
| 444 | + transition: all 0.2s ease; | ||
| 445 | + } | ||
| 446 | + | ||
| 447 | + .store-card:hover { | ||
| 448 | + transform: translateY(-4rpx); | ||
| 449 | + box-shadow: 0 12rpx 48rpx 0 rgba(76, 175, 80, 0.18); | ||
| 450 | + } | ||
| 451 | + | ||
| 452 | + .store-header { | ||
| 453 | + display: flex; | ||
| 454 | + justify-content: space-between; | ||
| 455 | + align-items: center; | ||
| 456 | + margin-bottom: 24rpx; | ||
| 457 | + padding-bottom: 24rpx; | ||
| 458 | + border-bottom: 2rpx solid #e8f5e9; | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | + .store-name { | ||
| 462 | + font-size: 36rpx; | ||
| 463 | + font-weight: bold; | ||
| 464 | + color: #2e7d32; | ||
| 465 | + flex: 1; | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + .store-status { | ||
| 469 | + padding: 8rpx 20rpx; | ||
| 470 | + border-radius: 16rpx; | ||
| 471 | + font-size: 24rpx; | ||
| 472 | + font-weight: 500; | ||
| 473 | + } | ||
| 474 | + | ||
| 475 | + .status-open { | ||
| 476 | + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); | ||
| 477 | + color: #fff; | ||
| 478 | + } | ||
| 479 | + | ||
| 480 | + .status-closed { | ||
| 481 | + background: #f5f5f5; | ||
| 482 | + color: #999; | ||
| 483 | + } | ||
| 484 | + | ||
| 485 | + .store-row { | ||
| 486 | + display: flex; | ||
| 487 | + flex-wrap: wrap; | ||
| 488 | + margin-bottom: 24rpx; | ||
| 489 | + gap: 16rpx; | ||
| 490 | + } | ||
| 491 | + | ||
| 492 | + .store-row:last-child { | ||
| 493 | + margin-bottom: 0; | ||
| 494 | + } | ||
| 495 | + | ||
| 496 | + .store-item { | ||
| 497 | + flex: 1 1 calc(50% - 8rpx); | ||
| 498 | + min-width: 0; | ||
| 499 | + display: flex; | ||
| 500 | + align-items: center; | ||
| 501 | + gap: 12rpx; | ||
| 502 | + padding: 16rpx 24rpx; | ||
| 503 | + background: #f8fdf8; | ||
| 504 | + border-radius: 16rpx; | ||
| 505 | + border: 2rpx solid #e8f5e9; | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + .store-item.full-width { | ||
| 509 | + flex: 1 1 100%; | ||
| 510 | + } | ||
| 511 | + | ||
| 512 | + .store-label { | ||
| 513 | + color: #388e3c; | ||
| 514 | + font-weight: 600; | ||
| 515 | + font-size: 28rpx; | ||
| 516 | + white-space: nowrap; | ||
| 517 | + margin-right: 30rpx; | ||
| 518 | + text-align: center; | ||
| 519 | + } | ||
| 520 | + | ||
| 521 | + .store-value { | ||
| 522 | + color: #2e7d32; | ||
| 523 | + font-size: 30rpx; | ||
| 524 | + font-weight: 500; | ||
| 525 | + word-break: break-all; | ||
| 526 | + flex: 1; | ||
| 527 | + } | ||
| 528 | + | ||
| 529 | + .loading { | ||
| 530 | + text-align: center; | ||
| 531 | + padding: 80rpx 40rpx; | ||
| 532 | + color: #6a9c6a; | ||
| 533 | + font-size: 28rpx; | ||
| 534 | + display: flex; | ||
| 535 | + flex-direction: column; | ||
| 536 | + align-items: center; | ||
| 537 | + gap: 20rpx; | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + .loading-text { | ||
| 541 | + font-size: 28rpx; | ||
| 542 | + } | ||
| 543 | + | ||
| 544 | + .loading-more { | ||
| 545 | + text-align: center; | ||
| 546 | + padding: 40rpx; | ||
| 547 | + color: #6a9c6a; | ||
| 548 | + font-size: 28rpx; | ||
| 549 | + display: flex; | ||
| 550 | + align-items: center; | ||
| 551 | + justify-content: center; | ||
| 552 | + gap: 16rpx; | ||
| 553 | + } | ||
| 554 | + | ||
| 555 | + .loading-more-text { | ||
| 556 | + font-size: 28rpx; | ||
| 557 | + } | ||
| 558 | + | ||
| 559 | + .no-more-data { | ||
| 560 | + text-align: center; | ||
| 561 | + padding: 40rpx; | ||
| 562 | + color: #6a9c6a; | ||
| 563 | + font-size: 28rpx; | ||
| 564 | + opacity: 0.8; | ||
| 565 | + } | ||
| 566 | + | ||
| 567 | + .empty-state { | ||
| 568 | + text-align: center; | ||
| 569 | + padding: 120rpx 40rpx; | ||
| 570 | + color: #6a9c6a; | ||
| 571 | + } | ||
| 572 | + | ||
| 573 | + .empty-state-icon { | ||
| 574 | + font-size: 120rpx; | ||
| 575 | + margin-bottom: 32rpx; | ||
| 576 | + opacity: 0.6; | ||
| 577 | + } | ||
| 578 | + | ||
| 579 | + .empty-state-text { | ||
| 580 | + font-size: 32rpx; | ||
| 581 | + margin-bottom: 16rpx; | ||
| 582 | + } | ||
| 583 | + | ||
| 584 | + .empty-state-subtext { | ||
| 585 | + font-size: 28rpx; | ||
| 586 | + opacity: 0.8; | ||
| 587 | + } | ||
| 588 | + | ||
| 589 | + .store-actions { | ||
| 590 | + margin-top: 24rpx; | ||
| 591 | + padding-top: 24rpx; | ||
| 592 | + border-top: 2rpx solid #e8f5e9; | ||
| 593 | + } | ||
| 594 | + | ||
| 595 | + .edit-btn { | ||
| 596 | + width: 100%; | ||
| 597 | + height: 72rpx; | ||
| 598 | + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); | ||
| 599 | + color: #fff; | ||
| 600 | + border: none; | ||
| 601 | + border-radius: 16rpx; | ||
| 602 | + font-size: 28rpx; | ||
| 603 | + font-weight: 600; | ||
| 604 | + box-shadow: 0 4rpx 16rpx rgba(67, 233, 123, 0.3); | ||
| 605 | + transition: all 0.2s ease; | ||
| 606 | + } | ||
| 607 | + | ||
| 608 | + .edit-btn:active { | ||
| 609 | + transform: translateY(-2rpx); | ||
| 610 | + box-shadow: 0 6rpx 20rpx rgba(67, 233, 123, 0.4); | ||
| 611 | + } | ||
| 612 | + | ||
| 613 | + /* 编辑弹窗样式 */ | ||
| 614 | + .dialog-overlay { | ||
| 615 | + position: fixed; | ||
| 616 | + top: 0; | ||
| 617 | + left: 0; | ||
| 618 | + right: 0; | ||
| 619 | + bottom: 0; | ||
| 620 | + background: rgba(0, 0, 0, 0.5); | ||
| 621 | + display: flex; | ||
| 622 | + align-items: center; | ||
| 623 | + justify-content: center; | ||
| 624 | + z-index: 9999; | ||
| 625 | + } | ||
| 626 | + | ||
| 627 | + .edit-dialog { | ||
| 628 | + background: #fff; | ||
| 629 | + border-radius: 20rpx; | ||
| 630 | + overflow: hidden; | ||
| 631 | + width: 600rpx; | ||
| 632 | + max-width: 90%; | ||
| 633 | + } | ||
| 634 | + | ||
| 635 | + .dialog-header { | ||
| 636 | + background: linear-gradient(120deg, #43e97b 0%, #38f9d7 100%); | ||
| 637 | + padding: 32rpx 40rpx; | ||
| 638 | + text-align: center; | ||
| 639 | + } | ||
| 640 | + | ||
| 641 | + .dialog-title { | ||
| 642 | + color: #fff; | ||
| 643 | + font-size: 32rpx; | ||
| 644 | + font-weight: 600; | ||
| 645 | + letter-spacing: 2rpx; | ||
| 646 | + } | ||
| 647 | + | ||
| 648 | + .dialog-content { | ||
| 649 | + padding: 40rpx; | ||
| 650 | + } | ||
| 651 | + | ||
| 652 | + .form-item { | ||
| 653 | + margin-bottom: 32rpx; | ||
| 654 | + } | ||
| 655 | + | ||
| 656 | + .form-item:last-child { | ||
| 657 | + margin-bottom: 0; | ||
| 658 | + } | ||
| 659 | + | ||
| 660 | + .form-label { | ||
| 661 | + font-size: 28rpx; | ||
| 662 | + color: #388e3c; | ||
| 663 | + font-weight: 600; | ||
| 664 | + margin-bottom: 16rpx; | ||
| 665 | + display: block; | ||
| 666 | + } | ||
| 667 | + | ||
| 668 | + .form-value { | ||
| 669 | + font-size: 30rpx; | ||
| 670 | + color: #2e7d32; | ||
| 671 | + font-weight: 500; | ||
| 672 | + display: block; | ||
| 673 | + padding: 16rpx 20rpx; | ||
| 674 | + background: #f8fdf8; | ||
| 675 | + border-radius: 12rpx; | ||
| 676 | + border: 2rpx solid #e8f5e9; | ||
| 677 | + } | ||
| 678 | + | ||
| 679 | + .form-item /deep/ .u-input { | ||
| 680 | + border: 2rpx solid #e8f5e9; | ||
| 681 | + border-radius: 12rpx; | ||
| 682 | + background: #f8fff8; | ||
| 683 | + } | ||
| 684 | + | ||
| 685 | + .form-item /deep/ .u-input__content { | ||
| 686 | + padding: 20rpx; | ||
| 687 | + } | ||
| 688 | + | ||
| 689 | + .form-item /deep/ .u-input__content__field-wrapper__field { | ||
| 690 | + font-size: 28rpx; | ||
| 691 | + color: #2e7d32; | ||
| 692 | + } | ||
| 693 | + | ||
| 694 | + .dialog-buttons { | ||
| 695 | + display: flex; | ||
| 696 | + gap: 24rpx; | ||
| 697 | + padding: 0 40rpx 40rpx; | ||
| 698 | + } | ||
| 699 | + | ||
| 700 | + .dialog-btn { | ||
| 701 | + flex: 1; | ||
| 702 | + height: 80rpx; | ||
| 703 | + border-radius: 20rpx; | ||
| 704 | + font-size: 28rpx; | ||
| 705 | + font-weight: 600; | ||
| 706 | + letter-spacing: 2rpx; | ||
| 707 | + transition: all 0.3s ease; | ||
| 708 | + } | ||
| 709 | + | ||
| 710 | + .cancel-dialog-btn { | ||
| 711 | + background: #f5f5f5; | ||
| 712 | + color: #666; | ||
| 713 | + border: 2rpx solid #e0e0e0; | ||
| 714 | + } | ||
| 715 | + | ||
| 716 | + .cancel-dialog-btn:active { | ||
| 717 | + background: #eeeeee; | ||
| 718 | + } | ||
| 719 | + | ||
| 720 | + .confirm-dialog-btn { | ||
| 721 | + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); | ||
| 722 | + color: #fff; | ||
| 723 | + border: none; | ||
| 724 | + box-shadow: 0 4rpx 16rpx rgba(67, 233, 123, 0.3); | ||
| 725 | + } | ||
| 726 | + | ||
| 727 | + .confirm-dialog-btn:active { | ||
| 728 | + transform: translateY(-2rpx); | ||
| 729 | + box-shadow: 0 6rpx 20rpx rgba(67, 233, 123, 0.4); | ||
| 730 | + } | ||
| 731 | +</style> | ||
| 732 | + |