diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxUserLogController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxUserLogController.java index 0faf52b4a..cf4eb42d9 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxUserLogController.java +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxUserLogController.java @@ -7,6 +7,7 @@ import com.stdiet.common.core.domain.AjaxResult; import com.stdiet.common.core.page.TableDataInfo; import com.stdiet.common.enums.BusinessType; import com.stdiet.common.utils.StringUtils; +import com.stdiet.common.utils.oss.AliyunOSSUtils; import com.stdiet.common.utils.poi.ExcelUtil; import com.stdiet.custom.domain.SysWxUserInfo; import com.stdiet.custom.domain.SysWxUserLog; @@ -19,7 +20,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.util.List; +import java.time.LocalDate; +import java.util.*; /** * 微信用户记录Controller @@ -80,7 +82,6 @@ public class SysWxUserLogController extends BaseController { @GetMapping(value = "/{id}") public AjaxResult getInfo(@PathVariable("id") String id) { SysWxUserLog sysWxUserLog = sysWxUserLogService.selectSysWxUserLogById(id); - System.out.println(sysWxUserLog.getPhone()); return AjaxResult.success(sysWxUserLog); } @@ -149,4 +150,43 @@ public class SysWxUserLogController extends BaseController { int count = sysWxUserLogService.checkWxLogInfoCount(openid); return AjaxResult.success(count); } + + /** + * 获取微信用户记录详细信息 + */ + @PreAuthorize("@ss.hasPermi('custom:wxUserLog:query')") + @GetMapping(value = "/getPunchLogDetail/{id}") + public AjaxResult getPunchLogDetail(@PathVariable("id") String id) { + SysWxUserLog sysWxUserLog = null; + //根据ID查询 + SysWxUserLog param = new SysWxUserLog(); + param.setId(Long.parseLong(id)); + List<SysWxUserLog> sysWxUserLogList = sysWxUserLogService.selectSysWxUserLogList(param); + if(sysWxUserLogList != null && sysWxUserLogList.size() > 0){ + sysWxUserLog = sysWxUserLogList.get(0); + } + if(sysWxUserLog == null){ + return AjaxResult.error("打卡记录不存在"); + } + Map<String, List<String>> imageUrlMap = new HashMap<>(); + List<String> breakfastImagesUrlList = StringUtils.isNotEmpty(sysWxUserLog.getBreakfastImages()) ? Arrays.asList(sysWxUserLog.getBreakfastImages().split("\\|")) : new ArrayList<>(); + imageUrlMap.put("breakfastImages", breakfastImagesUrlList); + + List<String> lunchImagesUrlList = StringUtils.isNotEmpty(sysWxUserLog.getLunchImages()) ? Arrays.asList(sysWxUserLog.getLunchImages().split("\\|")) : new ArrayList<>(); + imageUrlMap.put("lunchImages", lunchImagesUrlList); + + List<String> dinnerImagesUrlList = StringUtils.isNotEmpty(sysWxUserLog.getDinnerImages()) ? Arrays.asList(sysWxUserLog.getDinnerImages().split("\\|")) : new ArrayList<>(); + imageUrlMap.put("dinnerImages", dinnerImagesUrlList); + + List<String> extraMealImagesUrlList = StringUtils.isNotEmpty(sysWxUserLog.getExtraMealImages()) ? Arrays.asList(sysWxUserLog.getExtraMealImages().split("\\|")) : new ArrayList<>(); + imageUrlMap.put("extraMealImages", extraMealImagesUrlList); + + List<String> bodyImagesUrlList = StringUtils.isNotEmpty(sysWxUserLog.getBodyImages()) ? Arrays.asList(sysWxUserLog.getBodyImages().split("\\|")) : new ArrayList<>(); + imageUrlMap.put("bodyImages", bodyImagesUrlList ); + + //生成预览链接 + Map<String,List<String>> downUrlList = AliyunOSSUtils.generatePresignedUrl(imageUrlMap); + sysWxUserLog.setImagesUrl(downUrlList); + return AjaxResult.success(sysWxUserLog); + } } \ No newline at end of file diff --git a/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java b/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java index 0a5b163b1..4e7ccdd53 100644 --- a/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java +++ b/stdiet-common/src/main/java/com/stdiet/common/utils/oss/AliyunOSSUtils.java @@ -16,10 +16,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.UUID; +import java.util.*; public class AliyunOSSUtils { @@ -274,6 +271,34 @@ public class AliyunOSSUtils { return downUrlList; } + /** + * + * @param fileUrlList + * @return + */ + public static Map<String, List<String>> generatePresignedUrl(Map<String, List<String>> fileUrlList){ + Map<String, List<String>> downUrlMap = new HashMap<>(); + + // 创建OSSClient实例。 + OSS ossClient = getOssClient(); + + Date expiration = new Date(System.currentTimeMillis() + expire); + + for (String key : fileUrlList.keySet()) { + List<String> urlList = fileUrlList.get(key); + List<String> downList = new ArrayList<>(); + for (String fileUrl : urlList) { + downList.add(ossClient.generatePresignedUrl(AliyunOSSConfig.Buckets, getObjectName(fileUrl), expiration).toString()); + } + downUrlMap.put(key, downList); + } + + // 关闭OSSClient。 + ossClient.shutdown(); + + return downUrlMap; + } + /** * 删除指定路径下的一个文件 * diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxUserLog.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxUserLog.java index 40c818cbd..9cb4ce4c8 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxUserLog.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxUserLog.java @@ -2,13 +2,13 @@ package com.stdiet.custom.domain; import java.math.BigDecimal; import java.util.Date; +import java.util.List; +import java.util.Map; + import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import com.stdiet.common.annotation.Excel; import com.stdiet.common.core.domain.BaseEntity; -import org.springframework.web.multipart.MultipartFile; /** * 微信用户记录对象 sys_wx_user_log @@ -119,4 +119,14 @@ public class SysWxUserLog extends BaseEntity /** 体型对比照 */ @Excel(name = "体型对比照") private String bodyImages; + + //售后营养师ID + private Long afterNutritionistId; + + //售后营养师 + @Excel(name = "售后营养师") + private String afterNutritionist; + + //图片预览路径 + private Map<String, List<String>> imagesUrl; } \ No newline at end of file diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysWxUserLogMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysWxUserLogMapper.xml index 50ee15f59..1ceef353a 100644 --- a/stdiet-custom/src/main/resources/mapper/custom/SysWxUserLogMapper.xml +++ b/stdiet-custom/src/main/resources/mapper/custom/SysWxUserLogMapper.xml @@ -37,6 +37,7 @@ <result property="customerName" column="customer_name"></result> <!-- 营养师 --> <result property="nutritionist" column="nutritionist"></result> + <result property="afterNutritionist" column="after_nutritionist"></result> </resultMap> <resultMap type="com.stdiet.custom.page.WxLogInfo" id="WxLogInfo"> @@ -72,12 +73,17 @@ <!-- 后台查询 --> <select id="selectSysWxUserLogList" parameterType="SysWxUserLog" resultMap="SysWxUserLogResult"> SELECT wxlog.id,wxinfo.appid,wxinfo.openid,wxinfo.avatar_url,wxinfo.phone,wxlog.weight,wxlog.log_time,wxlog.sleep_time, wxlog.wakeup_time,wxlog.defecation, wxlog.water, wxlog.insomnia,wxlog.sport,wxlog.diet,wxlog.remark, - sc.name as customer_name, su.nick_name as nutritionist + wxlog.emotion,wxlog.sly_eat_food,wxlog.constipation,wxlog.breakfast_images,wxlog.lunch_images,wxlog.dinner_images,wxlog.extra_meal_images,wxlog.body_images, + sc.name as customer_name, su.nick_name as nutritionist, su_atferSale.nick_name as after_nutritionist FROM sys_wx_user_log wxlog left join sys_wx_user_info wxinfo on wxinfo.openid = wxlog.openid left join sys_customer sc on sc.phone = wxinfo.phone and sc.del_flag = 0 left join sys_user su on su.user_id = sc.main_dietitian and su.del_flag = '0' + left join sys_user su_atferSale on su_atferSale.user_id = sc.after_dietitian and su_atferSale.del_flag = '0' where wxinfo.phone is not null + <if test="id != null"> + and wxlog.id = #{id} + </if> <if test="phone != null and phone != ''">and (sc.name like concat('%',#{phone},'%') or wxinfo.phone like concat('%',#{phone},'%') )</if> <if test="appid != null"> and wxinfo.appid = #{appid} @@ -85,6 +91,9 @@ <if test="nutritionistId != null"> and su.user_id = #{nutritionistId} </if> + <if test="afterNutritionistId != null"> + and su_atferSale.user_id = #{afterNutritionistId} + </if> order by wxlog.create_time desc </select> diff --git a/stdiet-ui/src/api/custom/wxUserLog.js b/stdiet-ui/src/api/custom/wxUserLog.js index 29a706b55..9ef6d2ecb 100644 --- a/stdiet-ui/src/api/custom/wxUserLog.js +++ b/stdiet-ui/src/api/custom/wxUserLog.js @@ -36,9 +36,9 @@ export function updateWxUserLog(data) { } // 删除微信用户记录 -export function delWxUserLog(openid) { +export function delWxUserLog(id) { return request({ - url: '/custom/wxUserLog/' + openid, + url: '/custom/wxUserLog/' + id, method: 'delete' }) } @@ -51,3 +51,12 @@ export function exportWxUserLog(query) { params: query }) } + +// 根据ID查询打卡日志详情 +export function getPunchLogDetail(id) { + return request({ + url: '/custom/wxUserLog/getPunchLogDetail/' + id, + method: 'get', + params: {} + }) +} diff --git a/stdiet-ui/src/components/PunchLog/PunchLogDetail/index.vue b/stdiet-ui/src/components/PunchLog/PunchLogDetail/index.vue new file mode 100644 index 000000000..e5e9203c6 --- /dev/null +++ b/stdiet-ui/src/components/PunchLog/PunchLogDetail/index.vue @@ -0,0 +1,186 @@ +<template> + <el-dialog + :visible.sync="visible" + :title="title" + append-to-body + @closed="onClosed" + width="1000px" + > + <div style="margin-top: -20px;"> + <div + style="float: right; " + + > + + <!--<el-button + type="primary" + plain + >评分</el-button + >--> + + + </div> + <!-- 打卡信息详情 --> + <div> + + <h3>一、基础信息</h3> + <TableDetailMessage :data="punchLogDetail"></TableDetailMessage> + <h3>二、图片信息</h3> + <div style="height: 400px; overflow: auto"> + <div> + <h4>早餐</h4> + <div> + <el-image v-for="(item, index) in punchLog.imagesUrl.breakfastImages" title="点击大图预览" :key="index" + style="width: 300px; height: 380px" + :src="item" + :preview-src-list="imageUrl"> + </el-image> + </div> + </div> + <div> + <h4>午餐</h4> + <div> + <el-image v-for="(item, index) in punchLog.imagesUrl.lunchImages" title="点击大图预览" :key="index" + style="width: 300px; height: 400px" + :src="item" + :preview-src-list="imageUrl"> + </el-image> + </div> + </div> + <div> + <h4>晚餐</h4> + <div> + <el-image v-for="(item, index) in punchLog.imagesUrl.dinnerImages" title="点击大图预览" :key="index" + style="width: 300px; height: 400px" + :src="item" + :preview-src-list="imageUrl"> + </el-image> + </div> + </div> + <div> + <h4>加餐</h4> + <div> + <el-image v-for="(item, index) in punchLog.imagesUrl.extraMealImages" title="点击大图预览" :key="index" + style="width: 300px; height: 400px" + :src="item" + :preview-src-list="imageUrl"> + </el-image> + </div> + </div> + <div> + <h4>体型对比照</h4> + <div> + <el-image v-for="(item, index) in punchLog.imagesUrl.bodyImages" title="点击大图预览" :key="index" + style="width: 300px; height: 400px" + :src="item" + :preview-src-list="imageUrl"> + </el-image> + </div> + </div> + </div> + </div> + </div> + </el-dialog> +</template> +<script> +import { + getPunchLogDetail +} from "@/api/custom/wxUserLog"; +import TableDetailMessage from "@/components/TableDetailMessage"; + +export default { + name: "PunchLogDetail", + components: { + TableDetailMessage + }, + data() { + return { + visible: false, + title: "", + data: null, + punchLog: null, + imageUrl: [], + punchLogDetail: [], + //打卡详情的标题,按竖显示 + punchTitleData: [ + ["姓名", "体重(斤)","饮水量(ml)"], + ["睡觉时间", "起床时间","运动锻炼"], + ["情绪","按食谱进食","食谱外食物"], + ["熬夜失眠", "起床排便","是否便秘"] + ], + //打卡详情的属性名称,与标题对应,按竖显示 + punchValueData: [ + ["customerName","weight","water"], + ["sleepTime", "wakeupTime","sport"], + ["emotion", "diet","slyEatFood"], + ["insomnia","defecation", "constipation"] + ], + }; + }, + methods: { + + // 自定义列背景色 + columnStyle({ row, column, rowIndex, columnIndex }) { + if (columnIndex % 2 === 0) { + //第三第四列的背景色就改变了2和3都是列数的下标 + return "background:#f3f6fc;font-weight:bold"; + } else { + return "background:#ffffff;"; + } + }, + // 自定义备注列背景色 + remarkColumnStyle({ row, column, rowIndex, columnIndex }) { + if (columnIndex % 2 === 0) { + //第三第四列的背景色就改变了2和3都是列数的下标 + return "background:#f3f6fc;font-weight:bold"; + } else { + return "background:#ffffff;"; + } + }, + showDialog(data) { + this.data = data; + this.title = `「${data.customerName}`+" "+`${data.logTime}」打卡记录`; + this.getPunchLogById(); + }, + getPunchLogById() { + getPunchLogDetail(this.data.id).then((res) => { + if (res.code == 200) { + this.visible = true; + this.punchLog = res.data; + res.data.sport = res.data.sport === "Y" ? "是" : "否"; + res.data.diet = res.data.diet === "Y" ? "是" : "否"; + res.data.insomnia = res.data.insomnia === "Y" ? "是" : "否"; + res.data.defecation = res.data.defecation === "Y" ? "是" : "否"; + res.data.constipation = res.data.constipation === "Y" ? "是" : "否"; + for (let i = 0; i < this.punchTitleData.length; i++) { + this.punchLogDetail.push({ + attr_name_one: this.punchTitleData[i][0], + value_one: res.data[this.punchValueData[i][0]], + attr_name_two: this.punchTitleData[i][1], + value_two: res.data[this.punchValueData[i][1]], + attr_name_three: this.punchTitleData[i][2], + value_three: res.data[this.punchValueData[i][2]], + }); + } + let imageUrl = []; + imageUrl = imageUrl.concat(res.data.imagesUrl.breakfastImages); + imageUrl = imageUrl.concat(res.data.imagesUrl.lunchImages); + imageUrl = imageUrl.concat(res.data.imagesUrl.dinnerImages); + imageUrl = imageUrl.concat(res.data.imagesUrl.extraMealImages); + imageUrl = imageUrl.concat(res.data.imagesUrl.bodyImages); + this.imageUrl = imageUrl; + } + }); + }, + onClosed() { + this.data = null; + this.punchLog = null, + this.punchLogDetail = [] + } + }, +}; +</script> + +<style lang="scss" scoped> + +</style> diff --git a/stdiet-ui/src/views/custom/wxUserLog/index.vue b/stdiet-ui/src/views/custom/wxUserLog/index.vue index 08f9a3254..78fbb22ab 100644 --- a/stdiet-ui/src/views/custom/wxUserLog/index.vue +++ b/stdiet-ui/src/views/custom/wxUserLog/index.vue @@ -7,7 +7,7 @@ v-show="showSearch" label-width="68px" > - <el-form-item label="微信应用" prop="appid"> + <!--<el-form-item label="微信应用" prop="appid"> <el-select v-model="queryParams.appid" placeholder="请选择微信应用" @@ -21,7 +21,7 @@ :value="dict.dictValue" /> </el-select> - </el-form-item> + </el-form-item>--> <el-form-item label="客户信息" prop="phone"> <el-input v-model="queryParams.phone" @@ -41,6 +41,17 @@ /> </el-select> </el-form-item> + <el-form-item label="售后" prop="afterNutritionistId"> + <el-select v-model="queryParams.afterNutritionistId" clearable filterable placeholder="请选择"> + <el-option + v-for="dict in afterSaleIdOptions.slice(1)" + :key="dict.dictValue" + :label="dict.dictLabel" + :value="parseInt(dict.dictValue)" + /> + </el-select> + </el-form-item> + <el-form-item> <el-button type="cyan" @@ -109,32 +120,16 @@ :data="wxUserLogList" @selection-change="handleSelectionChange" > - <el-table-column label="用户头像" align="center" prop="avatarUrl"> + <!--<el-table-column label="用户头像" align="center" prop="avatarUrl"> <template slot-scope="scope"> <el-image :src="scope.row.avatarUrl" style="width: 32px; height: 32px; border-radius: 50%" /> </template> - </el-table-column> + </el-table-column>--> <!-- <el-table-column type="selection" width="55" align="center" />--> <!-- <el-table-column label="微信openid" align="center" prop="openid" />--> - <el-table-column label="当天体重" align="center" prop="weight"> - <template slot-scope="scope"> - <span>{{ `${scope.row.weight} 斤` }}</span> - </template> - </el-table-column> - <el-table-column - label="微信应用" - align="center" - prop="appid" - width="120" - :formatter="appidFormat" - /> - <el-table-column label="姓名" align="center" prop="customerName" /> - - <el-table-column label="手机号" align="center" prop="phone" width="180" /> - <el-table-column label="营养师" align="center" prop="nutritionist" /> <el-table-column label="打卡日期" align="center" @@ -145,15 +140,31 @@ <span>{{ parseTime(scope.row.logTime, "{y}-{m}-{d}") }}</span> </template> </el-table-column> + <el-table-column label="姓名" align="center" prop="customerName" /> + <el-table-column label="当天体重" align="center" prop="weight"> + <template slot-scope="scope"> + <span>{{ `${scope.row.weight} 斤` }}</span> + </template> + </el-table-column> + <!--<el-table-column + label="微信应用" + align="center" + prop="appid" + width="120" + :formatter="appidFormat" + />--> + + <!--<el-table-column label="手机号" align="center" prop="phone" width="180" />--> + <el-table-column label="营养师" align="center" prop="nutritionist" /> + <el-table-column label="售后" align="center" prop="afterNutritionist" /> + + <el-table-column label="睡觉时间" align="center" prop="sleepTime" width="120" > - <!-- <template slot-scope="scope">--> - <!-- <span>{{ parseTime(scope.row.sleepTime, '{y}-{m}-{d}') }}</span>--> - <!-- </template>--> </el-table-column> <el-table-column label="起床时间" @@ -161,9 +172,6 @@ prop="wakeupTime" width="120" > - <!-- <template slot-scope="scope">--> - <!-- <span>{{ parseTime(scope.row.wakeupTime, '{y}-{m}-{d}') }}</span>--> - <!-- </template>--> </el-table-column> <el-table-column label="运动锻炼" @@ -171,12 +179,33 @@ prop="sport" :formatter="sportFormat" /> + <el-table-column + label="情绪" + align="center" + prop="emotion" + width="160" + > + <template slot-scope="scope"> + <AutoHideMessage :maxLength="4" :data="scope.row.emotion"></AutoHideMessage> + </template> + </el-table-column> + <el-table-column label="按食谱" align="center" prop="diet" :formatter="dietFormat" /> + <el-table-column + label="其他食物" + align="center" + prop="slyEatFood" + width="160" + > + <template slot-scope="scope"> + <AutoHideMessage :maxLength="4" :data="scope.row.slyEatFood"></AutoHideMessage> + </template> + </el-table-column> <el-table-column label="熬夜失眠" align="center" @@ -189,6 +218,12 @@ prop="defecation" :formatter="defecationFormat" /> + <el-table-column + label="便秘" + align="center" + prop="constipation" + :formatter="constipationFormat" + /> <el-table-column label="饮水量" align="center" prop="water"> <template slot-scope="scope"> <span>{{ `${scope.row.water} ml` }}</span> @@ -201,13 +236,20 @@ > <template slot-scope="scope"> <el-button + size="mini" + type="text" + @click="showPunchLogDetail(scope.row)" + v-hasPermi="['custom:wxUserLog:query']" + >详情 + </el-button> + <!--<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['custom:wxUserLog:edit']" >修改 - </el-button> + </el-button>--> <el-button size="mini" type="text" @@ -357,6 +399,8 @@ <el-button @click="cancel">取 消</el-button> </div> </el-dialog> + + <PunchLogDetail ref="punchLogDetailRef"></PunchLogDetail> </div> </template> @@ -370,7 +414,8 @@ import { updateWxUserLog, } from "@/api/custom/wxUserLog"; import { mapGetters } from "vuex"; - +import PunchLogDetail from "@/components/PunchLog/PunchLogDetail"; +import AutoHideMessage from "@/components/AutoHideMessage"; export default { name: "WxUserLog", data() { @@ -409,7 +454,8 @@ export default { pageSize: 10, appid: null, phone: null, - nutritionistId: null + nutritionistId: null, + afterNutritionistId: null }, // 表单参数 form: {}, @@ -422,6 +468,9 @@ export default { }, }; }, + components:{ + PunchLogDetail,AutoHideMessage + }, created() { this.getList(); this.getDicts("cus_wx_app").then((response) => { @@ -478,6 +527,10 @@ export default { defecationFormat(row, column) { return this.selectDictLabel(this.defecationOptions, row.defecation); }, + // 便秘情况字典翻译 + constipationFormat(row, column) { + return this.selectDictLabel(this.defecationOptions, row.constipation); + }, // 取消按钮 cancel() { this.open = false; @@ -590,6 +643,9 @@ export default { }) .catch(function () {}); }, + showPunchLogDetail(data){ + this.$refs.punchLogDetailRef.showDialog(data); + }, /** 导出按钮操作 */ handleExport() { const queryParams = this.queryParams;