| @ -0,0 +1,61 @@ | |||
| import request from '@/utils/request' | |||
| // 查询日订单列表 | |||
| export function listAppletOrderDateFrequency(query) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency/list', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| // 查询日订单详细 | |||
| export function getAppletOrderDateFrequency(id) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 查询日订单详细 | |||
| export function getAppletOrderDateFrequencyCheck(id) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency/check/' + id, | |||
| method: 'get' | |||
| }) | |||
| } | |||
| // 新增日订单 | |||
| export function addAppletOrderDateFrequency(data) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency', | |||
| method: 'post', | |||
| data: data | |||
| }) | |||
| } | |||
| // 修改日订单 | |||
| export function updateAppletOrderDateFrequency(data) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency', | |||
| method: 'put', | |||
| data: data | |||
| }) | |||
| } | |||
| // 删除日订单 | |||
| export function delAppletOrderDateFrequency(id) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency/' + id, | |||
| method: 'delete' | |||
| }) | |||
| } | |||
| // 导出日订单 | |||
| export function exportAppletOrderDateFrequency(query) { | |||
| return request({ | |||
| url: '/model/appletOrderDateFrequency/export', | |||
| method: 'get', | |||
| params: query | |||
| }) | |||
| } | |||
| @ -0,0 +1,540 @@ | |||
| <template> | |||
| <el-dialog title="打卡信息" :visible.sync="visible" width="80%" :before-close="handleClose" class="checkin-dialog"> | |||
| <div v-loading="loading" class="checkin-content"> | |||
| <!-- 个人准备 --> | |||
| <div class="section"> | |||
| <div class="section-title"> | |||
| <span class="title-text">个人准备</span> | |||
| </div> | |||
| <div class="upload-group"> | |||
| <div class="upload-item"> | |||
| <div class="upload-label">手套照片</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.gloveImages && checkinData.gloveImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.gloveImages" :key="index" class="image-item" | |||
| @click="previewImage(image)"> | |||
| <img :src="image" alt="手套照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| <div class="upload-item"> | |||
| <div class="upload-label">鞋套照片</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.shoeImages && checkinData.shoeImages.length > 0" class="image-list"> | |||
| <div v-for="(image, index) in checkinData.shoeImages" :key="index" class="image-item" | |||
| @click="previewImage(image)"> | |||
| <img :src="image" alt="鞋套照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 宠物状态记录 --> | |||
| <div class="section"> | |||
| <div class="section-title"> | |||
| <span class="title-text">宠物状态记录</span> | |||
| </div> | |||
| <div v-if="checkinData.petList && checkinData.petList.length > 0"> | |||
| <div v-for="(pet, index) in checkinData.petList" :key="index" class="pet-item"> | |||
| <div class="upload-label">{{ pet.title }}照片</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="pet.images && pet.images.length > 0" class="image-list"> | |||
| <div | |||
| v-for="(image, imgIndex) in pet.images" | |||
| :key="imgIndex" | |||
| class="image-item" | |||
| @click="previewImage(image)" | |||
| > | |||
| <img :src="image" alt="宠物状态照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无宠物数据</div> | |||
| </div> | |||
| <!-- 基础服务记录 --> | |||
| <div class="section"> | |||
| <div class="section-title"> | |||
| <span class="title-text">基础服务记录</span> | |||
| </div> | |||
| <div class="service-item"> | |||
| <div class="service-label">粮碗前后对比</div> | |||
| <div class="compare-container"> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">前</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.groomingBeforeImages && checkinData.groomingBeforeImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.groomingBeforeImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="粮碗前照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">后</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.groomingAfterImages && checkinData.groomingAfterImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.groomingAfterImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="粮碗后照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="service-item"> | |||
| <div class="service-label">水碗前后对比</div> | |||
| <div class="compare-container"> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">前</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.waterBowlBeforeImages && checkinData.waterBowlBeforeImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.waterBowlBeforeImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="水碗前照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">后</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.waterBowlAfterImages && checkinData.waterBowlAfterImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.waterBowlAfterImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="水碗后照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="service-item"> | |||
| <div class="service-label">猫砂盆、尿垫前后对比</div> | |||
| <div class="compare-container"> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">前</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.basinBeforeImages && checkinData.basinBeforeImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.basinBeforeImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="猫砂盆前照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| <div class="compare-item"> | |||
| <div class="compare-label">后</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="checkinData.basinAfterImages && checkinData.basinAfterImages.length > 0" | |||
| class="image-list"> | |||
| <div v-for="(image, index) in checkinData.basinAfterImages" :key="index" | |||
| class="image-item" @click="previewImage(image)"> | |||
| <img :src="image" alt="猫砂盆后照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 定制服务记录 --> | |||
| <div class="section" v-if="checkinData.projectList && checkinData.projectList.length > 0"> | |||
| <div class="section-title"> | |||
| <span class="title-text">定制服务记录</span> | |||
| </div> | |||
| <div v-for="(project, index) in checkinData.projectList" :key="index" class="project-item"> | |||
| <div class="upload-label">{{ project.title }}</div> | |||
| <div class="image-gallery"> | |||
| <div v-if="project.images && project.images.length > 0" class="image-list"> | |||
| <div | |||
| v-for="(image, imgIndex) in project.images" | |||
| :key="imgIndex" | |||
| class="image-item" | |||
| @click="previewImage(image)" | |||
| > | |||
| <img :src="image" alt="定制服务照片" /> | |||
| </div> | |||
| </div> | |||
| <div v-else class="no-data">暂无图片</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- 其他补充信息 --> | |||
| <div class="section" v-if="checkinData.notes"> | |||
| <div class="section-title"> | |||
| <span class="title-text">其他补充信息</span> | |||
| </div> | |||
| <div class="notes-content"> | |||
| {{ checkinData.notes }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div slot="footer" class="dialog-footer"> | |||
| <el-button @click="handleClose">关 闭</el-button> | |||
| </div> | |||
| <!-- 图片预览弹窗 --> | |||
| <el-dialog title="图片预览" :visible.sync="previewVisible" width="60%" class="image-preview-dialog"> | |||
| <div class="preview-container"> | |||
| <img :src="previewImageUrl" alt="预览图片" style="max-width: 100%; max-height: 500px;" /> | |||
| </div> | |||
| </el-dialog> | |||
| </el-dialog> | |||
| </template> | |||
| <script> | |||
| import { getAppletOrderDateFrequencyCheck } from "@/api/model/appletOrderDateFrequency"; | |||
| export default { | |||
| name: 'CheckinDialog', | |||
| props: { | |||
| value: { | |||
| type: Boolean, | |||
| default: false | |||
| }, | |||
| orderData: { | |||
| type: Object, | |||
| default: () => ({}) | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| visible: this.value, | |||
| loading: false, | |||
| checkinData: {}, | |||
| previewVisible: false, | |||
| previewImageUrl: '' | |||
| } | |||
| }, | |||
| watch: { | |||
| value(val) { | |||
| this.visible = val | |||
| if (val && this.orderData.id) { | |||
| this.loadCheckinData() | |||
| } | |||
| }, | |||
| visible(val) { | |||
| this.$emit('input', val) | |||
| } | |||
| }, | |||
| methods: { | |||
| // 加载打卡数据 | |||
| loadCheckinData() { | |||
| this.loading = true | |||
| getAppletOrderDateFrequencyCheck(this.orderData.id).then(response => { | |||
| if (response.code === 200) { | |||
| const data = response.data || {} | |||
| // 处理数据格式,将接口返回的字段映射到组件需要的格式 | |||
| this.checkinData = { | |||
| // 手套照片 - 单个字符串转为数组 | |||
| gloveImages: data.glovePhoto ? [data.glovePhoto] : [], | |||
| // 鞋套照片 - 单个字符串转为数组 | |||
| shoeImages: data.shoeCoverPhoto ? [data.shoeCoverPhoto] : [], | |||
| // 粮碗前后对比(原梳毛前后对比) | |||
| groomingBeforeImages: data.grainBowlFront ? [data.grainBowlFront] : [], | |||
| groomingAfterImages: data.grainBowlAfter ? [data.grainBowlAfter] : [], | |||
| // 水碗前后对比 | |||
| waterBowlBeforeImages: data.waterBowlFront ? [data.waterBowlFront] : [], | |||
| waterBowlAfterImages: data.waterBowlAfter ? [data.waterBowlAfter] : [], | |||
| // 猫砂盆/尿垫前后对比(原洗澡盆前后对比) | |||
| basinBeforeImages: data.basinFront ? [data.basinFront] : [], | |||
| basinAfterImages: data.basinAfter ? [data.basinAfter] : [], | |||
| // 宠物列表 | |||
| petList: this.parsePetList(data.petPhoto), | |||
| // 定制服务列表 | |||
| projectList: this.parseProjectList(data.workDogImage), | |||
| // 其他补充信息 | |||
| notes: data.notes | |||
| } | |||
| } else { | |||
| this.$message.error('获取打卡数据失败') | |||
| this.checkinData = {} | |||
| } | |||
| this.loading = false | |||
| }).catch(error => { | |||
| console.error('获取打卡数据失败:', error) | |||
| this.$message.error('获取打卡数据失败') | |||
| this.checkinData = {} | |||
| this.loading = false | |||
| }) | |||
| }, | |||
| // 解析图片数组(处理JSON字符串格式的图片数据) | |||
| parseImageArray(...jsonStrings) { | |||
| let images = [] | |||
| jsonStrings.forEach(jsonStr => { | |||
| if (jsonStr) { | |||
| try { | |||
| const parsed = JSON.parse(jsonStr) | |||
| if (Array.isArray(parsed)) { | |||
| parsed.forEach(item => { | |||
| if (item.fileList) { | |||
| // 如果fileList是逗号分隔的字符串,拆分成数组 | |||
| const fileList = item.fileList.split(',').filter(url => url.trim()) | |||
| images.push(...fileList) | |||
| } | |||
| }) | |||
| } | |||
| } catch (e) { | |||
| console.warn('解析图片数据失败:', e) | |||
| } | |||
| } | |||
| }) | |||
| return images | |||
| }, | |||
| // 预览图片 | |||
| previewImage(imageUrl) { | |||
| this.previewImageUrl = imageUrl | |||
| this.previewVisible = true | |||
| }, | |||
| // 关闭弹窗 | |||
| handleClose() { | |||
| this.visible = false | |||
| this.checkinData = {} | |||
| }, | |||
| // 解析宠物列表 | |||
| parsePetList(petPhoto) { | |||
| if (petPhoto) { | |||
| try { | |||
| const petList = JSON.parse(petPhoto) | |||
| return petList.map(pet => ({ | |||
| title: pet.title, | |||
| images: pet.fileList ? pet.fileList.split(',').filter(url => url.trim()) : [] | |||
| })) | |||
| } catch (e) { | |||
| console.warn('解析宠物数据失败:', e) | |||
| return [] | |||
| } | |||
| } | |||
| return [] | |||
| }, | |||
| // 解析定制服务列表 | |||
| parseProjectList(workDogImage) { | |||
| if (workDogImage) { | |||
| try { | |||
| const projectList = JSON.parse(workDogImage) | |||
| return projectList.map(project => ({ | |||
| title: project.title, | |||
| images: project.fileList ? project.fileList.split(',').filter(url => url.trim()) : [] | |||
| })) | |||
| } catch (e) { | |||
| console.warn('解析定制服务数据失败:', e) | |||
| return [] | |||
| } | |||
| } | |||
| return [] | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| .checkin-dialog { | |||
| .checkin-content { | |||
| max-height: 70vh; | |||
| overflow-y: auto; | |||
| } | |||
| .section { | |||
| margin-bottom: 30px; | |||
| padding: 20px; | |||
| border: 1px solid #e4e7ed; | |||
| border-radius: 6px; | |||
| background-color: #fafafa; | |||
| .section-title { | |||
| margin-bottom: 20px; | |||
| .title-text { | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| color: #ff9500; | |||
| position: relative; | |||
| &::before { | |||
| content: ''; | |||
| position: absolute; | |||
| left: -10px; | |||
| top: 50%; | |||
| transform: translateY(-50%); | |||
| width: 4px; | |||
| height: 16px; | |||
| background-color: #ff9500; | |||
| border-radius: 2px; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .upload-group { | |||
| display: flex; | |||
| gap: 40px; | |||
| flex-wrap: wrap; | |||
| } | |||
| .upload-item { | |||
| flex: 1; | |||
| min-width: 300px; | |||
| .upload-label { | |||
| margin-bottom: 10px; | |||
| font-weight: 500; | |||
| color: #333; | |||
| } | |||
| } | |||
| .pet-item, | |||
| .project-item { | |||
| margin-bottom: 20px; | |||
| .upload-label { | |||
| margin-bottom: 10px; | |||
| font-weight: 500; | |||
| color: #333; | |||
| } | |||
| } | |||
| .notes-content { | |||
| padding: 15px; | |||
| background-color: #f5f5f5; | |||
| border-radius: 8px; | |||
| border: 1px solid #e4e7ed; | |||
| color: #606266; | |||
| font-size: 14px; | |||
| line-height: 1.6; | |||
| white-space: pre-wrap; | |||
| word-break: break-word; | |||
| } | |||
| .service-item { | |||
| margin-bottom: 30px; | |||
| .service-label { | |||
| margin-bottom: 15px; | |||
| font-weight: 500; | |||
| color: #333; | |||
| } | |||
| .compare-container { | |||
| display: flex; | |||
| gap: 40px; | |||
| .compare-item { | |||
| flex: 1; | |||
| .compare-label { | |||
| text-align: center; | |||
| margin-bottom: 10px; | |||
| font-weight: 500; | |||
| color: #666; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .image-gallery { | |||
| min-height: 100px; | |||
| .image-list { | |||
| display: flex; | |||
| flex-wrap: wrap; | |||
| gap: 10px; | |||
| .image-item { | |||
| width: 100px; | |||
| height: 100px; | |||
| border: 1px solid #d9d9d9; | |||
| border-radius: 6px; | |||
| overflow: hidden; | |||
| cursor: pointer; | |||
| transition: all 0.3s; | |||
| &:hover { | |||
| border-color: #409eff; | |||
| transform: scale(1.05); | |||
| } | |||
| img { | |||
| width: 100%; | |||
| height: 100%; | |||
| object-fit: cover; | |||
| } | |||
| } | |||
| } | |||
| .no-data { | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| height: 100px; | |||
| color: #999; | |||
| font-size: 14px; | |||
| border: 1px dashed #d9d9d9; | |||
| border-radius: 6px; | |||
| background-color: #fafafa; | |||
| } | |||
| } | |||
| } | |||
| .dialog-footer { | |||
| text-align: right; | |||
| padding-top: 20px; | |||
| border-top: 1px solid #e4e7ed; | |||
| } | |||
| .image-preview-dialog { | |||
| .preview-container { | |||
| text-align: center; | |||
| } | |||
| } | |||
| </style> | |||
| @ -1,29 +1,30 @@ | |||
| <template> | |||
| <el-tag :type="valueType">{{valueLabel}}</el-tag> | |||
| <el-tag :type="valueType">{{ valueLabel }}</el-tag> | |||
| </template> | |||
| <script> | |||
| import {mapGetters} from "vuex"; | |||
| import { mapGetters } from "vuex"; | |||
| export default { | |||
| props: ["value", "propName", 'options'], | |||
| computed: { | |||
| ...mapGetters(['dictMap']), | |||
| options1() { | |||
| if (this.options) { | |||
| return this.options; | |||
| } | |||
| if (!this.propName) { | |||
| return []; | |||
| } | |||
| return this.dictMap[this.propName] || [] | |||
| props: ["value", "propName", 'options'], | |||
| computed: { | |||
| ...mapGetters(['dictMap']), | |||
| options1() { | |||
| if (this.options) { | |||
| return this.options; | |||
| } | |||
| if (!this.propName) { | |||
| return []; | |||
| } | |||
| return this.dictMap[this.propName] || [] | |||
| }, | |||
| valueLabel() { | |||
| return this.options1.find(it => it.value === this.value || it.value == this.value)?.label; | |||
| }, | |||
| valueType() { | |||
| let data = this.options1.find(it => it.value === this.value || it.value == this.value) | |||
| return data && (data.listClass || data.raw.listClass); | |||
| } | |||
| }, | |||
| valueLabel() { | |||
| return this.options1.find(it => it.value === this.value || it.value == this.value)?.label; | |||
| }, | |||
| valueType() { | |||
| return this.options1.find(it => it.value === this.value || it.value == this.value)?.listClass; | |||
| } | |||
| }, | |||
| }; | |||
| </script> | |||
| @ -1,310 +1,277 @@ | |||
| <template> | |||
| <div class="app-container"> | |||
| <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" size="medium" class="ry_form"> | |||
| <el-form-item label="名称" prop="name"> | |||
| <el-input | |||
| v-model="queryParams.name" | |||
| placeholder="请输入名称" | |||
| clearable | |||
| size="small" | |||
| @keyup.enter.native="handleQuery" | |||
| /> | |||
| </el-form-item> | |||
| <el-form-item label="地址" prop="url"> | |||
| <el-input | |||
| v-model="queryParams.url" | |||
| placeholder="请输入地址" | |||
| clearable | |||
| size="small" | |||
| @keyup.enter.native="handleQuery" | |||
| /> | |||
| </el-form-item> | |||
| <el-form-item label="类别" prop="type"> | |||
| <el-select v-model="queryParams.type" placeholder="请选择类别" clearable size="small"> | |||
| </el-select> | |||
| </el-form-item> | |||
| <el-form-item class="flex_one tr"> | |||
| <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |||
| <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||
| </el-form-item> | |||
| </el-form> | |||
| <div class="app-container"> | |||
| <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" | |||
| size="medium" class="ry_form"> | |||
| <el-form-item label="名称" prop="name"> | |||
| <el-input v-model="queryParams.name" placeholder="请输入名称" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="地址" prop="url"> | |||
| <el-input v-model="queryParams.url" placeholder="请输入地址" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="类别" prop="type"> | |||
| <el-select v-model="queryParams.type" placeholder="请选择类别" clearable size="small"> | |||
| <el-option | |||
| v-for="dict in dict.type.applet_icon_type" | |||
| :key="dict.value" | |||
| :label="dict.label" | |||
| :value="dict.value" | |||
| /> | |||
| </el-select> | |||
| </el-form-item> | |||
| <el-form-item class="flex_one tr"> | |||
| <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |||
| <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||
| </el-form-item> | |||
| </el-form> | |||
| <el-row :gutter="10" class="mb8"> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="primary" | |||
| plain | |||
| icon="el-icon-plus" | |||
| size="mini" | |||
| @click="handleAdd" | |||
| v-hasPermi="['model:AppletIcon:add']" | |||
| >新增</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="success" | |||
| plain | |||
| icon="el-icon-edit" | |||
| size="mini" | |||
| :disabled="single" | |||
| @click="handleUpdate" | |||
| v-hasPermi="['model:AppletIcon:edit']" | |||
| >修改</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="danger" | |||
| plain | |||
| icon="el-icon-delete" | |||
| size="mini" | |||
| :disabled="multiple" | |||
| @click="handleDelete" | |||
| v-hasPermi="['model:AppletIcon:remove']" | |||
| >删除</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="warning" | |||
| plain | |||
| icon="el-icon-download" | |||
| size="mini" | |||
| :loading="exportLoading" | |||
| @click="handleExport" | |||
| v-hasPermi="['model:AppletIcon:export']" | |||
| >导出</el-button> | |||
| </el-col> | |||
| <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> | |||
| </el-row> | |||
| <el-row :gutter="10" class="mb8"> | |||
| <el-col :span="1.5"> | |||
| <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" | |||
| v-hasPermi="['model:AppletIcon:add']">新增</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" | |||
| v-hasPermi="['model:AppletIcon:edit']">修改</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" | |||
| @click="handleDelete" v-hasPermi="['model:AppletIcon:remove']">删除</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" | |||
| @click="handleExport" v-hasPermi="['model:AppletIcon:export']">导出</el-button> | |||
| </el-col> | |||
| <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> | |||
| </el-row> | |||
| <el-table v-loading="loading" :data="AppletIconList" @selection-change="handleSelectionChange"> | |||
| <el-table-column type="selection" width="55" align="center" /> | |||
| <el-table-column label="唯一标识" align="center" prop="id" /> | |||
| <el-table-column label="名称" align="center" prop="name" v-if="columns[0].visible"/> | |||
| <el-table-column label="图标" align="center" prop="image" v-if="columns[1].visible"/> | |||
| <el-table-column label="地址" align="center" prop="url" v-if="columns[2].visible"/> | |||
| <el-table-column label="类别" align="center" prop="type" v-if="columns[3].visible"/> | |||
| <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |||
| <template slot-scope="scope"> | |||
| <el-button | |||
| size="mini" | |||
| type="text" | |||
| icon="el-icon-edit" | |||
| @click="handleUpdate(scope.row)" | |||
| v-hasPermi="['model:AppletIcon:edit']" | |||
| >修改</el-button> | |||
| <el-button | |||
| size="mini" | |||
| type="text" | |||
| icon="el-icon-delete" | |||
| @click="handleDelete(scope.row)" | |||
| v-hasPermi="['model:AppletIcon:remove']" | |||
| >删除</el-button> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| <pagination | |||
| v-show="total>0" | |||
| :total="total" | |||
| :page.sync="queryParams.pageNum" | |||
| :limit.sync="queryParams.pageSize" | |||
| @pagination="getList" | |||
| /> | |||
| <el-table v-loading="loading" :data="AppletIconList" @selection-change="handleSelectionChange"> | |||
| <el-table-column type="selection" width="55" align="center" /> | |||
| <el-table-column label="ID" align="center" prop="id" /> | |||
| <el-table-column label="名称" align="center" prop="name" v-if="columns[0].visible" /> | |||
| <el-table-column label="图标" align="center" prop="image" v-if="columns[1].visible" /> | |||
| <el-table-column label="地址" align="center" prop="url" v-if="columns[2].visible" /> | |||
| <el-table-column label="类别" align="center" prop="type" v-if="columns[3].visible" > | |||
| <template slot-scope="scope"> | |||
| <dict-tag :options="dict.type.applet_icon_type" :value="scope.row.type"/> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | |||
| <template slot-scope="scope"> | |||
| <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" | |||
| v-hasPermi="['model:AppletIcon:edit']">修改</el-button> | |||
| <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" | |||
| v-hasPermi="['model:AppletIcon:remove']">删除</el-button> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| <!-- 添加或修改跳转图标菜单对话框 --> | |||
| <el-dialog :title="title" :visible.sync="open" width="50%" append-to-body> | |||
| <el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two"> | |||
| <el-form-item label="名称" prop="name"> | |||
| <el-input v-model="form.name" placeholder="请输入名称" /> | |||
| </el-form-item> | |||
| <el-form-item label="图标"> | |||
| <imageUpload v-model="form.image"/> | |||
| </el-form-item> | |||
| <el-form-item label="地址" prop="url"> | |||
| <el-input v-model="form.url" placeholder="请输入地址" /> | |||
| </el-form-item> | |||
| <el-form-item label="逻辑删除标识" prop="delFlag"> | |||
| <el-input v-model="form.delFlag" placeholder="请输入逻辑删除标识" /> | |||
| </el-form-item> | |||
| </el-form> | |||
| <div slot="footer" class="dialog-footer"> | |||
| <el-button type="primary" @click="submitForm">确 定</el-button> | |||
| <el-button @click="cancel">取 消</el-button> | |||
| </div> | |||
| </el-dialog> | |||
| </div> | |||
| <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" | |||
| @pagination="getList" /> | |||
| <!-- 添加或修改跳转图标菜单对话框 --> | |||
| <el-dialog :title="title" :visible.sync="open" width="50%" append-to-body> | |||
| <el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two"> | |||
| <el-form-item label="名称" prop="name"> | |||
| <el-input v-model="form.name" placeholder="请输入名称" /> | |||
| </el-form-item> | |||
| <el-form-item label="图标"> | |||
| <!-- <imageUpload v-model="form.image" /> --> | |||
| <el-input v-model="form.image" placeholder="请输入图标" /> | |||
| </el-form-item> | |||
| <el-form-item label="地址" prop="url"> | |||
| <el-input v-model="form.url" placeholder="请输入地址" /> | |||
| </el-form-item> | |||
| <el-form-item label="类别" prop="type"> | |||
| <el-radio-group v-model="form.type"> | |||
| <el-radio | |||
| v-for="dict in dict.type.applet_icon_type" | |||
| :key="dict.value" | |||
| :label="dict.value" | |||
| >{{dict.label}}</el-radio> | |||
| </el-radio-group> | |||
| </el-form-item> | |||
| </el-form> | |||
| <div slot="footer" class="dialog-footer"> | |||
| <el-button type="primary" @click="submitForm">确 定</el-button> | |||
| <el-button @click="cancel">取 消</el-button> | |||
| </div> | |||
| </el-dialog> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { listAppletIcon, getAppletIcon, delAppletIcon, addAppletIcon, updateAppletIcon, exportAppletIcon } from "@/api/model/AppletIcon"; | |||
| export default { | |||
| name: "AppletIcon", | |||
| data() { | |||
| return { | |||
| // 遮罩层 | |||
| loading: true, | |||
| // 导出遮罩层 | |||
| exportLoading: false, | |||
| // 选中数组 | |||
| ids: [], | |||
| // 非单个禁用 | |||
| single: true, | |||
| // 非多个禁用 | |||
| multiple: true, | |||
| // 显示搜索条件 | |||
| showSearch: true, | |||
| // 总条数 | |||
| total: 0, | |||
| // 跳转图标菜单表格数据 | |||
| AppletIconList: [], | |||
| // 弹出层标题 | |||
| title: "", | |||
| // 是否显示弹出层 | |||
| open: false, | |||
| // 查询参数 | |||
| queryParams: { | |||
| pageNum: 1, | |||
| pageSize: 10, | |||
| name: null, | |||
| name: "AppletIcon", | |||
| dicts: ['applet_icon_type'], | |||
| data() { | |||
| return { | |||
| // 遮罩层 | |||
| loading: true, | |||
| // 导出遮罩层 | |||
| exportLoading: false, | |||
| // 选中数组 | |||
| ids: [], | |||
| // 非单个禁用 | |||
| single: true, | |||
| // 非多个禁用 | |||
| multiple: true, | |||
| // 显示搜索条件 | |||
| showSearch: true, | |||
| // 总条数 | |||
| total: 0, | |||
| // 跳转图标菜单表格数据 | |||
| AppletIconList: [], | |||
| // 弹出层标题 | |||
| title: "", | |||
| // 是否显示弹出层 | |||
| open: false, | |||
| // 查询参数 | |||
| queryParams: { | |||
| pageNum: 1, | |||
| pageSize: 10, | |||
| name: null, | |||
| image: null, | |||
| image: null, | |||
| url: null, | |||
| url: null, | |||
| type: null, | |||
| type: null, | |||
| }, | |||
| // 表单参数 | |||
| form: {}, | |||
| // 表单校验 | |||
| rules: { | |||
| }, | |||
| columns: [ | |||
| { key: 1, label: "名称", visible: true }, | |||
| { key: 2, label: "图标", visible: false }, | |||
| { key: 3, label: "地址", visible: true }, | |||
| { key: 4, label: "类别", visible: true }, | |||
| ], | |||
| }; | |||
| }, | |||
| created() { | |||
| this.getList(); | |||
| }, | |||
| methods: { | |||
| /** 查询跳转图标菜单列表 */ | |||
| getList() { | |||
| this.loading = true; | |||
| listAppletIcon(this.queryParams).then(response => { | |||
| this.AppletIconList = response.rows; | |||
| this.total = response.total; | |||
| this.loading = false; | |||
| }); | |||
| }, | |||
| // 表单参数 | |||
| form: {}, | |||
| // 表单校验 | |||
| rules: { | |||
| }, | |||
| columns: [ | |||
| { key: 1, label: "名称", visible: true }, | |||
| { key: 2, label: "图标", visible: false }, | |||
| { key: 3, label: "地址", visible: true }, | |||
| { key: 4, label: "类别", visible: true }, | |||
| ], | |||
| }; | |||
| }, | |||
| // 取消按钮 | |||
| cancel() { | |||
| this.open = false; | |||
| this.reset(); | |||
| created() { | |||
| this.getList(); | |||
| }, | |||
| // 表单重置 | |||
| reset() { | |||
| this.form = { | |||
| id: null, | |||
| methods: { | |||
| /** 查询跳转图标菜单列表 */ | |||
| getList() { | |||
| this.loading = true; | |||
| listAppletIcon(this.queryParams).then(response => { | |||
| this.AppletIconList = response.rows; | |||
| this.total = response.total; | |||
| this.loading = false; | |||
| }); | |||
| }, | |||
| // 取消按钮 | |||
| cancel() { | |||
| this.open = false; | |||
| this.reset(); | |||
| }, | |||
| // 表单重置 | |||
| reset() { | |||
| this.form = { | |||
| id: null, | |||
| name: null, | |||
| name: null, | |||
| image: null, | |||
| image: null, | |||
| url: null, | |||
| url: null, | |||
| type: null, | |||
| type: null, | |||
| createTime: null, | |||
| createTime: null, | |||
| createBy: null, | |||
| createBy: null, | |||
| updateTime: null, | |||
| updateTime: null, | |||
| updateBy: null, | |||
| updateBy: null, | |||
| delFlag: null, | |||
| delFlag: null, | |||
| }; | |||
| this.resetForm("form"); | |||
| }, | |||
| /** 搜索按钮操作 */ | |||
| handleQuery() { | |||
| this.queryParams.pageNum = 1; | |||
| this.getList(); | |||
| }, | |||
| /** 重置按钮操作 */ | |||
| resetQuery() { | |||
| this.resetForm("queryForm"); | |||
| this.handleQuery(); | |||
| }, | |||
| // 多选框选中数据 | |||
| handleSelectionChange(selection) { | |||
| this.ids = selection.map(item => item.id) | |||
| this.single = selection.length!==1 | |||
| this.multiple = !selection.length | |||
| }, | |||
| /** 新增按钮操作 */ | |||
| handleAdd() { | |||
| this.reset(); | |||
| this.open = true; | |||
| this.title = "添加跳转图标菜单"; | |||
| }, | |||
| /** 修改按钮操作 */ | |||
| handleUpdate(row) { | |||
| this.reset(); | |||
| const id = row.id || this.ids | |||
| getAppletIcon(id).then(response => { | |||
| this.form = response.data; | |||
| this.open = true; | |||
| this.title = "修改跳转图标菜单"; | |||
| }); | |||
| }, | |||
| /** 提交按钮 */ | |||
| submitForm() { | |||
| this.$refs["form"].validate(valid => { | |||
| if (valid) { | |||
| if (this.form.id != null) { | |||
| updateAppletIcon(this.form).then(response => { | |||
| this.$modal.msgSuccess("修改成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }; | |||
| this.resetForm("form"); | |||
| }, | |||
| /** 搜索按钮操作 */ | |||
| handleQuery() { | |||
| this.queryParams.pageNum = 1; | |||
| this.getList(); | |||
| }, | |||
| /** 重置按钮操作 */ | |||
| resetQuery() { | |||
| this.resetForm("queryForm"); | |||
| this.handleQuery(); | |||
| }, | |||
| // 多选框选中数据 | |||
| handleSelectionChange(selection) { | |||
| this.ids = selection.map(item => item.id) | |||
| this.single = selection.length !== 1 | |||
| this.multiple = !selection.length | |||
| }, | |||
| /** 新增按钮操作 */ | |||
| handleAdd() { | |||
| this.reset(); | |||
| this.open = true; | |||
| this.title = "添加跳转图标菜单"; | |||
| }, | |||
| /** 修改按钮操作 */ | |||
| handleUpdate(row) { | |||
| this.reset(); | |||
| const id = row.id || this.ids | |||
| getAppletIcon(id).then(response => { | |||
| this.form = response.data; | |||
| this.open = true; | |||
| this.title = "修改跳转图标菜单"; | |||
| }); | |||
| } else { | |||
| addAppletIcon(this.form).then(response => { | |||
| this.$modal.msgSuccess("新增成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }, | |||
| /** 提交按钮 */ | |||
| submitForm() { | |||
| this.$refs["form"].validate(valid => { | |||
| if (valid) { | |||
| if (this.form.id != null) { | |||
| updateAppletIcon(this.form).then(response => { | |||
| this.$modal.msgSuccess("修改成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }); | |||
| } else { | |||
| addAppletIcon(this.form).then(response => { | |||
| this.$modal.msgSuccess("新增成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }); | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| }, | |||
| /** 删除按钮操作 */ | |||
| handleDelete(row) { | |||
| const ids = row.id || this.ids; | |||
| this.$modal.confirm('是否确认删除跳转图标菜单编号为"' + ids + '"的数据项?').then(function () { | |||
| return delAppletIcon(ids); | |||
| }).then(() => { | |||
| this.getList(); | |||
| this.$modal.msgSuccess("删除成功"); | |||
| }).catch(() => { }); | |||
| }, | |||
| /** 导出按钮操作 */ | |||
| handleExport() { | |||
| const queryParams = this.queryParams; | |||
| this.$modal.confirm('是否确认导出所有跳转图标菜单数据项?').then(() => { | |||
| this.exportLoading = true; | |||
| return exportAppletIcon(queryParams); | |||
| }).then(response => { | |||
| this.download(response.msg); | |||
| this.exportLoading = false; | |||
| }).catch(() => { }); | |||
| } | |||
| }); | |||
| }, | |||
| /** 删除按钮操作 */ | |||
| handleDelete(row) { | |||
| const ids = row.id || this.ids; | |||
| this.$modal.confirm('是否确认删除跳转图标菜单编号为"' + ids + '"的数据项?').then(function() { | |||
| return delAppletIcon(ids); | |||
| }).then(() => { | |||
| this.getList(); | |||
| this.$modal.msgSuccess("删除成功"); | |||
| }).catch(() => {}); | |||
| }, | |||
| /** 导出按钮操作 */ | |||
| handleExport() { | |||
| const queryParams = this.queryParams; | |||
| this.$modal.confirm('是否确认导出所有跳转图标菜单数据项?').then(() => { | |||
| this.exportLoading = true; | |||
| return exportAppletIcon(queryParams); | |||
| }).then(response => { | |||
| this.download(response.msg); | |||
| this.exportLoading = false; | |||
| }).catch(() => {}); | |||
| } | |||
| } | |||
| }; | |||
| </script> | |||
| @ -0,0 +1,453 @@ | |||
| <template> | |||
| <div class="app-container"> | |||
| <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="100px" | |||
| size="medium" class="ry_form"> | |||
| <el-form-item label="订单ID" prop="orderId"> | |||
| <el-input v-model="queryParams.orderId" placeholder="请输入订单ID" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="服务日期" prop="serviceDate"> | |||
| <el-input v-model="queryParams.serviceDate" placeholder="请输入服务日期" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <!-- <el-form-item label="省份" prop="receiverProvince"> | |||
| <el-input v-model="queryParams.receiverProvince" placeholder="请输入省份" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="城市" prop="receiverCity"> | |||
| <el-input v-model="queryParams.receiverCity" placeholder="请输入城市" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> --> | |||
| <!-- <el-form-item label="区县" prop="receiverDistrict"> | |||
| <el-input | |||
| v-model="queryParams.receiverDistrict" | |||
| placeholder="请输入区县" | |||
| clearable | |||
| size="small" | |||
| @keyup.enter.native="handleQuery" | |||
| /> | |||
| </el-form-item> --> | |||
| <el-form-item label="伴宠师" prop="masterId"> | |||
| <el-input v-model="queryParams.masterId" placeholder="请输入伴宠师" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="下单用户" prop="userId"> | |||
| <el-input v-model="queryParams.userId" placeholder="请输入下单用户" clearable size="small" | |||
| @keyup.enter.native="handleQuery" /> | |||
| </el-form-item> | |||
| <el-form-item label="完成状态" prop="status"> | |||
| <el-select v-model="queryParams.status" placeholder="请选择完成状态" clearable size="small"> | |||
| <el-option v-for="dict in dict.type.order_check_status" :key="dict.value" :label="dict.label" | |||
| :value="dict.value" /> | |||
| </el-select> | |||
| </el-form-item> | |||
| <!-- <template v-if="showMoreCondition"> | |||
| <el-form-item label="完成状态" prop="status"> | |||
| <el-select v-model="queryParams.status" placeholder="请选择完成状态" clearable size="small"> | |||
| <el-option | |||
| v-for="dict in dict.type.order_check_status" | |||
| :key="dict.value" | |||
| :label="dict.label" | |||
| :value="dict.value" | |||
| /> | |||
| </el-select> | |||
| </el-form-item> | |||
| </template> --> | |||
| <el-form-item class="flex_one tr"> | |||
| <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button> | |||
| <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> | |||
| <!-- <el-button :icon="showMoreCondition ? 'el-icon-arrow-up' : 'el-icon-arrow-down'" size="mini" @click="showMoreCondition = !showMoreCondition">{{showMoreCondition ? '收起条件' : '展开条件'}}</el-button> --> | |||
| </el-form-item> | |||
| </el-form> | |||
| <!-- <el-row :gutter="10" class="mb8"> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="primary" | |||
| plain | |||
| icon="el-icon-plus" | |||
| size="mini" | |||
| @click="handleAdd" | |||
| v-hasPermi="['model:appletOrderDateFrequency:add']" | |||
| >新增</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="success" | |||
| plain | |||
| icon="el-icon-edit" | |||
| size="mini" | |||
| :disabled="single" | |||
| @click="handleUpdate" | |||
| v-hasPermi="['model:appletOrderDateFrequency:edit']" | |||
| >修改</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="danger" | |||
| plain | |||
| icon="el-icon-delete" | |||
| size="mini" | |||
| :disabled="multiple" | |||
| @click="handleDelete" | |||
| v-hasPermi="['model:appletOrderDateFrequency:remove']" | |||
| >删除</el-button> | |||
| </el-col> | |||
| <el-col :span="1.5"> | |||
| <el-button | |||
| type="warning" | |||
| plain | |||
| icon="el-icon-download" | |||
| size="mini" | |||
| :loading="exportLoading" | |||
| @click="handleExport" | |||
| v-hasPermi="['model:appletOrderDateFrequency:export']" | |||
| >导出</el-button> | |||
| </el-col> | |||
| <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar> | |||
| </el-row> --> | |||
| <el-table v-loading="loading" :data="appletOrderDateFrequencyList" @selection-change="handleSelectionChange"> | |||
| <el-table-column type="selection" width="55" align="center" /> | |||
| <el-table-column label="编号" align="center" prop="id" width="100px"/> | |||
| <el-table-column label="订单ID" align="center" prop="orderId" v-if="columns[0].visible" width="120px"/> | |||
| <el-table-column label="服务日期" align="center" prop="serviceDate" v-if="columns[1].visible" width="100px"/> | |||
| <!-- <el-table-column label="省份" align="center" prop="receiverProvince" v-if="columns[2].visible"/> --> | |||
| <el-table-column label="城市" align="center" prop="receiverCity" v-if="columns[3].visible"> | |||
| <template slot-scope="scope"> | |||
| {{ scope.row.receiverProvince }}{{ scope.row.receiverCity }}{{ scope.row.receiverDistrict }} | |||
| </template> | |||
| </el-table-column> | |||
| <!-- <el-table-column label="区县" align="center" prop="receiverDistrict" v-if="columns[4].visible"/> --> | |||
| <el-table-column label="接单伴宠师" align="center" prop="masterId" v-if="columns[5].visible" width="180px"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex; align-items: center; justify-content: center;"> | |||
| <!-- 左侧头像 --> | |||
| <div style="margin-right: 10px;"> | |||
| <el-avatar :size="40" :src="scope.row.master.userImage" icon="el-icon-user-solid" | |||
| style="background-color: #409EFF;"> | |||
| </el-avatar> | |||
| </div> | |||
| <!-- 右侧信息:上下布局 --> | |||
| <div style="display: flex; flex-direction: column; align-items: flex-start;"> | |||
| <div style="font-weight: bold; margin-bottom: 2px;"> | |||
| {{ scope.row.master.userName || '未分配' }} | |||
| </div> | |||
| <div style="font-size: 12px; color: #999;"> | |||
| ID: {{ scope.row.masterId || '--' }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="下单用户" align="center" prop="userId" v-if="columns[6].visible" width="140px"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex; align-items: center; justify-content: center;"> | |||
| <div style="display: flex; flex-direction: column; align-items: flex-start;"> | |||
| <div style="font-weight: bold; margin-bottom: 2px;"> | |||
| {{ scope.row.user.nickname || '未分配' }} | |||
| </div> | |||
| <div style="font-size: 12px; color: #999;"> | |||
| ID: {{ scope.row.userId || '--' }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="宠物" align="center" prop="status" v-if="columns[7].visible"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex; align-items: center; justify-content: center;" | |||
| v-for="(pet, index) in scope.row.pets" | |||
| :key="index"> | |||
| <!-- 左侧头像 --> | |||
| <div style="margin-right: 10px;"> | |||
| <el-avatar :size="40" :src="pet.photo" icon="el-icon-user-solid" | |||
| style="background-color: #409EFF;"> | |||
| </el-avatar> | |||
| </div> | |||
| <!-- 右侧信息:上下布局 --> | |||
| <div style="display: flex; flex-direction: column; align-items: flex-start;"> | |||
| <div style="margin-bottom: 2px;"> | |||
| {{ pet.name }} | {{ pet.breed }} | {{ pet.bodyType }} | |||
| </div> | |||
| <div style="font-size: 12px; color: #999;"> | |||
| {{ pet.orderItemList.map(n => n.productName).join(',') }} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="完成状态" align="center" prop="status" v-if="columns[7].visible" width="100px"> | |||
| <template slot-scope="scope"> | |||
| <dict-tag :options="dict.type.order_check_status" :value="scope.row.status" /> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="完成时间" align="center" prop="completionTime" v-if="columns[8].visible" width="130px"/> | |||
| <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120px"> | |||
| <template slot-scope="scope"> | |||
| <!-- <el-button | |||
| size="mini" | |||
| type="text" | |||
| icon="el-icon-edit" | |||
| @click="handleUpdate(scope.row)" | |||
| v-hasPermi="['model:appletOrderDateFrequency:edit']" | |||
| >修改</el-button> | |||
| <el-button | |||
| size="mini" | |||
| type="text" | |||
| icon="el-icon-delete" | |||
| @click="handleDelete(scope.row)" | |||
| v-hasPermi="['model:appletOrderDateFrequency:remove']" | |||
| >删除</el-button> --> | |||
| <el-button size="mini" type="text" icon="el-icon-full-screen" | |||
| @click="handleCheckin(scope.row)">打卡信息</el-button> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" | |||
| @pagination="getList" /> | |||
| <!-- 添加或修改日订单对话框 --> | |||
| <el-dialog :title="title" :visible.sync="open" width="50%" append-to-body> | |||
| <el-form ref="form" :model="form" :rules="rules" label-width="108px" inline class="dialog-form-two"> | |||
| <el-form-item label="下单端订单ID" prop="orderId"> | |||
| <el-input v-model="form.orderId" placeholder="请输入下单端订单ID" /> | |||
| </el-form-item> | |||
| <el-form-item label="服务日期" prop="serviceDate"> | |||
| <el-input v-model="form.serviceDate" placeholder="请输入服务日期" /> | |||
| </el-form-item> | |||
| <el-form-item label="省份" prop="receiverProvince"> | |||
| <el-input v-model="form.receiverProvince" placeholder="请输入省份" /> | |||
| </el-form-item> | |||
| <el-form-item label="城市" prop="receiverCity"> | |||
| <el-input v-model="form.receiverCity" placeholder="请输入城市" /> | |||
| </el-form-item> | |||
| <el-form-item label="区县" prop="receiverDistrict"> | |||
| <el-input v-model="form.receiverDistrict" placeholder="请输入区县" /> | |||
| </el-form-item> | |||
| <el-form-item label="伴宠师" prop="masterId"> | |||
| <el-input v-model="form.masterId" placeholder="请输入伴宠师" /> | |||
| </el-form-item> | |||
| <el-form-item label="下单用户" prop="userId"> | |||
| <el-input v-model="form.userId" placeholder="请输入下单用户" /> | |||
| </el-form-item> | |||
| <el-form-item label="完成状态"> | |||
| <el-radio-group v-model="form.status"> | |||
| <el-radio v-for="dict in dict.type.order_check_status" :key="dict.value" | |||
| :label="parseInt(dict.value)">{{ dict.label }}</el-radio> | |||
| </el-radio-group> | |||
| </el-form-item> | |||
| </el-form> | |||
| <div slot="footer" class="dialog-footer"> | |||
| <el-button type="primary" @click="submitForm">确 定</el-button> | |||
| <el-button @click="cancel">取 消</el-button> | |||
| </div> | |||
| </el-dialog> | |||
| <!-- 打卡弹窗 --> | |||
| <checkin-dialog | |||
| v-model="checkinDialogVisible" | |||
| :order-data="currentOrderData"> | |||
| </checkin-dialog> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { listAppletOrderDateFrequency, | |||
| getAppletOrderDateFrequencyCheck, | |||
| getAppletOrderDateFrequency, delAppletOrderDateFrequency, addAppletOrderDateFrequency, updateAppletOrderDateFrequency, exportAppletOrderDateFrequency } from "@/api/model/appletOrderDateFrequency"; | |||
| import CheckinDialog from "@/components/CheckinDialog.vue"; | |||
| export default { | |||
| name: "AppletOrderDateFrequency", | |||
| dicts: ['order_check_status'], | |||
| components: { | |||
| CheckinDialog | |||
| }, | |||
| data() { | |||
| return { | |||
| // 遮罩层 | |||
| loading: true, | |||
| // 导出遮罩层 | |||
| exportLoading: false, | |||
| // 选中数组 | |||
| ids: [], | |||
| // 非单个禁用 | |||
| single: true, | |||
| // 非多个禁用 | |||
| multiple: true, | |||
| // 显示搜索条件 | |||
| showSearch: true, | |||
| // 总条数 | |||
| total: 0, | |||
| // 日订单表格数据 | |||
| appletOrderDateFrequencyList: [], | |||
| // 弹出层标题 | |||
| title: "", | |||
| // 是否显示弹出层 | |||
| open: false, | |||
| // 打卡弹窗显示状态 | |||
| checkinDialogVisible: false, | |||
| // 当前选中的订单数据 | |||
| currentOrderData: {}, | |||
| // 查询参数 | |||
| queryParams: { | |||
| pageNum: 1, | |||
| pageSize: 10, | |||
| orderId: null, | |||
| serviceDate: null, | |||
| receiverProvince: null, | |||
| receiverCity: null, | |||
| receiverDistrict: null, | |||
| masterId: null, | |||
| userId: null, | |||
| status: null, | |||
| }, | |||
| // 表单参数 | |||
| form: {}, | |||
| // 表单校验 | |||
| rules: { | |||
| orderId: [ | |||
| { required: true, message: "下单端订单ID不能为空", trigger: "blur" } | |||
| ], | |||
| serviceDate: [ | |||
| { required: true, message: "服务日期不能为空", trigger: "blur" } | |||
| ], | |||
| }, | |||
| columns: [ | |||
| { key: 1, label: "下单端订单ID", visible: true }, | |||
| { key: 2, label: "服务日期", visible: true }, | |||
| { key: 5, label: "省份", visible: true }, | |||
| { key: 6, label: "城市", visible: true }, | |||
| { key: 7, label: "区县", visible: true }, | |||
| { key: 9, label: "伴宠师", visible: true }, | |||
| { key: 10, label: "下单用户", visible: true }, | |||
| { key: 11, label: "完成状态", visible: true }, | |||
| { key: 12, label: "完成时间", visible: true }, | |||
| { key: 13, label: "宠物信息", visible: true }, | |||
| ], | |||
| showMoreCondition: false | |||
| }; | |||
| }, | |||
| created() { | |||
| this.getList(); | |||
| }, | |||
| methods: { | |||
| /** 查询日订单列表 */ | |||
| getList() { | |||
| this.loading = true; | |||
| listAppletOrderDateFrequency(this.queryParams).then(response => { | |||
| this.appletOrderDateFrequencyList = response.rows; | |||
| this.total = response.total; | |||
| this.loading = false; | |||
| }); | |||
| }, | |||
| // 取消按钮 | |||
| cancel() { | |||
| this.open = false; | |||
| this.reset(); | |||
| }, | |||
| // 表单重置 | |||
| reset() { | |||
| this.form = { | |||
| id: null, | |||
| orderId: null, | |||
| serviceDate: null, | |||
| serviceExpected: null, | |||
| petId: null, | |||
| receiverProvince: null, | |||
| receiverCity: null, | |||
| receiverDistrict: null, | |||
| receiverDetailAddress: null, | |||
| masterId: null, | |||
| userId: null, | |||
| status: 0, | |||
| completionTime: null, | |||
| createBy: null, | |||
| createTime: null, | |||
| updateBy: null, | |||
| updateTime: null | |||
| }; | |||
| this.resetForm("form"); | |||
| }, | |||
| /** 搜索按钮操作 */ | |||
| handleQuery() { | |||
| this.queryParams.pageNum = 1; | |||
| this.getList(); | |||
| }, | |||
| /** 重置按钮操作 */ | |||
| resetQuery() { | |||
| this.resetForm("queryForm"); | |||
| this.handleQuery(); | |||
| }, | |||
| // 多选框选中数据 | |||
| handleSelectionChange(selection) { | |||
| this.ids = selection.map(item => item.id) | |||
| this.single = selection.length !== 1 | |||
| this.multiple = !selection.length | |||
| }, | |||
| /** 新增按钮操作 */ | |||
| handleAdd() { | |||
| this.reset(); | |||
| this.open = true; | |||
| this.title = "添加日订单"; | |||
| }, | |||
| /** 修改按钮操作 */ | |||
| handleUpdate(row) { | |||
| this.reset(); | |||
| const id = row.id || this.ids | |||
| getAppletOrderDateFrequency(id).then(response => { | |||
| this.form = response.data; | |||
| this.open = true; | |||
| this.title = "修改日订单"; | |||
| }); | |||
| }, | |||
| /** 提交按钮 */ | |||
| submitForm() { | |||
| this.$refs["form"].validate(valid => { | |||
| if (valid) { | |||
| if (this.form.id != null) { | |||
| updateAppletOrderDateFrequency(this.form).then(response => { | |||
| this.$modal.msgSuccess("修改成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }); | |||
| } else { | |||
| addAppletOrderDateFrequency(this.form).then(response => { | |||
| this.$modal.msgSuccess("新增成功"); | |||
| this.open = false; | |||
| this.getList(); | |||
| }); | |||
| } | |||
| } | |||
| }); | |||
| }, | |||
| /** 删除按钮操作 */ | |||
| handleDelete(row) { | |||
| const ids = row.id || this.ids; | |||
| this.$modal.confirm('是否确认删除日订单编号为"' + ids + '"的数据项?').then(function () { | |||
| return delAppletOrderDateFrequency(ids); | |||
| }).then(() => { | |||
| this.getList(); | |||
| this.$modal.msgSuccess("删除成功"); | |||
| }).catch(() => { }); | |||
| }, | |||
| /** 导出按钮操作 */ | |||
| handleExport() { | |||
| const queryParams = this.queryParams; | |||
| this.$modal.confirm('是否确认导出所有日订单数据项?').then(() => { | |||
| this.exportLoading = true; | |||
| return exportAppletOrderDateFrequency(queryParams); | |||
| }).then(response => { | |||
| this.download(response.msg); | |||
| this.exportLoading = false; | |||
| }).catch(() => { }); | |||
| }, | |||
| handleCheckin(row) { | |||
| this.currentOrderData = row; | |||
| this.checkinDialogVisible = true; | |||
| } | |||
| } | |||
| }; | |||
| </script> | |||
| @ -0,0 +1,99 @@ | |||
| package com.ruoyi.web.core.config; | |||
| import com.cyl.manager.staff.domain.Staff; | |||
| import com.cyl.manager.staff.service.IStaffService; | |||
| import com.cyl.manager.ums.domain.Member; | |||
| import com.cyl.manager.ums.service.MemberService; | |||
| import com.cyl.manager.ums.service.MemberWechatService; | |||
| import com.ruoyi.common.constant.Constants; | |||
| import com.ruoyi.common.constant.HttpStatus; | |||
| import com.ruoyi.common.core.domain.model.LoginMember; | |||
| import com.ruoyi.common.exception.ServiceException; | |||
| import com.ruoyi.framework.config.LocalDataUtil; | |||
| import com.ruoyi.framework.web.service.TokenService; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| //@Configuration | |||
| public class AppletTechnicianInterceptor extends HandlerInterceptorAdapter { | |||
| @Autowired | |||
| private TokenService tokenService; | |||
| @Autowired | |||
| private MemberService memberService; | |||
| @Autowired | |||
| private MemberWechatService memberWechatService; | |||
| @Autowired | |||
| private IStaffService iStaffService; | |||
| private static String[] WHITE_PATHS = { | |||
| "/h5/sms/login", | |||
| "/h5/wechat/login", | |||
| "/h5/account/login", | |||
| "/h5/register", | |||
| "/h5/validate", | |||
| "/h5/staff", | |||
| "/h5/order/listByOpenid", | |||
| "/h5/system", | |||
| "/h5/oss/upload", | |||
| "/h5/companion/staff/getTrainAnswerRecord", | |||
| }; | |||
| @Override | |||
| public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |||
| String requestUri = request.getRequestURI(); | |||
| boolean flag = true; | |||
| if (requestUri.startsWith("/h5/")) { | |||
| return super.preHandle(request, response, handler); | |||
| } | |||
| if (!requestUri.startsWith("/applet/")) { | |||
| return super.preHandle(request, response, handler); | |||
| } | |||
| for (String s : WHITE_PATHS) { | |||
| if (requestUri.startsWith(s)) { | |||
| flag = false; | |||
| break; | |||
| } | |||
| } | |||
| if (!flag) { | |||
| return super.preHandle(request, response, handler); | |||
| } | |||
| LoginMember loginMember = tokenService.getLoginMember(request); | |||
| if (loginMember == null) { | |||
| throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); | |||
| } | |||
| tokenService.verifyMemberToken(loginMember); | |||
| if (new Integer(1).equals(loginMember.getSourceType())) { | |||
| //伴宠师 | |||
| Staff staff = iStaffService.getById(loginMember.getMemberId()); | |||
| if (staff == null) { | |||
| throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); | |||
| } | |||
| //将员工信息存放至全局 | |||
| LocalDataUtil.setVar(Constants.STAFF_INFO, staff); | |||
| }else { | |||
| //获取会员信息 | |||
| Member member = memberService.selectById(loginMember.getMemberId()); | |||
| if (member == null || member.getStatus() == 0) { | |||
| throw new ServiceException("获取用户ID异常", HttpStatus.UNAUTHORIZED); | |||
| } | |||
| //将会员信息存放至全局 | |||
| LocalDataUtil.setVar(Constants.MEMBER_INFO, member); | |||
| } | |||
| return super.preHandle(request, response, handler); | |||
| } | |||
| } | |||
| @ -0,0 +1,87 @@ | |||
| package com.ruoyi.applet.contoller; | |||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
| import com.cyl.h5.config.SecurityUtil; | |||
| import com.cyl.manager.oms.domain.OrderItem; | |||
| import com.cyl.manager.oms.mapper.OrderItemMapper; | |||
| import com.cyl.manager.ums.domain.Member; | |||
| import com.ruoyi.common.core.controller.BaseController; | |||
| import com.ruoyi.common.core.domain.AjaxResult; | |||
| import com.ruoyi.common.core.page.TableDataInfo; | |||
| import com.ruoyi.model.domain.AppletOrderDateFrequency; | |||
| import com.ruoyi.model.domain.AppletOrderItemDateLog; | |||
| import com.ruoyi.model.service.IAppletOrderDateFrequencyService; | |||
| import com.ruoyi.model.service.IAppletOrderItemDateLogService; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.*; | |||
| import java.util.stream.Collectors; | |||
| /** | |||
| * 新版本小程序日订单Controller | |||
| * | |||
| * @author daixiande | |||
| * @date 2025-05-28 | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/applet/appletOrderDateFrequency") | |||
| public class AppletOrderDateFrequencyAppletController extends BaseController { | |||
| @Autowired | |||
| private IAppletOrderDateFrequencyService appletOrderDateFrequencyService; | |||
| @Autowired | |||
| private IAppletOrderItemDateLogService appletOrderItemDateLogService; | |||
| /** | |||
| * 查询日订单列表 | |||
| */ | |||
| @GetMapping("/list") | |||
| public AjaxResult list(AppletOrderDateFrequency frequency) { | |||
| List<AppletOrderDateFrequency> list = appletOrderDateFrequencyService.selectAppletOrderDateFrequencyList(frequency); | |||
| // 按日期分组 | |||
| SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); | |||
| Map<String, List<AppletOrderDateFrequency>> groupedByDate = list.stream() | |||
| .collect(Collectors.groupingBy(item -> formatter.format(item.getServiceDate()))); | |||
| // 转换为目标格式,按日期排序 | |||
| List<Map<String, Object>> result = new ArrayList<>(); | |||
| groupedByDate.entrySet().stream() | |||
| .sorted(Map.Entry.comparingByKey()) | |||
| .forEach(entry -> { | |||
| Map<String, Object> group = new HashMap<>(); | |||
| group.put("date", entry.getKey()); | |||
| group.put("list", entry.getValue()); | |||
| result.add(group); | |||
| }); | |||
| return success(result); | |||
| } | |||
| /** | |||
| * 获取日订单详细信息 | |||
| */ | |||
| @GetMapping(value = "/{id}") | |||
| public AjaxResult getInfo(@PathVariable("id") Long id) { | |||
| AppletOrderDateFrequency frequency = appletOrderDateFrequencyService.selectAppletOrderDateFrequencyById(id); | |||
| AppletOrderItemDateLog check = appletOrderItemDateLogService.selectAppletOrderItemDateLogByItemDateId(id); | |||
| HashMap<String, Object> map = new HashMap<>(); | |||
| map.put("frequency", frequency); | |||
| map.put("check", check); | |||
| return AjaxResult.success(map); | |||
| } | |||
| /** | |||
| * 获取日订单详细信息 | |||
| */ | |||
| @PostMapping(value = "/check") | |||
| public AjaxResult check(@RequestBody AppletOrderItemDateLog log) { | |||
| return AjaxResult.success(appletOrderDateFrequencyService.check(log)); | |||
| } | |||
| } | |||
| @ -0,0 +1,114 @@ | |||
| package com.ruoyi.model.controller; | |||
| import java.util.List; | |||
| import com.ruoyi.model.domain.AppletOrderItemDateLog; | |||
| import com.ruoyi.model.service.IAppletOrderItemDateLogService; | |||
| import org.springframework.security.access.prepost.PreAuthorize; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.PutMapping; | |||
| import org.springframework.web.bind.annotation.DeleteMapping; | |||
| import org.springframework.web.bind.annotation.PathVariable; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import com.ruoyi.common.annotation.Log; | |||
| import com.ruoyi.common.core.controller.BaseController; | |||
| import com.ruoyi.common.core.domain.AjaxResult; | |||
| import com.ruoyi.common.enums.BusinessType; | |||
| import com.ruoyi.model.domain.AppletOrderDateFrequency; | |||
| import com.ruoyi.model.service.IAppletOrderDateFrequencyService; | |||
| import com.ruoyi.common.utils.poi.ExcelUtil; | |||
| import com.ruoyi.common.core.page.TableDataInfo; | |||
| /** | |||
| * 日订单Controller | |||
| * | |||
| * @author daixiande | |||
| * @date 2025-05-28 | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/model/appletOrderDateFrequency") | |||
| public class AppletOrderDateFrequencyController extends BaseController { | |||
| @Autowired | |||
| private IAppletOrderDateFrequencyService appletOrderDateFrequencyService; | |||
| @Autowired | |||
| private IAppletOrderItemDateLogService appletOrderItemDateLogService; | |||
| /** | |||
| * 查询日订单列表 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:list')") | |||
| @GetMapping("/list") | |||
| public TableDataInfo list(AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| startPage(); | |||
| List<AppletOrderDateFrequency> list = appletOrderDateFrequencyService.selectAppletOrderDateFrequencyList(appletOrderDateFrequency); | |||
| list.forEach(appletOrderDateFrequencyService::buildUserData); | |||
| return getDataTable(list); | |||
| } | |||
| /** | |||
| * 导出日订单列表 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:export')") | |||
| @Log(title = "日订单", businessType = BusinessType.EXPORT) | |||
| @GetMapping("/export") | |||
| public AjaxResult export(AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| List<AppletOrderDateFrequency> list = appletOrderDateFrequencyService.selectAppletOrderDateFrequencyList(appletOrderDateFrequency); | |||
| ExcelUtil<AppletOrderDateFrequency> util = new ExcelUtil<AppletOrderDateFrequency>(AppletOrderDateFrequency.class); | |||
| return util.exportExcel(list, "日订单数据"); | |||
| } | |||
| /** | |||
| * 获取日订单详细信息 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:query')") | |||
| @GetMapping(value = "/{id}") | |||
| public AjaxResult getInfo(@PathVariable("id") Long id) { | |||
| return AjaxResult.success(appletOrderDateFrequencyService.selectAppletOrderDateFrequencyById(id)); | |||
| } | |||
| /** | |||
| * 获取日订单打卡详细信息 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:query')") | |||
| @GetMapping(value = "/check/{id}") | |||
| public AjaxResult getCheck(@PathVariable("id") Long id) { | |||
| AppletOrderItemDateLog check = appletOrderItemDateLogService.selectAppletOrderItemDateLogByItemDateId(id); | |||
| return AjaxResult.success(check); | |||
| } | |||
| /** | |||
| * 新增日订单 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:add')") | |||
| @Log(title = "日订单", businessType = BusinessType.INSERT) | |||
| @PostMapping | |||
| public AjaxResult add(@RequestBody AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| return toAjax(appletOrderDateFrequencyService.insertAppletOrderDateFrequency(appletOrderDateFrequency)); | |||
| } | |||
| /** | |||
| * 修改日订单 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:edit')") | |||
| @Log(title = "日订单", businessType = BusinessType.UPDATE) | |||
| @PutMapping | |||
| public AjaxResult edit(@RequestBody AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| return toAjax(appletOrderDateFrequencyService.updateAppletOrderDateFrequency(appletOrderDateFrequency)); | |||
| } | |||
| /** | |||
| * 删除日订单 | |||
| */ | |||
| @PreAuthorize("@ss.hasPermi('model:appletOrderDateFrequency:remove')") | |||
| @Log(title = "日订单", businessType = BusinessType.DELETE) | |||
| @DeleteMapping("/{ids}") | |||
| public AjaxResult remove(@PathVariable Long[] ids) { | |||
| return toAjax(appletOrderDateFrequencyService.deleteAppletOrderDateFrequencyByIds(ids)); | |||
| } | |||
| } | |||
| @ -0,0 +1,107 @@ | |||
| package com.ruoyi.model.domain; | |||
| import com.baomidou.mybatisplus.annotation.TableField; | |||
| import com.cyl.manager.ums.domain.Member; | |||
| import com.cyl.manager.ums.domain.Pet; | |||
| import com.fasterxml.jackson.annotation.JsonFormat; | |||
| import com.ruoyi.common.annotation.Excel; | |||
| import lombok.AllArgsConstructor; | |||
| import lombok.Builder; | |||
| import lombok.Data; | |||
| import lombok.NoArgsConstructor; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| /** | |||
| * 日订单对象 applet_order_date_frequency | |||
| * | |||
| * @author daixiande | |||
| */ | |||
| @Data | |||
| @Builder | |||
| @AllArgsConstructor | |||
| @NoArgsConstructor | |||
| public class AppletOrderDateFrequency { | |||
| private static final long serialVersionUID = 1L; | |||
| /** 编号 */ | |||
| private Long id; | |||
| /** 下单端订单ID */ | |||
| @Excel(name = "下单端订单ID") | |||
| private Long orderId; | |||
| /** 服务日期 */ | |||
| @Excel(name = "服务日期") | |||
| @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") | |||
| private Date serviceDate; | |||
| /** 期望上门时间 */ | |||
| private String serviceExpected; | |||
| /** 关联宠物直接用json保存他以及服务内容 */ | |||
| private String petId; | |||
| /** 省份 */ | |||
| @Excel(name = "省份") | |||
| private String receiverProvince; | |||
| /** 城市 */ | |||
| @Excel(name = "城市") | |||
| private String receiverCity; | |||
| /** 区县 */ | |||
| @Excel(name = "区县") | |||
| private String receiverDistrict; | |||
| /** 详细地址 */ | |||
| private String receiverDetailAddress; | |||
| /** 当日上门的第几次 */ | |||
| private Integer dayNumber; | |||
| /** 伴宠师 */ | |||
| @Excel(name = "伴宠师") | |||
| private Long masterId; | |||
| /** 下单用户 */ | |||
| @Excel(name = "下单用户") | |||
| private Long userId; | |||
| /** 完成状态 */ | |||
| @Excel(name = "完成状态") | |||
| private String status; | |||
| /** 完成时间 */ | |||
| @Excel(name = "完成时间") | |||
| @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8") | |||
| private Date completionTime; | |||
| /** 项目ids多个,号隔开 */ | |||
| private String projectIds; | |||
| /** 创建者 */ | |||
| private Long createBy; | |||
| /** 创建时间 */ | |||
| private String createTime; | |||
| /** 更新者 */ | |||
| private Long updateBy; | |||
| /** 更新时间 */ | |||
| private String updateTime; | |||
| @TableField(exist = false) | |||
| private List<Pet> pets; | |||
| // 伴宠师 | |||
| @TableField(exist = false) | |||
| private AppUsers master; | |||
| // 下单用户 | |||
| @TableField(exist = false) | |||
| private Member user; | |||
| } | |||
| @ -0,0 +1,14 @@ | |||
| package com.ruoyi.model.mapper; | |||
| import java.util.List; | |||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
| import com.ruoyi.model.domain.AppletOrderDateFrequency; | |||
| /** | |||
| * 日订单Mapper接口 | |||
| * | |||
| * @author daixiande | |||
| */ | |||
| public interface AppletOrderDateFrequencyMapper extends BaseMapper<AppletOrderDateFrequency> { | |||
| } | |||
| @ -0,0 +1,78 @@ | |||
| package com.ruoyi.model.service; | |||
| import java.util.List; | |||
| import com.baomidou.mybatisplus.extension.service.IService; | |||
| import com.cyl.h5.pojo.vo.H5OrderVO; | |||
| import com.ruoyi.model.domain.AppletOrderDateFrequency; | |||
| import com.ruoyi.model.domain.AppletOrderItemDateLog; | |||
| /** | |||
| * 日订单Service接口 | |||
| * | |||
| * @author daixiande | |||
| */ | |||
| public interface IAppletOrderDateFrequencyService extends IService<AppletOrderDateFrequency> { | |||
| /** | |||
| * 查询日订单 | |||
| * | |||
| * @param id 日订单主键 | |||
| * @return 日订单 | |||
| */ | |||
| AppletOrderDateFrequency selectAppletOrderDateFrequencyById(Long id); | |||
| /** | |||
| * 查询日订单列表 | |||
| * | |||
| * @param appletOrderDateFrequency 日订单 | |||
| * @return 日订单集合 | |||
| */ | |||
| List<AppletOrderDateFrequency> selectAppletOrderDateFrequencyList(AppletOrderDateFrequency appletOrderDateFrequency); | |||
| /** | |||
| * 新增日订单 | |||
| * | |||
| * @param appletOrderDateFrequency 日订单 | |||
| * @return 结果 | |||
| */ | |||
| int insertAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency); | |||
| /** | |||
| * 修改日订单 | |||
| * | |||
| * @param appletOrderDateFrequency 日订单 | |||
| * @return 结果 | |||
| */ | |||
| int updateAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency); | |||
| /** | |||
| * 批量删除日订单 | |||
| * | |||
| * @param ids 需要删除的日订单主键集合 | |||
| * @return 结果 | |||
| */ | |||
| int deleteAppletOrderDateFrequencyByIds(Long[] ids); | |||
| void buildPetData(AppletOrderDateFrequency frequency); | |||
| /** | |||
| * 删除日订单信息 | |||
| * | |||
| * @param id 日订单主键 | |||
| * @return 结果 | |||
| */ | |||
| int deleteAppletOrderDateFrequencyById(Long id); | |||
| /** | |||
| * 接单生成日订单 | |||
| * @param h5OrderVO 下单端订单信息 | |||
| * @param masterId 伴宠师ID | |||
| */ | |||
| void aceptOrdersGenerateDayOrdersByOrderVO(H5OrderVO h5OrderVO, Long masterId); | |||
| void buildUserData(AppletOrderDateFrequency frequency); | |||
| int check(AppletOrderItemDateLog log); | |||
| } | |||
| @ -0,0 +1,382 @@ | |||
| package com.ruoyi.model.service.impl; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.time.LocalDateTime; | |||
| import java.util.*; | |||
| import java.util.stream.Collectors; | |||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
| import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; | |||
| import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
| import com.cyl.h5.pojo.vo.H5OrderVO; | |||
| import com.cyl.h5.service.H5MemberService; | |||
| import com.cyl.manager.oms.domain.OmsOrderService; | |||
| import com.cyl.manager.oms.domain.OrderItem; | |||
| import com.cyl.manager.oms.mapper.OmsOrderServiceMapper; | |||
| import com.cyl.manager.oms.mapper.OrderItemMapper; | |||
| import com.cyl.manager.oms.service.OmsOrderServiceService; | |||
| import com.cyl.manager.ums.domain.Pet; | |||
| import com.cyl.manager.ums.mapper.PetMapper; | |||
| import com.cyl.manager.ums.service.MemberService; | |||
| import com.cyl.manager.ums.service.PetService; | |||
| import com.ruoyi.model.domain.*; | |||
| import com.ruoyi.model.mapper.AppletOrderItemMapper; | |||
| import com.ruoyi.model.service.*; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Service; | |||
| import com.ruoyi.model.mapper.AppletOrderDateFrequencyMapper; | |||
| import org.springframework.transaction.annotation.Transactional; | |||
| import static org.apache.ibatis.ognl.OgnlOps.in; | |||
| /** | |||
| * 日订单Service业务层处理 | |||
| * | |||
| * @author daixiande | |||
| */ | |||
| @Service | |||
| public class AppletOrderDateFrequencyServiceImpl extends ServiceImpl<AppletOrderDateFrequencyMapper, AppletOrderDateFrequency> implements IAppletOrderDateFrequencyService { | |||
| @Autowired | |||
| private AppletOrderDateFrequencyMapper appletOrderDateFrequencyMapper; | |||
| @Autowired | |||
| private PetMapper petMapper; | |||
| @Autowired | |||
| private OrderItemMapper orderItemMapper; | |||
| @Autowired | |||
| private OmsOrderServiceMapper omsOrderServiceMapper; | |||
| @Autowired | |||
| private IAppUsersService appUsersService; | |||
| @Autowired | |||
| private MemberService memberService; | |||
| @Autowired | |||
| private IAppletOrderItemDateLogService appletOrderItemDateLogService; | |||
| @Autowired | |||
| private AppletOrderItemMapper appletOrderItemMapper; | |||
| @Autowired | |||
| private IAppletAmountLogService appletAmountLogService; | |||
| /** | |||
| * 查询日订单 | |||
| * | |||
| * @param id 日订单主键 | |||
| * @return 日订单 | |||
| */ | |||
| @Override | |||
| public AppletOrderDateFrequency selectAppletOrderDateFrequencyById(Long id) { | |||
| AppletOrderDateFrequency appletOrderDateFrequency = appletOrderDateFrequencyMapper.selectById(id); | |||
| buildPetData(appletOrderDateFrequency); | |||
| return appletOrderDateFrequency; | |||
| } | |||
| /** | |||
| * 查询日订单列表 | |||
| * | |||
| * @param frequency 日订单 | |||
| * @return 日订单 | |||
| */ | |||
| @Override | |||
| public List<AppletOrderDateFrequency> selectAppletOrderDateFrequencyList(AppletOrderDateFrequency frequency) { | |||
| LambdaQueryChainWrapper<AppletOrderDateFrequency> qw = lambdaQuery() | |||
| .eq(frequency.getOrderId() != null, AppletOrderDateFrequency::getOrderId, frequency.getOrderId()) | |||
| .eq(frequency.getMasterId() != null, AppletOrderDateFrequency::getMasterId, frequency.getMasterId()) | |||
| .orderByAsc(AppletOrderDateFrequency::getServiceDate); | |||
| if (frequency.getStatus() != null){ | |||
| qw.in(AppletOrderDateFrequency::getStatus, | |||
| Arrays.asList(frequency.getStatus().split(","))); | |||
| } | |||
| List<AppletOrderDateFrequency> list = qw.list(); | |||
| list.forEach(this::buildPetData); | |||
| return list; | |||
| } | |||
| @Override | |||
| public void buildPetData(AppletOrderDateFrequency frequency){ | |||
| SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); | |||
| String[] split = frequency.getPetId().split(","); | |||
| List<Pet> pets = petMapper.selectList(Wrappers.<Pet>lambdaQuery() | |||
| .in(Pet::getId, split)); | |||
| frequency.setPets(pets); | |||
| if(frequency.getProjectIds() == null){ | |||
| return; | |||
| } | |||
| pets.forEach(pet -> { | |||
| LambdaQueryWrapper<OmsOrderService> omsOrderServiceQW = Wrappers.<OmsOrderService>lambdaQuery() | |||
| .eq(OmsOrderService::getPetId, pet.getId()) | |||
| .eq(OmsOrderService::getOrderId, frequency.getOrderId()) | |||
| .eq(OmsOrderService::getServiceDate, formatter.format(frequency.getServiceDate())) | |||
| .select(OmsOrderService::getId); | |||
| List<Long> omsOrderServiceIds = omsOrderServiceMapper.selectList(omsOrderServiceQW).stream().map(n -> n.getId()) | |||
| .collect(Collectors.toList()); | |||
| LambdaQueryWrapper<OrderItem> qw = Wrappers.<OrderItem>lambdaQuery() | |||
| .in(OrderItem::getOrderServiceId, omsOrderServiceIds) | |||
| .in(OrderItem::getId, Arrays.asList(frequency.getProjectIds().split(","))); | |||
| List<OrderItem> orderItemList = orderItemMapper.selectList(qw); | |||
| pet.setOrderItemList(orderItemList); | |||
| }); | |||
| } | |||
| /** | |||
| * 新增日订单 | |||
| * | |||
| * @param appletOrderDateFrequency 日订单 | |||
| * @return 结果 | |||
| */ | |||
| @Override | |||
| public int insertAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| return appletOrderDateFrequencyMapper.insert(appletOrderDateFrequency); | |||
| } | |||
| /** | |||
| * 修改日订单 | |||
| * | |||
| * @param appletOrderDateFrequency 日订单 | |||
| * @return 结果 | |||
| */ | |||
| @Override | |||
| public int updateAppletOrderDateFrequency(AppletOrderDateFrequency appletOrderDateFrequency) { | |||
| return appletOrderDateFrequencyMapper.updateById(appletOrderDateFrequency); | |||
| } | |||
| /** | |||
| * 批量删除日订单 | |||
| * | |||
| * @param ids 需要删除的日订单主键 | |||
| * @return 结果 | |||
| */ | |||
| @Override | |||
| public int deleteAppletOrderDateFrequencyByIds(Long[] ids) { | |||
| return appletOrderDateFrequencyMapper.deleteBatchIds(Arrays.asList(ids)); | |||
| } | |||
| /** | |||
| * 删除日订单信息 | |||
| * | |||
| * @param id 日订单主键 | |||
| * @return 结果 | |||
| */ | |||
| @Override | |||
| public int deleteAppletOrderDateFrequencyById(Long id) { | |||
| return appletOrderDateFrequencyMapper.deleteById(id); | |||
| } | |||
| /** | |||
| * 接单生成日订单 | |||
| * 以下是新的日订单代码 | |||
| * @param masterId 伴宠师ID | |||
| */ | |||
| @Override | |||
| public void aceptOrdersGenerateDayOrdersByOrderVO(H5OrderVO h5OrderVO, Long masterId) { | |||
| //生成按照次数完成打卡的日订单 | |||
| ArrayList<AppletOrderDateFrequency> frequencies = new ArrayList<>(); | |||
| //提取去重的日期列表。避免重复添加 | |||
| List<OmsOrderService> orderServiceSet = h5OrderVO.getOrderServiceList().stream() | |||
| .filter(service -> service.getServiceDate() != null) | |||
| .collect(Collectors.collectingAndThen( | |||
| Collectors.toCollection(() -> | |||
| new TreeSet<>(Comparator.comparing(OmsOrderService::getServiceDate))), | |||
| ArrayList::new)); | |||
| SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); | |||
| for (OmsOrderService service : orderServiceSet) { | |||
| // 当前订单生成数 | |||
| int index = 0; | |||
| // 订单最大生成数 | |||
| int maxIndex = 3; | |||
| //找出符合当前日期时间的服务列表 | |||
| List<OmsOrderService> serviceList = h5OrderVO.getOrderServiceList().stream(). | |||
| filter(n -> n.getServiceDate().equals(service.getServiceDate())) | |||
| .map(n -> { | |||
| n.setOrderItems(new ArrayList<>()); | |||
| return n; | |||
| }) | |||
| .collect(Collectors.toList()); | |||
| //取出当前日期所对应的项目 | |||
| List<OrderItem> orderItemList = h5OrderVO.getOrderItemList().stream(). | |||
| filter(n -> { | |||
| for (OmsOrderService omsOrderService : serviceList) { | |||
| if(n.getOrderServiceId().equals(omsOrderService.getId())){ | |||
| omsOrderService.getOrderItems().add(n); | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| }).collect(Collectors.toList()); | |||
| // 找出最大次数,生成对应个数的日订单 | |||
| for (OrderItem orderItem : orderItemList) { | |||
| maxIndex = Math.max(maxIndex, orderItem.getQuantity()); | |||
| } | |||
| // 根据次数生成 | |||
| while (index < maxIndex){ | |||
| //当前次数对应的项目 | |||
| HashSet<Long> projectIds = new HashSet<>(); | |||
| //当前次数对应的宠物 | |||
| HashSet<Integer> petIds = new HashSet<>(); | |||
| for (OmsOrderService omsOrderService : serviceList) { | |||
| //找出最大次数,最大次数符合的才能添加宠物 | |||
| int oIndex = 0; | |||
| for (OrderItem orderItem : omsOrderService.getOrderItems()) { | |||
| oIndex = Math.max(oIndex, orderItem.getQuantity()); | |||
| //找出符合次数的项目 | |||
| if (orderItem.getQuantity() > index){ | |||
| projectIds.add(orderItem.getId()); | |||
| } | |||
| } | |||
| //最大次数符合当前次数内,添加宠物id | |||
| if (oIndex > index){ | |||
| petIds.add(omsOrderService.getPetId()); | |||
| } | |||
| } | |||
| //如果当前次数没有需要服务的宠物了,则直接跳过 | |||
| if (petIds.isEmpty()){ | |||
| break; | |||
| } | |||
| Date serviceDate; | |||
| try { | |||
| serviceDate = formatter.parse(service.getServiceDate()); | |||
| } catch (ParseException e) { | |||
| throw new RuntimeException("日期解析失败"); | |||
| } | |||
| frequencies.add(AppletOrderDateFrequency.builder() | |||
| .serviceDate(serviceDate) | |||
| .receiverCity(h5OrderVO.getReceiverCity()) | |||
| .receiverProvince(h5OrderVO.getReceiverProvince()) | |||
| .receiverDistrict(h5OrderVO.getReceiverDistrict()) | |||
| .receiverDetailAddress(h5OrderVO.getReceiverDetailAddress()) | |||
| .userId(h5OrderVO.getMemberId()) | |||
| .masterId(masterId) | |||
| .orderId(service.getOrderId()) | |||
| .dayNumber(index + 1) | |||
| .petId(String.join(",", petIds.stream() | |||
| .map(String::valueOf).collect(Collectors.toList()))) | |||
| .projectIds(String.join(",", projectIds.stream() | |||
| .map(String::valueOf).collect(Collectors.toList()))) | |||
| .build()); | |||
| index++; | |||
| } | |||
| } | |||
| saveBatch(frequencies); | |||
| } | |||
| @Override | |||
| public void buildUserData(AppletOrderDateFrequency frequency) { | |||
| frequency.setMaster(appUsersService.selectAppUsersByUserId(frequency.getMasterId())); | |||
| frequency.setUser(memberService.selectById(frequency.getUserId())); | |||
| } | |||
| @Override | |||
| @Transactional | |||
| public int check(AppletOrderItemDateLog log) { | |||
| AppletOrderDateFrequency byId = getById(log.getItemDateId()); | |||
| if(byId == null){ | |||
| throw new RuntimeException("无效日订单"); | |||
| } | |||
| byId.setStatus(String.valueOf(log.getSubmitFlag())); | |||
| if(log.getSubmitFlag() == 2){ | |||
| byId.setCompletionTime(new Date()); | |||
| } | |||
| updateById(byId); | |||
| log.setOrderId(byId.getOrderId()); | |||
| //当所有的日订单完成,就将订单状态修改完成 | |||
| Integer count = lambdaQuery() | |||
| .eq(AppletOrderDateFrequency::getOrderId, byId.getOrderId()) | |||
| .in(AppletOrderDateFrequency::getStatus, Arrays.asList("0,1".split(","))) | |||
| .count(); | |||
| //总订单 | |||
| AppletOrderItem appletOrderItem = appletOrderItemMapper | |||
| .selectAppletOrderItemByOrderIdUserId(byId.getOrderId(), byId.getMasterId()); | |||
| //订单完成 | |||
| if(count == 0){ | |||
| appletOrderItem.setOrderStatus(2); | |||
| appletOrderItemMapper.updateAppletOrderItem(appletOrderItem); | |||
| //根据订单中的用户id查询用户信息 | |||
| AppUsers user = appUsersService.selectAppUsersByUserId(appletOrderItem.getUserId()); | |||
| //增加伴宠师流水 | |||
| // 记录日志 | |||
| AppletAmountLog moneyLog = new AppletAmountLog(); | |||
| moneyLog.setUserId(user.getUserId()); | |||
| moneyLog.setTitle("伴宠师佣金"); | |||
| moneyLog.setAmount(appletOrderItem.getOrderGivePrice()); | |||
| moneyLog.setType(0); //收入 | |||
| moneyLog.setState(1); //到账 | |||
| moneyLog.setCreateTime(LocalDateTime.now()); | |||
| moneyLog.setMoneyType(1);//钱包类型 | |||
| int i = appletAmountLogService.insertAppletAmountLog(moneyLog); | |||
| user.setPrice(user.getPrice().add(appletOrderItem.getOrderGivePrice())); | |||
| appUsersService.updateAppUsers(user); | |||
| }else if (appletOrderItem.getOrderStatus() == 0){//修改成订单进行中 | |||
| appletOrderItem.setOrderStatus(1); | |||
| appletOrderItemMapper.updateAppletOrderItem(appletOrderItem); | |||
| } | |||
| if(log.getId() == null){ | |||
| return appletOrderItemDateLogService.insertAppletOrderItemDateLog(log); | |||
| }else { | |||
| return appletOrderItemDateLogService.updateAppletOrderItemDateLog(log); | |||
| } | |||
| } | |||
| } | |||