123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- <template>
- <div class="behavior-track-container">
- <!-- 筛选区域 -->
- <div class="filter-section">
- <div class="filter-item">
- <label>操作类型:</label>
- <el-select
- v-model="queryParams.operationType"
- class="type-select"
- @change="handleTypeChange"
- placeholder="请选择行为类型"
- clearable
- >
- <el-option
- v-for="item in typeList"
- :key="item"
- :label="item"
- :value="item"
- ></el-option>
- </el-select>
- </div>
- </div>
- <div v-if="steps.length === 0" class="no-data">
- <p>暂无数据</p>
- </div>
- <!-- 按日期分组展示(分页后的数据) -->
- <div v-if="steps.length != 0" v-for="(records, date) in groupedPaginatedSteps" :key="date" class="date-group">
- <!-- 日期标题(如果是今天,显示“今天”,否则显示具体日期) -->
- <div class="date-title">
- {{ isToday(date) ? '今天' : date }}
- </div>
- <div class="date-divider"></div>
- <!-- 当前日期下的记录 -->
- <el-steps
- direction="vertical"
- :space="120"
- process-status="process"
- finish-status="success"
- class="custom-steps"
- >
- <el-step
- v-for="(step, index) in records"
- :key="index"
- :icon="index === 0 ? 'el-icon-s-help' : 'el-icon-bangzhu'"
- >
- <template #title>
- <div class="step-title">
- {{ step.operationType }}
- <span class="step-time">{{ step.createTime }}</span> <!-- 每个步骤的时间 -->
- </div>
- </template>
- <template #description>
- <!-- 答题 -->
- <div v-if="step.operationType == '答题'" class="step-content">
- <!-- 第一行 -->
- <div class="step-row first-row">
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-notebook-2"></i> 课节名称:</span>
- <span class="detail-value">{{ step.paramVo.courseName }}</span>
- </div>
- </div>
- <!-- 第二行 -->
- <div v-if="step.details" class="step-row second-row">
- <div class="detail-item">
- <span class="detail-label"><i class="el-icon-chat-dot-round"></i> 备注:</span>
- <span class="detail-value">{{ step.details }}</span>
- </div>
- </div>
- </div>
- <!-- 发放奖励 -->
- <div v-else-if="step.operationType == '发送奖励'" class="step-content">
- <!-- 第一行 -->
- <div class="step-row first-row">
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-gift"></i> 课程名称:</span>
- <span class="detail-value">{{ step.paramVo.courseName }}</span>
- </div>
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-coin"></i> 小节名称:</span>
- <span class="detail-value">{{ step.paramVo.title }}</span>
- </div>
- <div v-if="step.fsCourseRedPacketLog" class="detail-item">
- <span class="detail-label"><i class="el-icon-coin"></i> 发放金额:</span>
- <span class="detail-value">{{ step.fsCourseRedPacketLog.amount }} 元</span>
- </div>
- </div>
- <!-- 第二行 -->
- <div v-if="step.details" class="step-row second-row">
- <div class="detail-item">
- <span class="detail-label"><i class="el-icon-chat-dot-round"></i> 备注:</span>
- <span class="detail-value">{{ step.details }}</span>
- </div>
- </div>
- </div>
- <!-- 其他类型 -->
- <div v-else class="step-content">
- <!-- 第一行 -->
- <div class="step-row first-row">
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-office-building"></i> 训练营:</span>
- <span class="detail-value">{{ step.paramVo.trainingCampName }}</span>
- </div>
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-collection-tag"></i> 营期名称:</span>
- <span class="detail-value">{{ step.paramVo.periodName }}</span>
- </div>
- <div v-if="step.paramVo" class="detail-item">
- <span class="detail-label"><i class="el-icon-notebook-2"></i> 课节名称:</span>
- <span class="detail-value">{{ step.paramVo.courseName }}</span>
- </div>
- </div>
- <!-- 第二行 -->
- <div v-if="step.details" class="step-row second-row">
- <div class="detail-item">
- <span class="detail-label"><i class="el-icon-chat-dot-round"></i> 备注:</span>
- <span class="detail-value">{{ step.details }}</span>
- </div>
- </div>
- </div>
- </template>
- </el-step>
- </el-steps>
- </div>
- <!-- 分页 -->
- <pagination
- v-show="total>0"
- :total="total"
- :page.sync="queryParams.pageNum"
- :limit.sync="queryParams.pageSize"
- @pagination="getList"
- />
- </div>
- </template>
- <script>
- import { listUserOperationLog,getOperationType} from "@/api/his/userOperationLog";
- export default {
- data() {
- return {
- // 遮罩层
- loading: true,
- typeList: [],
- queryParams: {
- pageNum: 1,
- pageSize: 10,
- operationType:null,
- userId:null,
- },
- total: 0,
- steps: [
- ]
- };
- },
- created() {
- getOperationType().then(response => {
- this.typeList = response.data;
- });
- },
- computed: {
- // 删除这个属性,直接在 getList 中使用后端的操作类型
- groupedPaginatedSteps() {
- const groups = {};
- this.steps.forEach((step) => {
- const date = step.createTime ?
- (step.createTime instanceof Date ? step.createTime.toISOString().substr(0, 10) : new Date(step.createTime).toISOString().substr(0, 10))
- : null;
- if (!groups[date]) {
- groups[date] = [];
- }
- groups[date].push(step);
- });
- return groups;
- },
- },
- methods: {
- getList() {
- this.loading = true;
- listUserOperationLog(this.queryParams).then(response => {
- this.steps = response.rows;
- this.total = response.total;
- this.loading = false;
- });
- },
- // 判断是否为今天
- isToday(date) {
- const today = new Date();
- const formattedDate = `${today.getFullYear()}-${(today.getMonth() + 1).toString().padStart(2, '0')}-${today.getDate().toString().padStart(2, '0')}`;
- return date === formattedDate;
- },
- getDetails(orderId) {
- this.queryParams.userId=orderId;
- this.getList();
- },
- handleTypeChange() {
- this.queryParams.pageNum = 1; // 重置分页为第一页
- this.getList(); // 重新获取数据
- }
- },
- };
- </script>
- <style scoped>
- .behavior-track-container {
- width: 100%;
- padding: 24px;
- font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", Arial, sans-serif;
- background-color: #f9fbfd;
- border-radius: 12px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
- }
- .filter-section {
- margin-bottom: 24px;
- background: #ffffff;
- border-radius: 8px;
- padding: 16px 20px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- display: flex;
- align-items: center;
- }
- .filter-item {
- display: flex;
- align-items: center;
- }
- .filter-item label {
- font-weight: 600;
- color: #333;
- margin-right: 12px;
- font-size: 14px;
- }
- .type-select {
- width: 240px;
- }
- .custom-steps {
- padding: 0 16px;
- }
- .step-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
- }
- .step-detail p {
- margin: 8px 0;
- line-height: 1.6;
- font-size: 14px;
- color: #555;
- }
- /* 步骤条样式优化 - 移除图标边框 */
- .custom-steps >>> .el-step__head {
- padding-right: 16px;
- }
- .custom-steps >>> .el-step__icon {
- width: 24px;
- height: 24px;
- font-size: 18px;
- }
- .custom-steps >>> .el-step__icon.is-icon {
- color: #52c41a;
- }
- .custom-steps >>> .el-step__line {
- top: 36px;
- left: 11px;
- background-color: #e8e8e8;
- }
- /* 分页样式优化 */
- .pagination-wrapper {
- margin-top: 32px;
- text-align: center;
- padding: 16px 0;
- }
- .custom-pagination >>> .el-pager li {
- border-radius: 4px;
- margin: 0 4px;
- }
- .custom-pagination >>> .el-pager li.active {
- background-color: #52c41a;
- color: #fff;
- }
- .custom-pagination >>> .el-pagination__jump {
- margin-left: 12px;
- }
- .custom-pagination >>> .el-input__inner {
- border-radius: 4px;
- }
- /* 新增和修改的样式 */
- .step-content {
- margin-top: 8px;
- padding: 16px;
- background: #ffffff;
- border-radius: 8px;
- border: 1px solid #ebeef5;
- box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06);
- transition: all 0.3s ease;
- }
- .step-content:hover {
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
- transform: translateY(-1px);
- }
- .detail-label {
- display: inline-flex;
- align-items: center;
- width: 100px;
- color: #606266;
- font-weight: 500;
- flex-shrink: 0;
- }
- .detail-label i {
- margin-right: 6px;
- font-size: 14px;
- color: #909399;
- }
- .detail-value {
- flex: 1;
- color: #303133;
- word-break: break-word;
- padding-left: 4px;
- }
- .step-row {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
- margin-bottom: 8px;
- }
- .first-row .detail-item {
- flex: 1 1 30%; /* 平均分布 */
- display: flex;
- align-items: center;
- margin-right: 16px;
- }
- .second-row .detail-item {
- display: flex;
- align-items: center;
- }
- .time-item {
- margin-left: auto; /* 时间靠右 */
- }
- .detail-label {
- font-weight: 500;
- color: #606266;
- margin-right: 6px;
- }
- .detail-value {
- color: #303133;
- word-break: break-word;
- }
- @media (max-width: 768px) {
- .first-row,
- .second-row {
- flex-direction: column;
- }
- .time-item {
- margin-left: 0;
- }
- }
- /* 完全重置步骤描述区域的样式 */
- .custom-steps >>> .el-step__description {
- width: 100% !important;
- max-width: 100% !important;
- padding: 0 !important;
- margin: 0 !important;
- }
- /* 确保步骤内容使用弹性布局 */
- .step-content {
- display: flex;
- flex-direction: column;
- width: 100%;
- }
- /* 调整时间项 */
- .time-item {
- align-self: flex-end; /* 替代 margin-left: auto */
- margin-top: 8px; /* 如果需要与上方的间距 */
- }
- /* 日期标题样式 */
- .date-title {
- font-size: 16px;
- font-weight: bold;
- color: #333;
- margin-top: 16px;
- }
- .date-divider {
- height: 1px;
- background: #e8e8e8;
- margin: 4px 0 12px;
- }
- /* 在步骤条标题旁边显示时间 */
- .step-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .step-time {
- font-size: 12px;
- color: #999;
- margin-left: 10px;
- }
- /* 第二行的备注 */
- .second-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .second-row .detail-item {
- display: flex;
- align-items: center;
- }
- .no-data {
- text-align: center;
- color: #999;
- font-size: 18px;
- padding: 20px;
- }
- </style>
|