fix/non-blocking-route-navigation
方佳 博 2 years ago
commit 3c38e63bcf

@ -15,12 +15,13 @@
"url": "https://gitee.com/y_project/RuoYi-Vue.git" "url": "https://gitee.com/y_project/RuoYi-Vue.git"
}, },
"dependencies": { "dependencies": {
"@antv/g2": "^5.2.3",
"echarts-stat": "^1.2.0",
"@element-plus/icons-vue": "2.0.10", "@element-plus/icons-vue": "2.0.10",
"@vueup/vue-quill": "1.1.0", "@vueup/vue-quill": "1.1.0",
"@vueuse/core": "9.5.0", "@vueuse/core": "9.5.0",
"axios": "0.27.2", "axios": "0.27.2",
"echarts": "5.4.0", "echarts": "5.4.0",
"echarts-stat": "^1.2.0",
"element-plus": "2.2.27", "element-plus": "2.2.27",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.6.2", "fuse.js": "6.6.2",

@ -2,7 +2,7 @@
* @Author: qinzhenpen qzp1807@126.com * @Author: qinzhenpen qzp1807@126.com
* @Date: 2024-08-16 10:14:59 * @Date: 2024-08-16 10:14:59
* @LastEditors: qinzhenpen qzp1807@126.com * @LastEditors: qinzhenpen qzp1807@126.com
* @LastEditTime: 2024-08-16 16:38:09 * @LastEditTime: 2024-08-17 16:57:01
* @FilePath: \vue3\src\api\marketing-algorithm.js * @FilePath: \vue3\src\api\marketing-algorithm.js
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
@ -31,3 +31,27 @@ export function getMarketingAlgorithmPreprocessing(data) {
data, data,
}); });
} }
// 自建表导入
export function getMarketingAlgorithmImport(data) {
return request({
url: "/api/userprofile/uploadExcel",
method: "POST",
data,
});
}
// 查询自建表
export function getMarketingAlgorithmTable(params) {
return request({
url: "/api/userprofile/selfExcelBaseInfo",
method: "GET",
params,
});
}
// 算法知识导入
export function getMarketingAlgorithmKnowledgeImport(data) {
return request({
url: "/api/model/batchImport",
method: "POST",
data,
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

@ -228,3 +228,32 @@ aside {
box-shadow: 0px 0px 13px 0px #D6E0FE; box-shadow: 0px 0px 13px 0px #D6E0FE;
border-radius: 10px; border-radius: 10px;
} }
.dialogClass{
background:url('@/assets/images/弹框.png') !important;
background-size: 100% 100% !important;
.el-dialog__header{
padding: 5px 0px;
margin-right: 5px !important;
.gbImg{
cursor: pointer;
width: 51px;
height: 31px;
background-size: 100% 100%;
}
}
.xtImg{
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
span{
color: #FFFFFF;
padding: 38px 20px 0;
}
}

@ -1,28 +1,14 @@
<template> <template>
<div <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }">
:class="classObj" <div class="title" style="height: 58px; background-color: #072048 !important; z-index: 900 !important; position: relative">
class="app-wrapper"
:style="{ '--current-color': theme }"
>
<div class="title" style="height: 58px;background-color: #072048 !important;">
<div class="navTitle"> <div class="navTitle">
<span class="nacber-name">天 择 数 字 营 销 实 训 系 统 </span> <span class="nacber-name">天 择 数 字 营 销 实 训 系 统</span>
</div> </div>
</div> </div>
<div <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
v-if="device === 'mobile' && sidebar.opened"
class="drawer-bg"
@click="handleClickOutside"
/>
<sidebar v-if="!sidebar.hide" class="sidebar-container" /> <sidebar v-if="!sidebar.hide" class="sidebar-container" />
<div <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container">
:class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" <div :class="{ 'fixed-header': fixedHeader }"></div>
class="main-container"
>
<div :class="{ 'fixed-header': fixedHeader }">
<!-- <navbar @setLayout="setLayout" />
<tags-view v-if="needTagsView" /> -->
</div>
<app-main /> <app-main />
<settings ref="settingRef" /> <settings ref="settingRef" />
</div> </div>

@ -87,19 +87,6 @@ export const dynamicRoutes = [
}, },
], ],
}, },
// {
// path: "",
// component: Layout,
// redirect: "/digitalMarketAlgorithm",
// children: [
// {
// path: "/digitalMarketAlgorithm",
// component: () => import("@/views/digitalMarketAlgorithm/index"),
// name: "digitalMarketAlgorithm",
// meta: { title: "数字营销算法", icon: "monitor2", affix: true },
// },
// ],
// },
{ {
path: "", path: "",
component: Layout, component: Layout,

@ -1,20 +1,61 @@
import { parseTime } from './ruoyi' import { parseTime } from "./ruoyi";
export function getAssetsFile(url){ /**
* 通用分页函数
* @param {Array} data - 需要分页的数据源
* @param {Number} page - 当前页码
* @param {Number} pageSize - 每页显示的条目数
* @returns {Object} 分页结果,包含当前页的数据,页码信息,及总页数
*/
export function paginate(data, page = 1, pageSize = 10) {
// 计算总页数
const totalItems = data.length;
const totalPages = Math.ceil(totalItems / pageSize);
// 确保页码在有效范围内
const currentPage = Math.min(Math.max(page, 1), totalPages);
// 计算当前页的数据起始索引和结束索引
const startIndex = (currentPage - 1) * pageSize;
const endIndex = Math.min(startIndex + pageSize, totalItems);
// 获取当前页的数据片段
const pageData = data.slice(startIndex, endIndex);
return {
currentPage,
pageSize,
totalItems,
totalPages,
data: pageData,
};
}
export function getAssetsFile(url) {
return new URL(`../assets/images/${url}`, import.meta.url).href; return new URL(`../assets/images/${url}`, import.meta.url).href;
} }
/** /**
* 表格时间格式化 * 表格时间格式化
*/ */
function isTimestamp(value) {
// 判断是否为数字类型且是否为整数
if (typeof value === "number" && Number.isInteger(value)) {
// 判断时间戳是否为13位
return value.toString().length === 13;
}
return false;
}
export function formatDate(cellValue) { export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return ""; // 判断是不是时间戳不是就返回
var date = new Date(cellValue) let time;
var year = date.getFullYear() if (isTimestamp(cellValue)) {
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1 var date = new Date(cellValue);
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate() var year = date.getFullYear();
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours() var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes() var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds() var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
time = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
} else {
time = cellValue;
}
return time;
} }
/** /**
@ -23,40 +64,30 @@ export function formatDate(cellValue) {
* @returns {string} * @returns {string}
*/ */
export function formatTime(time, option) { export function formatTime(time, option) {
if (('' + time).length === 10) { if (("" + time).length === 10) {
time = parseInt(time) * 1000 time = parseInt(time) * 1000;
} else { } else {
time = +time time = +time;
} }
const d = new Date(time) const d = new Date(time);
const now = Date.now() const now = Date.now();
const diff = (now - d) / 1000 const diff = (now - d) / 1000;
if (diff < 30) { if (diff < 30) {
return '刚刚' return "刚刚";
} else if (diff < 3600) { } else if (diff < 3600) {
// less 1 hour // less 1 hour
return Math.ceil(diff / 60) + '分钟前' return Math.ceil(diff / 60) + "分钟前";
} else if (diff < 3600 * 24) { } else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前' return Math.ceil(diff / 3600) + "小时前";
} else if (diff < 3600 * 24 * 2) { } else if (diff < 3600 * 24 * 2) {
return '1天前' return "1天前";
} }
if (option) { if (option) {
return parseTime(time, option) return parseTime(time, option);
} else { } else {
return ( return d.getMonth() + 1 + "月" + d.getDate() + "日" + d.getHours() + "时" + d.getMinutes() + "分";
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
} }
} }
@ -65,18 +96,18 @@ export function formatTime(time, option) {
* @returns {Object} * @returns {Object}
*/ */
export function getQueryObject(url) { export function getQueryObject(url) {
url = url == null ? window.location.href : url url = url == null ? window.location.href : url;
const search = url.substring(url.lastIndexOf('?') + 1) const search = url.substring(url.lastIndexOf("?") + 1);
const obj = {} const obj = {};
const reg = /([^?&=]+)=([^?&=]*)/g const reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, (rs, $1, $2) => { search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1) const name = decodeURIComponent($1);
let val = decodeURIComponent($2) let val = decodeURIComponent($2);
val = String(val) val = String(val);
obj[name] = val obj[name] = val;
return rs return rs;
}) });
return obj return obj;
} }
/** /**
@ -85,14 +116,14 @@ export function getQueryObject(url) {
*/ */
export function byteLength(str) { export function byteLength(str) {
// returns the byte length of an utf8 string // returns the byte length of an utf8 string
let s = str.length let s = str.length;
for (var i = str.length - 1; i >= 0; i--) { for (var i = str.length - 1; i >= 0; i--) {
const code = str.charCodeAt(i) const code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) s++ if (code > 0x7f && code <= 0x7ff) s++;
else if (code > 0x7ff && code <= 0xffff) s += 2 else if (code > 0x7ff && code <= 0xffff) s += 2;
if (code >= 0xDC00 && code <= 0xDFFF) i-- if (code >= 0xdc00 && code <= 0xdfff) i--;
} }
return s return s;
} }
/** /**
@ -100,13 +131,13 @@ export function byteLength(str) {
* @returns {Array} * @returns {Array}
*/ */
export function cleanArray(actual) { export function cleanArray(actual) {
const newArray = [] const newArray = [];
for (let i = 0; i < actual.length; i++) { for (let i = 0; i < actual.length; i++) {
if (actual[i]) { if (actual[i]) {
newArray.push(actual[i]) newArray.push(actual[i]);
} }
} }
return newArray return newArray;
} }
/** /**
@ -114,13 +145,13 @@ export function cleanArray(actual) {
* @returns {Array} * @returns {Array}
*/ */
export function param(json) { export function param(json) {
if (!json) return '' if (!json) return "";
return cleanArray( return cleanArray(
Object.keys(json).map(key => { Object.keys(json).map((key) => {
if (json[key] === undefined) return '' if (json[key] === undefined) return "";
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) return encodeURIComponent(key) + "=" + encodeURIComponent(json[key]);
}) })
).join('&') ).join("&");
} }
/** /**
@ -128,21 +159,21 @@ export function param(json) {
* @returns {Object} * @returns {Object}
*/ */
export function param2Obj(url) { export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') const search = decodeURIComponent(url.split("?")[1]).replace(/\+/g, " ");
if (!search) { if (!search) {
return {} return {};
} }
const obj = {} const obj = {};
const searchArr = search.split('&') const searchArr = search.split("&");
searchArr.forEach(v => { searchArr.forEach((v) => {
const index = v.indexOf('=') const index = v.indexOf("=");
if (index !== -1) { if (index !== -1) {
const name = v.substring(0, index) const name = v.substring(0, index);
const val = v.substring(index + 1, v.length) const val = v.substring(index + 1, v.length);
obj[name] = val obj[name] = val;
} }
}) });
return obj return obj;
} }
/** /**
@ -150,9 +181,9 @@ export function param2Obj(url) {
* @returns {string} * @returns {string}
*/ */
export function html2Text(val) { export function html2Text(val) {
const div = document.createElement('div') const div = document.createElement("div");
div.innerHTML = val div.innerHTML = val;
return div.textContent || div.innerText return div.textContent || div.innerText;
} }
/** /**
@ -162,21 +193,21 @@ export function html2Text(val) {
* @returns {Object} * @returns {Object}
*/ */
export function objectMerge(target, source) { export function objectMerge(target, source) {
if (typeof target !== 'object') { if (typeof target !== "object") {
target = {} target = {};
} }
if (Array.isArray(source)) { if (Array.isArray(source)) {
return source.slice() return source.slice();
} }
Object.keys(source).forEach(property => { Object.keys(source).forEach((property) => {
const sourceProperty = source[property] const sourceProperty = source[property];
if (typeof sourceProperty === 'object') { if (typeof sourceProperty === "object") {
target[property] = objectMerge(target[property], sourceProperty) target[property] = objectMerge(target[property], sourceProperty);
} else { } else {
target[property] = sourceProperty target[property] = sourceProperty;
} }
}) });
return target return target;
} }
/** /**
@ -185,18 +216,16 @@ export function objectMerge(target, source) {
*/ */
export function toggleClass(element, className) { export function toggleClass(element, className) {
if (!element || !className) { if (!element || !className) {
return return;
} }
let classString = element.className let classString = element.className;
const nameIndex = classString.indexOf(className) const nameIndex = classString.indexOf(className);
if (nameIndex === -1) { if (nameIndex === -1) {
classString += '' + className classString += "" + className;
} else { } else {
classString = classString = classString.substr(0, nameIndex) + classString.substr(nameIndex + className.length);
classString.substr(0, nameIndex) +
classString.substr(nameIndex + className.length)
} }
element.className = classString element.className = classString;
} }
/** /**
@ -204,10 +233,10 @@ export function toggleClass(element, className) {
* @returns {Date} * @returns {Date}
*/ */
export function getTime(type) { export function getTime(type) {
if (type === 'start') { if (type === "start") {
return new Date().getTime() - 3600 * 1000 * 24 * 90 return new Date().getTime() - 3600 * 1000 * 24 * 90;
} else { } else {
return new Date(new Date().toDateString()) return new Date(new Date().toDateString());
} }
} }
@ -218,38 +247,38 @@ export function getTime(type) {
* @return {*} * @return {*}
*/ */
export function debounce(func, wait, immediate) { export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result let timeout, args, context, timestamp, result;
const later = function() { const later = function () {
// 据上一次触发时间间隔 // 据上一次触发时间间隔
const last = +new Date() - timestamp const last = +new Date() - timestamp;
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) { if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last) timeout = setTimeout(later, wait - last);
} else { } else {
timeout = null timeout = null;
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) { if (!immediate) {
result = func.apply(context, args) result = func.apply(context, args);
if (!timeout) context = args = null if (!timeout) context = args = null;
}
} }
} }
};
return function(...args) { return function (...args) {
context = this context = this;
timestamp = +new Date() timestamp = +new Date();
const callNow = immediate && !timeout const callNow = immediate && !timeout;
// 如果延时不存在,重新设定延时 // 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait) if (!timeout) timeout = setTimeout(later, wait);
if (callNow) { if (callNow) {
result = func.apply(context, args) result = func.apply(context, args);
context = args = null context = args = null;
} }
return result return result;
} };
} }
/** /**
@ -260,18 +289,18 @@ export function debounce(func, wait, immediate) {
* @returns {Object} * @returns {Object}
*/ */
export function deepClone(source) { export function deepClone(source) {
if (!source && typeof source !== 'object') { if (!source && typeof source !== "object") {
throw new Error('error arguments', 'deepClone') throw new Error("error arguments", "deepClone");
} }
const targetObj = source.constructor === Array ? [] : {} const targetObj = source.constructor === Array ? [] : {};
Object.keys(source).forEach(keys => { Object.keys(source).forEach((keys) => {
if (source[keys] && typeof source[keys] === 'object') { if (source[keys] && typeof source[keys] === "object") {
targetObj[keys] = deepClone(source[keys]) targetObj[keys] = deepClone(source[keys]);
} else { } else {
targetObj[keys] = source[keys] targetObj[keys] = source[keys];
} }
}) });
return targetObj return targetObj;
} }
/** /**
@ -279,16 +308,16 @@ export function deepClone(source) {
* @returns {Array} * @returns {Array}
*/ */
export function uniqueArr(arr) { export function uniqueArr(arr) {
return Array.from(new Set(arr)) return Array.from(new Set(arr));
} }
/** /**
* @returns {string} * @returns {string}
*/ */
export function createUniqueString() { export function createUniqueString() {
const timestamp = +new Date() + '' const timestamp = +new Date() + "";
const randomNum = parseInt((1 + Math.random()) * 65536) + '' const randomNum = parseInt((1 + Math.random()) * 65536) + "";
return (+(randomNum + timestamp)).toString(32) return (+(randomNum + timestamp)).toString(32);
} }
/** /**
@ -298,7 +327,7 @@ export function createUniqueString() {
* @returns {boolean} * @returns {boolean}
*/ */
export function hasClass(ele, cls) { export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
} }
/** /**
@ -307,7 +336,7 @@ export function hasClass(ele, cls) {
* @param {string} cls * @param {string} cls
*/ */
export function addClass(ele, cls) { export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls if (!hasClass(ele, cls)) ele.className += " " + cls;
} }
/** /**
@ -317,94 +346,91 @@ export function addClass(ele, cls) {
*/ */
export function removeClass(ele, cls) { export function removeClass(ele, cls) {
if (hasClass(ele, cls)) { if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
ele.className = ele.className.replace(reg, ' ') ele.className = ele.className.replace(reg, " ");
} }
} }
export function makeMap(str, expectsLowerCase) { export function makeMap(str, expectsLowerCase) {
const map = Object.create(null) const map = Object.create(null);
const list = str.split(',') const list = str.split(",");
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
map[list[i]] = true map[list[i]] = true;
} }
return expectsLowerCase return expectsLowerCase ? (val) => map[val.toLowerCase()] : (val) => map[val];
? val => map[val.toLowerCase()]
: val => map[val]
} }
export const exportDefault = 'export default ' export const exportDefault = "export default ";
export const beautifierConf = { export const beautifierConf = {
html: { html: {
indent_size: '2', indent_size: "2",
indent_char: ' ', indent_char: " ",
max_preserve_newlines: '-1', max_preserve_newlines: "-1",
preserve_newlines: false, preserve_newlines: false,
keep_array_indentation: false, keep_array_indentation: false,
break_chained_methods: false, break_chained_methods: false,
indent_scripts: 'separate', indent_scripts: "separate",
brace_style: 'end-expand', brace_style: "end-expand",
space_before_conditional: true, space_before_conditional: true,
unescape_strings: false, unescape_strings: false,
jslint_happy: false, jslint_happy: false,
end_with_newline: true, end_with_newline: true,
wrap_line_length: '110', wrap_line_length: "110",
indent_inner_html: true, indent_inner_html: true,
comma_first: false, comma_first: false,
e4x: true, e4x: true,
indent_empty_lines: true indent_empty_lines: true,
}, },
js: { js: {
indent_size: '2', indent_size: "2",
indent_char: ' ', indent_char: " ",
max_preserve_newlines: '-1', max_preserve_newlines: "-1",
preserve_newlines: false, preserve_newlines: false,
keep_array_indentation: false, keep_array_indentation: false,
break_chained_methods: false, break_chained_methods: false,
indent_scripts: 'normal', indent_scripts: "normal",
brace_style: 'end-expand', brace_style: "end-expand",
space_before_conditional: true, space_before_conditional: true,
unescape_strings: false, unescape_strings: false,
jslint_happy: true, jslint_happy: true,
end_with_newline: true, end_with_newline: true,
wrap_line_length: '110', wrap_line_length: "110",
indent_inner_html: true, indent_inner_html: true,
comma_first: false, comma_first: false,
e4x: true, e4x: true,
indent_empty_lines: true indent_empty_lines: true,
} },
} };
// 首字母大小 // 首字母大小
export function titleCase(str) { export function titleCase(str) {
return str.replace(/( |^)[a-z]/g, L => L.toUpperCase()) return str.replace(/( |^)[a-z]/g, (L) => L.toUpperCase());
} }
// 下划转驼峰 // 下划转驼峰
export function camelCase(str) { export function camelCase(str) {
return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase()) return str.replace(/_[a-z]/g, (str1) => str1.substr(-1).toUpperCase());
} }
export function isNumberStr(str) { export function isNumberStr(str) {
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str) return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str);
} }
//文件下载 //文件下载
export function downBlobFile(fileName, fileBlob) { export function downBlobFile(fileName, fileBlob) {
const link = document.createElement('a') const link = document.createElement("a");
try { try {
// let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //如果后台返回的不是blob对象类型,先定义成blob对象格式,type格式根据返回文件不同修改 // let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //如果后台返回的不是blob对象类型,先定义成blob对象格式,type格式根据返回文件不同修改
const blob = fileBlob const blob = fileBlob;
const _fileName = fileName // 拆解获取文件名,如果后端没返回文件格式,则需要自己拼接文件后缀 const _fileName = fileName; // 拆解获取文件名,如果后端没返回文件格式,则需要自己拼接文件后缀
link.style.display = 'none' link.style.display = "none";
// 兼容浏览器 // 兼容浏览器
const url = window.URL || window.webkitURL || window.moxURL const url = window.URL || window.webkitURL || window.moxURL;
link.href = url.createObjectURL(blob) // 如果没设置axios请求reponseType为‘blob’的话,则参数应为new Blob(文件流),否则报错 link.href = url.createObjectURL(blob); // 如果没设置axios请求reponseType为‘blob’的话,则参数应为new Blob(文件流),否则报错
link.download = _fileName // 下载的文件名称 link.download = _fileName; // 下载的文件名称
link.click() link.click();
window.URL.revokeObjectURL(url) // #URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法. window.URL.revokeObjectURL(url); // #URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.
} catch (error) { } catch (error) {
console.error(error.message) console.error(error.message);
} }
} }

@ -19,7 +19,7 @@ const service = axios.create({
baseURL:'http://192.168.2.28:9868/', baseURL:'http://192.168.2.28:9868/',
// baseURL:'http://118.31.7.2:9868/', // baseURL:'http://118.31.7.2:9868/',
// 超时 // 超时
timeout: 10000 timeout: 100000
}) })
// request拦截器 // request拦截器
service.interceptors.request.use(config => { service.interceptors.request.use(config => {

@ -1,6 +1,6 @@
<template> <template>
<div class="main-content"> <div class="main-content">
<el-scrollbar height="680px"> <el-scrollbar height="730px">
<component :is="currentComponent" ref="content"></component> <component :is="currentComponent" ref="content"></component>
</el-scrollbar> </el-scrollbar>
</div> </div>

@ -0,0 +1,112 @@
<template>
<div>
<el-dialog
:title="title"
style="width: 1308px; height: 838px"
custom-class="dialog"
v-model="props.showModel"
:before-close="close"
>
<div
class="diaMain"
style="
margin-top: -35px;
padding: 10px;
padding-left: 20px;
"
>
<el-scrollbar height="730px">
<slot name="content" class="main"></slot>
</el-scrollbar>
</div>
<!-- <template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">确定</el-button>
<el-button type="primary" @click="dialogVisible = false">
返回
</el-button>
</div>
</template> -->
</el-dialog>
</div>
</template>
<script setup>
const emits = defineEmits(["closePop", "submit"]);
const dialogVisible = ref(false);
const props = defineProps({
modelValue: [String, Object, Array],
//控制显隐
showModel: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "任务知识导入",
},
width: {
type: String,
default: "673",
},
showOprBtn: {
type: Boolean,
default: true,
},
});
const close = () => {
emits("closePop");
};
const submit = () => {
emits("submit");
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss">
.diaMain{
img{
max-height: 1200px;
max-width: 1200px;
}
p{
font-size: 15px;
}
}
.dialog {
border-radius: 12px;
.el-dialog__header {
background: url("@/assets/images/szjj/弹窗标题.png") !important;
background-size: 100% 100% !important;
margin-right: 0 !important;
span {
font-size: 14px;
font-weight: 400;
color: #ffffff;
}
}
.el-dialog__headerbtn {
top: 8px !important;
background: url("@/assets/images/szjj/关闭2.png") no-repeat;
background-size: 100% 100% !important;
width: 16px;
height: 16px;
margin-right: 15px;
margin-top: 7px;
}
.el-dialog__headerbtn i {
content: "1";
font-size: 13px;
visibility: hidden;
}
.el-dialog__footer {
text-align: center;
}
.tj{
color: #FFFFFF;
}
.cxks{
background: url('@/assets/images/szjj/重新开始.png') no-repeat;
}
}
</style>

@ -1,115 +0,0 @@
<template>
<el-dialog
class="testDialog"
append-to-body
v-model="props.showModel"
title=""
align-center
draggable
:modal="false"
:show-close="false"
:style="{ borderRadius: 12 + 'px', width: props.width + 'px' }"
:close-on-click-modal="false"
custom-class="dialog"
>
<template #header>
<div
class="my-header"
:style="{
width: props.width + 'px',
backgroundSize: props.width + 'px ' + 43 + 'px',
}"
>
<span>{{ props.title }}</span>
<span style="cursor: pointer" @click="close()"
><img
style="width: 13px; height: 13px"
src="@/assets/images/关闭.png"
alt=""
/></span>
</div>
</template>
<slot name="content"></slot>
</el-dialog>
</template>
<script setup>
const emits = defineEmits(["closePop", "submit"]);
const dialogVisible = ref(false);
const props = defineProps({
modelValue: [String, Object, Array],
//控制显隐
showModel: {
type: Boolean,
default: false,
},
title: {
type: String,
default: "Title",
},
width: {
type: String,
default: "673",
},
showOprBtn: {
type: Boolean,
default: true,
},
});
const close = () => {
emits("closePop");
};
const submit = () => {
emits("submit");
};
</script>
<style lang="scss" scoped>
.my-header {
display: flex;
justify-content: space-between;
padding-left: 25px;
padding-top: 15px;
padding-right: 15px;
position: absolute;
left: 0;
top: 0;
// background: url("@/assets/images/popHeader.png") no-repeat;
background-color: #ff6100;
width: 673px;
height: 53px;
background-size: 673px 43px;
color: white;
border-radius: 10px 10px 0 0;
}
.dialog-footer {
display: block;
text-align: center;
.okBtn {
width: 118px;
height: 40px;
// background: url("@/assets/images/popOkBtn.png");
background-color: #ff6100;
border: none;
color: white;
// padding-left: 40px;
text-align: center;
// margin-right: 50px;
}
.cancelBtn {
width: 118px;
height: 40px;
// background: url("@/assets/images/popCancelBtn.png");
border: none;
color: white;
padding-left: 40px;
}
}
</style>
<style>
.dialog_class {
pointer-events: none;
}
.el-dialog {
pointer-events: auto;
}
</style>

@ -1,83 +1,74 @@
<!--
* @Author: qinzhenpen qzp1807@126.com
* @Date: 2024-08-16 17:56:32
* @LastEditors: qinzhenpen qzp1807@126.com
* @LastEditTime: 2024-08-16 17:59:16
* @FilePath: \vue3\src\views\digitalMarketTech\AIGCLargeModel\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template> <template>
<div class="app-top"> <div class="app-top">
<el-button v-for="(item,index) in imgData" :key="index" :class="item.img" @click="clickIndx(index)">{{item.text}}</el-button> <el-button v-for="(item, index) in imgData" :key="index" :class="item.img" @click="clickIndx(index)">{{ item.text }}</el-button>
</div> </div>
<component :is="page"></component> <component :is="page"></component>
</template> </template>
<script setup> <script setup>
import AIVenison from './components/AIVenisonDiagram.vue' import AIVenison from "./components/AIVenisonDiagram.vue";
import AIGC from './components/thirdPartyAIGC.vue' import AIGC from "./components/thirdPartyAIGC.vue";
const pageData=[AIVenison,null,null,null,null,AIGC] const pageData = [AIVenison, null, null, null, null, AIGC];
const page=ref(AIVenison) const page = ref(AIVenison);
const clickIndx=(index)=>{ const clickIndx = (index) => {
page.value=pageData[index] page.value = pageData[index];
} };
const imgData=[ const imgData = [
{
text: "AI文生图",
img: "wst",
},
{
text: "AI文章",
img: "wz",
},
{ {
text:'AI文生图', text: "AI标题",
img:'wst' img: "bt",
},{
text:'AI文章',
img:'wz'
},{
text:'AI标题',
img:'bt'
},{
text:'AI修图',
img:'xt'
},{
text:'AI视频',
img:'sp'
},{
text:'第三方AIGC大模型',
img:'dmx'
}, },
] {
text: "AI修图",
img: "xt",
},
{
text: "AI视频",
img: "sp",
},
];
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.content{ .content {
color: #fff; color: #fff;
} }
.app-top{ .app-top {
background: #041C49; background: #041c49;
padding: 10px; padding: 10px;
margin: 10px 0px -9px 10px;; margin: 10px 0px -9px 10px;
} }
.el-button{ .el-button {
width: 160px; width: 160px;
height: 36px; height: 36px;
color: #FFFFFF; color: #ffffff;
border-color:#FFFFFF00; border-color: #ffffff00;
padding: 8px 0px 8px 32px; padding: 8px 0px 8px 32px;
background-size: 100% 100% !important; background-size: 100% 100% !important;
} }
.wst{ .wst {
background: url('@/assets/images/1.png'); background: url("@/assets/images/1.png");
} }
.wz{ .wz {
background: url('@/assets/images/2.png'); background: url("@/assets/images/2.png");
} }
.bt{ .bt {
background: url('@/assets/images/3.png'); background: url("@/assets/images/3.png");
} }
.xt{ .xt {
background: url('@/assets/images/4.png'); background: url("@/assets/images/4.png");
} }
.sp{ .sp {
background: url('@/assets/images/5.png'); background: url("@/assets/images/5.png");
} }
.dmx{ .dmx {
background: url('@/assets/images/6.png'); background: url("@/assets/images/6.png");
} }
</style> </style>

@ -5,20 +5,7 @@
<p style="font-weight: 400;font-size: 12px;color: #E6E6E6;">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p> <p style="font-weight: 400;font-size: 12px;color: #E6E6E6;">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
</div> </div>
<div class="main-but"> <div class="main-but">
<el-upload <el-button @click="runResultShow=true"><img src="../../../assets/images/导入.png" alt="">算法知识导入</el-button>
ref="uploadRef"
class="upload-demo"
:file-list="fileList"
:auto-upload="false"
:on-change="handleChange"
:show-file-list="false"
multiple="multiple"
>
<template #trigger>
<el-button><img src="../../../assets/images/导入.png" alt="">算法知识导入</el-button>
</template>
<!-- <div class="reportPromptFile" v-html="item[`${index}`].path"></div> -->
</el-upload>
<el-button @click="taskSubmit"><img src="../../../assets/images/提交.png" alt="">实训任务提交</el-button> <el-button @click="taskSubmit"><img src="../../../assets/images/提交.png" alt="">实训任务提交</el-button>
</div> </div>
<div class="app-main"> <div class="app-main">
@ -113,7 +100,7 @@
<el-table :data="tableData2" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350"> <el-table :data="tableData2" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350">
<el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/> <el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/>
</el-table> </el-table>
<el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> <!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
</div> </div>
<div class="analysisResults" style="margin-top: 20px"> <div class="analysisResults" style="margin-top: 20px">
<span style="font-weight: bold;font-size: 18px;color: #3596EB;display: block;">分析结果:</span> <span style="font-weight: bold;font-size: 18px;color: #3596EB;display: block;">分析结果:</span>
@ -121,7 +108,7 @@
<el-table :data="tableData3" row-key="TSuid" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350"> <el-table :data="tableData3" row-key="TSuid" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350">
<el-table-column v-for="column in tableLabel2" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/> <el-table-column v-for="column in tableLabel2" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/>
</el-table> </el-table>
<el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> <!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
</div> </div>
</div> </div>
</div> </div>
@ -175,22 +162,44 @@
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<pop-model
:showModel="runResultShow"
title="关联规则挖掘"
@closePop="runResultShow = false"
>
<template v-slot:content>
<div>
<p style="font-weight: 700;font-size:22px">一、简介</p><p>Apriori算法是一种用于挖掘数据集中频繁项集的算法,进而用于生成关联规则。这种算法在数据挖掘、机器学习、市场篮子分析等多个领域都有广泛的应用。</p><p style="font-size:19px;font-weight:600">什么是关联规则挖掘?</p><p>关联规则挖掘是数据挖掘中的一个重要分支,其目标是发现在一个数据集中变量间存在的有趣的关联或模式。<br />例子: 假设在一个零售商的交易数据中,如果客户购买了啤酒,他们也很有可能购买薯片。这里的“啤酒”和“薯片”就形成了一个关联规则。</p><p style="font-size:19px;font-weight:600">什么是频繁项集?</p><p>频繁项集是在数据集中出现次数大于或等于最小支持度(Minimum Support Threshold)的项的集合。<br />例子: 在超市购物数据中,如果“牛奶”和“面包”这一组合经常一起出现在同一个购物篮里,并且出现的次数超过了最小支持度,那么{"牛奶", "面包"}就是一个频繁项集。</p><p style="font-size:19px;font-weight:600">什么是支持度与置信度?</p><li>支持度(Support): 是某个项集在所有交易中出现的频率。它用于衡量一个项集的普遍性。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子: 如果我们有100笔交易,其中有30笔交易包含了“牛奶”,那么“牛奶”的支持度就是30%。</li><li>置信度(Confidence): 是在A出现的情况下,B出现的条件概率。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子: 如果在包含“牛奶”的所有交易中,有70%的交易也包含了“面包”,那么从“牛奶”到“面包”的置信度就是70%。</li>
<p style="font-size:19px;font-weight:600">Apriori算法的重要性</p><p>Apriori算法由于其简单、高效的特性,在数据挖掘中有着广泛的应用。它不仅能用于挖掘数据中的隐藏模式,还能用于诸如产品推荐、用户行为分析、网络安全等多个应用场景。<br />例子: 在电子商务网站中,Apriori算法可以用于分析用户购买历史数据,进而实现个性化推荐,提升销售额和用户满意度。</p><p style="font-size:19px;font-weight:600">应用场景</p><p>由于其广泛的用途和灵活性,Apriori算法在以下几个主要领域内有着广泛的应用:</p><li>市场篮子分析: 了解哪些产品经常被一起购买,以进行有效的产品布局或优惠策略。</li><li>医疗诊断: 分析病人的历史数据,找出病症和治疗方案之间的关联。</li><li>网络安全: 通过分析网络日志,找出异常模式,以预防或检测安全威胁。</li><p>通过这些定义和例子,我们可以更全面地了解Apriori算法的基本概念、重要性和应用范围,为后续的技术解析和实战应用打下坚实的基础。</p><p style="font-weight: 700;font-size:22px">二、理论基础</p><p>在深入探讨Apriori算法之前,理解其背后的理论基础是非常重要的。本节将详细介绍关联规则挖掘的基础概念,包括项集、支持度、置信度、提升度以及如何使用这些概念来挖掘有用的关联规则。</p><p style="font-size:19px;font-weight:600">项和项集</p><li>项(Item): 在关联规则挖掘中,项通常指数据集中的一个元素。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子: 在一个超市的购物篮数据中,"牛奶"、"面包"、"啤酒"等都是单个的项。</li><li>项集(Itemset): 是一个项的集合,可以包含一个或多个项。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子: {"牛奶", "面包"} 和 {"啤酒", "薯片", "面包"} 都是项集。</li><p style="font-size:19px;font-weight:600">支持度(Support)</p>
<p>支持度是一个度量,用于表示一个项集在整个数据集中出现的频率。<br />!file</p><p style="font-size:19px;font-weight:600">置信度(Confidence)</p><p>置信度表示在包含项集X的所有事务中,也包含项集Y的事务的概率。</p><img src="@/assets/images/f2001.png" alt=""><p style="font-size:19px;font-weight:600">提升度(Lift)</p><p>提升度用于衡量项集X和Y的出现是否相互独立。</p><img src="@/assets/images/f2002.png" alt=""><p style="font-size:19px;font-weight:600">Apriori原理</p><p>Apriori原理是Apriori算法的核心,它基于一个简单但重要的观察:一个项集是频繁的,那么它的所有子集也必须是频繁的。<br />例子: 如果{"牛奶", "面包", "啤酒"}是一个频繁项集,那么{"牛奶", "面包"}、{"牛奶", "啤酒"}和{"面包", "啤酒"}也必须是频繁项集。<br />通过以上的概念和例子,我们应该对关联规则挖掘的基础理论有了更深入的了解。这为我们后续详解Apriori算法以及实际应用提供了坚实的基础。</p><p style="font-weight: 700;font-size:22px">三、Apriori算法概述</p><p>Apriori算法是由Agrawal和Srikant于1994年提出的,用于高效地挖掘频繁项集和生成关联规则。其名字“Apriori”来源于拉丁语,意为“从先验知识”。这很好地反映了算法的核心思想:利用已知的频繁项集(即先验知识)来更有效地找到更大的频繁项集。</p><p style="font-size:19px;font-weight:600">算法步骤</p><img src="@/assets/images/f2004.png" alt=""><p>Apriori算法的执行流程主要包含两个步骤:<br />&nbsp;&nbsp;1.频繁项集生成(Frequent Itemset Generation): 找出满足最小支持度阈值的所有频繁项集。<br />&nbsp;&nbsp;2.关联规则生成(Association Rule Generation): 从频繁项集中生成高置信度的关联规则。</p>
<p style="font-size:19px;font-weight:600">频繁项集生成</p><p>&nbsp;&nbsp;1.扫描数据集,找出所有单一项的支持度,并筛选出满足最小支持度的项。<br />&nbsp;&nbsp;2.使用满足最小支持度的项生成新的候选项集。<br />&nbsp;&nbsp;3.计算新生成的候选项集的支持度,并再次筛选。<br />&nbsp;&nbsp;4.重复上述步骤,直到不能生成新的频繁项集。<br />例子: 假设有一个购物交易数据集,其中包括5笔交易。第一步是计算所有单一商品(如“牛奶”,“面包”等)在这5笔交易中的出现次数,并筛选出那些出现次数达到最小支持度的商品。</p><p style="font-size:19px;font-weight:600">关联规则生成</p><p>&nbsp;&nbsp;1.对于每一个频繁项集,生成所有可能的非空子集。<br />&nbsp;&nbsp;2.对每一条生成的规则 ( A \Rightarrow B ),计算其置信度。<br />&nbsp;&nbsp;3.如果规则的置信度满足最小置信度要求,则该规则为有效关联规则。</p><p>例子: 对于频繁项集 {"牛奶", "面包", "黄油"},可能的规则有 "牛奶, 面包 -> 黄油", "牛奶, 黄油 -> 面包" 等。计算这些规则的置信度,并筛选出满足最小置信度的规则。</p><p style="font-size:19px;font-weight:600">优缺点</p><p style="font-size:19px;font-weight:600">优点</p><li>简单易懂: Apriori算法基于直观的原理,并且计算过程简单。</li><li>可扩展性强: 算法可以应用于大规模的数据集。</li><p style="font-size:19px;font-weight:600">缺点</p><li>计算量大: 在大数据集上,可能需要生成大量的候选项集。</li><li>多次扫描数据: 算法需要多次扫描数据集以计算项集的支持度,这在数据集很大时可能是低效的。</li><p>例子: 在一个包含百万级交易数据的电子商务网站中,使用Apriori算法可能需要消耗大量计算资源和时间。<br />通过以上的详细描述和例子,我们应该对Apriori算法有了全面而深入的理解。这为我们后续的技术解析和实战应用奠定了基础。</p>
<p style="font-weight: 700;font-size:22px">四、实战应用</p><p>在理解了Apriori算法的理论基础和工作原理之后,现在我们将进一步探讨其在实际场景中的应用。特别是在购物篮分析和推荐系统中,Apriori算法被广泛应用。<br />为了更好地说明这一点,下面将通过Python展示如何实现Apriori算法,并用一个简单的购物数据集进行演示。</p><p style="font-size:19px;font-weight:600">购物篮分析</p><p>购物篮分析(Market Basket Analysis)是一种在零售业非常流行的技术,用于发现顾客购买产品之间的关联规则。</p><p style="font-size:19px;font-weight:600">输入和输出</p><li>输入: 一组交易数据,每一笔交易包含多个购买的商品。</li><li>输出: 满足最小支持度和最小置信度的关联规则。</li><p style="font-size:19px;font-weight:600">Python实现代码</p>
<MdPreview editorId="id2" :modelValue="message" :codeFoldable="false" theme="dark" />
</div>
</template>
</pop-model>
</template> </template>
<script setup> <script setup>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { MdPreview } from "md-editor-v3";
import "md-editor-v3/lib/preview.css";
import ecStat from 'echarts-stat'; import ecStat from 'echarts-stat';
import * as API from '@/api/AI.js' import * as API from '@/api/AI.js'
import { getUserInfo } from "@/utils/auth"; import { getUserInfo } from "@/utils/auth";
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import popModel from "@/views/components/popModal.vue";
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const dialogVisible=ref(false) const dialogVisible=ref(false)
const runResultShow=ref(false)
const tableLabel=reactive([ const tableLabel=reactive([
{prop:'date',label:''}, {prop:'date',label:''},
]) ])
const tableLabel2=reactive([ const tableLabel2=reactive([
{prop:'date',label:''}, {prop:'date',label:''},
]) ])
const message=ref('')
const getList=()=>{ const getList=()=>{
API.selectionMetrics({userId:JSON.parse(getUserInfo()).userId}).then((res)=>{ API.selectionMetrics({userId:JSON.parse(getUserInfo()).userId}).then((res)=>{
res.data.forEach(element => { res.data.forEach(element => {
@ -504,34 +513,3 @@ margin: 20px 20px 0;
} }
} }
</style> </style>
<style lang="scss">
.dialogClass{
background:url('../../../assets/images/弹框.png') !important;
background-size: 100% 100% !important;
.el-dialog__header{
padding: 5px 0px;
margin-right: 5px !important;
.gbImg{
cursor: pointer;
width: 51px;
height: 31px;
background-size: 100% 100%;
}
}
.xtImg{
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
span{
color: #FFFFFF;
padding: 38px 20px 0;
}
}
</style>

@ -1,5 +1,5 @@
<template> <template>
<div class="app-main"> <div class="app-main" v-loading="loading">
<div class="main-left"> <div class="main-left">
<div class="left-top"> <div class="left-top">
<img style="width: 26px; height: 26px" src="../../../assets/images/图标1.png" alt="" /> <img style="width: 26px; height: 26px" src="../../../assets/images/图标1.png" alt="" />
@ -15,14 +15,24 @@
<span>自建表</span> <span>自建表</span>
</div> </div>
<div class="left-item"> <div class="left-item">
<div v-for="(item, index) in zjData" :key="index" class="item" :class="{ 'is-active': zjIndex === index }" @click="goZJ(index)"> <div class="metrics">
<span>{{ item }}</span> <el-select v-model="n_dataTableQuery.selfTableName" placeholder="请选择数据" style="width: 180px" @change="selectType">
<el-option v-for="item in zjData" :key="item" :label="item" :value="item" />
</el-select>
</div>
</div> </div>
<div class="left-button">
<input type="file" ref="fileData" style="display: none" @change="importData" />
<el-button round type="primary" @click="$refs.fileData.click()">导入</el-button>
</div> </div>
</div> </div>
<div class="main-right"> <div class="main-right">
<el-table :data="tableData" style="width: 100%" :header-cell-style="headerCellStyle"> <el-table :data="tableData" style="width: 100%" :header-cell-style="headerCellStyle">
<el-table-column v-for="column in tableLabel" :key="column" :prop="column.prop" :label="column.label" align="center" /> <el-table-column v-for="column in tableLabel" :key="column" :prop="column.prop" :label="column.label" align="center">
<template #default="{ row }">
{{ formatDate(row[column.prop])?? '...' }}
</template>
</el-table-column>
</el-table> </el-table>
<pagination v-show="datatotal > 0" :total="datatotal" v-model:page="n_dataTableQuery.index" v-model:limit="n_dataTableQuery.size" @pagination="getSurface" style="margin-top: 10px" /> <pagination v-show="datatotal > 0" :total="datatotal" v-model:page="n_dataTableQuery.index" v-model:limit="n_dataTableQuery.size" @pagination="getSurface" style="margin-top: 10px" />
</div> </div>
@ -30,25 +40,30 @@
</template> </template>
<script setup> <script setup>
import * as portraitModel from "@/api/portraitModel"; import * as portraitModel from "@/api/portraitModel";
import * as marketingAlgorithmApi from "@/api/marketing-algorithm";
import { formatDate } from "@/utils/index.js";
import useUserStore from "@/store/modules/user"; import useUserStore from "@/store/modules/user";
import useAlgorithmStore from "@/store/modules/algorithm.js"; import useAlgorithmStore from "@/store/modules/algorithm.js";
import { ref } from "vue"; const { proxy } = getCurrentInstance();
import { getUserInfo } from "@/utils/auth";
const userInfo = JSON.parse(getUserInfo());
const loading = ref(false);
const fileData = ref(null);
const userStore = useUserStore(); const userStore = useUserStore();
const algorithmStore = useAlgorithmStore(); const algorithmStore = useAlgorithmStore();
// 数据表query // 数据表query
const n_dataTableQuery = ref({ const n_dataTableQuery = ref({
index: 1, index: 1,
size: 20, size: 7,
tableName: "用户属性表", tableName: "用户属性表",
userId: userStore.userInfo.userId, userId: userInfo.userId,
}); });
const datatotal = ref(0); const datatotal = ref(0);
const nzIndex = ref(0); const nzIndex = ref(0);
const nzData = ["用户属性表", "用户登录活跃表", "用户消费能力表", "用户行为表", "用户评论表"]; const nzData = ["用户属性表", "用户登录活跃表", "用户消费能力表", "用户行为表", "用户评论表"];
const zjIndex = ref(-1); const zjIndex = ref(-1);
const zjData = ["用户属性表", "用户登录活跃表", "用户消费能力表", "用户行为表", "用户评论表"]; const zjData = ref([]);
const tableLabel = reactive([ const tableLabel = ref([
{ prop: "id", label: "用户ID" }, { prop: "id", label: "用户ID" },
{ prop: "loginName", label: "登录名" }, { prop: "loginName", label: "登录名" },
{ prop: "userName", label: "用户姓名" }, { prop: "userName", label: "用户姓名" },
@ -62,10 +77,28 @@ const tableLabel = reactive([
{ prop: "updateTime", label: "注册时间" }, { prop: "updateTime", label: "注册时间" },
{ prop: "location", label: "所在地" }, { prop: "location", label: "所在地" },
]); ]);
const tableLabel2 = ref([]);
const arrhander = ref([]);
const arrhanderkey = ref([]);
const goNZ = (index, item) => { const goNZ = (index, item) => {
nzIndex.value = index; nzIndex.value = index;
zjIndex.value = -1; zjIndex.value = -1;
tableLabel.value = [
{ prop: "id", label: "用户ID" },
{ prop: "loginName", label: "登录名" },
{ prop: "userName", label: "用户姓名" },
{ prop: "studentId", label: "学号" },
{ prop: "stuClass", label: "班级" },
{ prop: "major", label: "专业" },
{ prop: "school", label: "学校" },
{ prop: "roleName", label: "角色名称" },
{ prop: "roleGender", label: "角色性别" },
{ prop: "roleAge", label: "角色年龄" },
{ prop: "updateTime", label: "注册时间" },
{ prop: "location", label: "所在地" },
];
n_dataTableQuery.value.tableName = item; n_dataTableQuery.value.tableName = item;
delete n_dataTableQuery.value.selfTableName;
getSurface(); getSurface();
}; };
const goZJ = (index) => { const goZJ = (index) => {
@ -73,22 +106,60 @@ const goZJ = (index) => {
nzIndex.value = -1; nzIndex.value = -1;
}; };
const tableData = ref([]); const tableData = ref([]);
const headerCellStyle = () => { const headerCellStyle = () => {
return { return {
color: "#ffffff !important", color: "#ffffff !important",
}; };
}; };
// 选择内置或自建 // 选择内置或自建
const selectType = (type) => {}; const selectType = (type) => {
delete n_dataTableQuery.value.tableName;
getSurface();
nzIndex.value = -1;
};
const getSurface = () => { const getSurface = () => {
portraitModel.getUserTableData(n_dataTableQuery.value).then((res) => { portraitModel.getUserTableData(n_dataTableQuery.value).then((res) => {
tableData.value = res?.data?.list; tableData.value = res?.data?.list;
datatotal.value = res.data.total; datatotal.value = res.data.total;
tableLabel2.value = [];
if (tableData.value[0]?.stepOneA) {
arrhander.value = JSON.parse(tableData.value[0].stepOneA);
arrhanderkey.value = Object.keys(tableData.value[0]).slice(2, arrhander.value.length + 2);
arrhander.value.forEach((item, index) => {
tableLabel2.value.push({
prop: arrhanderkey.value[index],
label: item,
});
});
tableLabel.value = tableLabel2.value;
}
});
};
// 导入
const importData = (e) => {
loading.value = true;
const files = e.target.files[0];
const formdata = new FormData();
formdata.append("file", files);
formdata.append("userId", userInfo.userId);
marketingAlgorithmApi.getMarketingAlgorithmImport(formdata).then((res) => {
loading.value = false;
proxy.$modal.msgSuccess("导入成功");
});
};
//选择自建表
const selectZJ = (item) => {
marketingAlgorithmApi.getMarketingAlgorithmTable();
};
// 查询自建下拉框
const getZJData = () => {
marketingAlgorithmApi.getMarketingAlgorithmTable({ userId: userInfo.userId }).then((res) => {
zjData.value = res?.data;
}); });
}; };
onMounted(() => { onMounted(() => {
getSurface(); getSurface();
getZJData();
}); });
</script> </script>
@ -135,6 +206,44 @@ onMounted(() => {
color: #ffffff; color: #ffffff;
} }
} }
.metrics {
padding: 0px 7px !important;
:deep(.el-input) {
.el-input__wrapper {
background-color: #ffffff00;
background-image: url("../../../assets/images/下拉框.png");
background-size: 100% 100%;
}
--el-input-text-color: #ffffff;
--el-input-border-color: #ffffff00;
--el-input-hover-border-color: #ffffff00;
--el-input-hover-border: #ffffff00;
--el-select-border-color-hover: #ffffff00;
--el-select-input-focus-border-color: #ffffff00;
--el-input-placeholder-color: #ffffff;
.el-input__inner {
color: #ffffff;
}
}
}
}
.left-button {
width: 195px;
height: 31px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
margin-top: 20px !important;
:deep(.el-button) {
width: 149px;
height: 48px;
background: url("../../../assets/images/确定.png");
color: #ffffff;
border-color: #ffffff00;
background-size: 100% 100%;
margin: 15px;
}
} }
} }
.main-right { .main-right {

@ -5,7 +5,7 @@
<p style="font-weight: 400;font-size: 12px;color: #E6E6E6;">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p> <p style="font-weight: 400;font-size: 12px;color: #E6E6E6;">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
</div> </div>
<div class="main-but"> <div class="main-but">
<el-button @click="runResultShow = true"><img src="../../../assets/images/导入.png" alt="">算法知识导入</el-button> <el-button @click="algorithmicKnowledge()"><img src="../../../assets/images/导入.png" alt="">算法知识导入</el-button>
<el-button @click="taskSubmit"><img src="../../../assets/images/提交.png" alt="">实训任务提交</el-button> <el-button @click="taskSubmit"><img src="../../../assets/images/提交.png" alt="">实训任务提交</el-button>
</div> </div>
<div class="app-main"> <div class="app-main">
@ -100,15 +100,15 @@
<el-table :data="tableData2" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350"> <el-table :data="tableData2" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350">
<el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/> <el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/>
</el-table> </el-table>
<el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> <!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
</div> </div>
<div class="analysisResults" style="margin-top: 20px"> <div class="analysisResults" style="margin-top: 20px">
<span style="font-weight: bold;font-size: 18px;color: #3596EB;display: block;">分析结果:</span> <span style="font-weight: bold;font-size: 18px;color: #3596EB;display: block;">分析结果:</span>
<el-button @click="upLoad">下载</el-button> <el-button @click="upLoad" v-if="showChart">下载</el-button>
<el-table :data="tableData3" row-key="TSuid" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350"> <el-table :data="tableData3" row-key="TSuid" style="width: 94%;margin-top:10px" :header-cell-style="headerCellStyle" height="350">
<el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/> <el-table-column v-for="column in tableLabel" :key="column.prop" :prop="column.prop" :label="column.label" align="center"/>
</el-table> </el-table>
<el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> <!-- <el-pagination style="margin-top:10px" background layout="prev, pager, next" :total="1000" /> -->
</div> </div>
<div style="margin-top:20px;gap:25px;display: flex;" v-show="showChart"> <div style="margin-top:20px;gap:25px;display: flex;" v-show="showChart">
<!-- <img src="../../../assets/images/图1.png" alt=""> --> <!-- <img src="../../../assets/images/图1.png" alt=""> -->
@ -176,23 +176,24 @@
<pop-model <pop-model
:showModel="runResultShow" :showModel="runResultShow"
title="运行结果" title="聚类分析"
@closePop="runResultShow = false" @closePop="runResultShow = false"
width="960"
@submit="runResultShow = false"
> >
<template v-slot:content> <template v-slot:content>
<div <div>
v-html=" <p style="font-weight: 700;font-size:22px">聚类分析的定义及原理</p><p style="font-size:19px">1.定义</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;所谓物以类聚、人以群分。聚类分析,即是基于研究对象的特征,将他们分门别类,以让同类别的个体之间差异相对小、相似度相对大,不同类别之间的个体差异大、相似度小。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;聚类分析是一种探索性分析方法,与判别分析不同,聚类分析事先并不知道分类的标准,甚至不知道应该分成几类,而是会根据样本数据的特征,自动进行分类。</p><img src="@/assets/images/f1001.png" />
`<p>0 &nbsp; &nbsp;23364</p><p>1 &nbsp; &nbsp; 6636</p><p >Name: default.payment.next.month, dtype: int64</p>` <p>聚类与分类的不同在于,聚类所要求划分的类是未知的</p><img src="@/assets/images/f1002.png" /><img src="@/assets/images/f1003.png" /><img src="@/assets/images/f1005.png" /><p style="font-size:19px">2.原理</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;假定研究对象均用所谓的“点”来表示。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在聚类分析中,一般的规则是将“距离”较小的点归为同一类,将“距离”较大的点归为不同的类。常见的是对个案分类,也可以对变量分类,但对于变量分类此时一般使用相似系数作为“距离”测量指标。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一般的规则:</p><img src="@/assets/images/f10010.png" /><br /><img src="@/assets/images/f10011.png" />
" <br /><img src="@/assets/images/f10012.png" /><p style="font-weight: 700;font-size:22px">聚类方法及其在SPSS中的实现</p><p style="font-size:19px">1.主要的聚类方法:</p><img src="@/assets/images/f10013.png" /><p style="font-size:19px">2.方法详解:</p><p style="font-size:17px">(1):K-means聚类</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;又称为快速聚类(K-Means Cluster),是在聚类的类别数已确定的情况下,快速将其他个案归类到相应的类别,适合大样本数据的聚类。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;具体步骤如下:</p><img src="@/assets/images/f10014.png" /><img src="@/assets/images/f10015.png" /><p>距离计算规则(欧几里得距离公式):</p><img src="@/assets/images/f10016.png" /><p>图解:</p><img src="@/assets/images/f10017.png" /><img src="@/assets/images/f10018.png" />
></div> <p>K-means的优缺点:<br />优势:<br /> (1)原理比较简单,实现也很容易,收敛速度快。<br /> (2)在对大规模数据集进行聚类分析时,算法聚类较高效且聚类效果较好。<br /> (3)簇与簇之间区别明显时,它的聚类效果很好。<br />不足:<br /> (1)分类数从初始分类开始就确定不变了,所以要求事先要对样本有足够的了解。<br />(2)仅限于个案间的聚类(Q型聚类),不能对变量进行聚类。<br /> (3)个案间的距离的测量方法使用的是欧式距离的平方,因此只能对连续变量进行聚类。<br />案例分析(SPSS):<br />通过查询整理出了2018年我国各省份的20项基本情况,根据这些指标把这31个省市或地区分成3类。</p><img src="@/assets/images/f10019.png" /><p> 分析步骤:分析>>分类>>K-均值聚类>>迭代>>次数>>选项>>勾选统计>>确认</p><img src="@/assets/images/f10020.png" /><img src="@/assets/images/f10021.png" /><p>结果分析:</p>
<img src="@/assets/images/f10022.png" /><img src="@/assets/images/f10023.png" /><p>若不收敛则调大迭代次数</p><img src="@/assets/images/f10024.png" /><p>方差分析表:</p><img src="@/assets/images/f10025.png" /><p> 其中聚类均方对应组间均方差,误差均方对应组内均方差,显著性p&lt;0.05时说明此变量分类效果好。由表可知,大部分变量的p&lt;0.05,且组间均方差大于组内均方差,说明各变量在三个类别中的差异大,分类结果可信度高。</p><img src="@/assets/images/f10026.png" /><br /><img src="@/assets/images/10027.png" /><p>聚类结果解读:</p>
<div class="table-box"><table cellspacing="0" style="width:355pt;"><tbody><tr><td style="text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第一类:</strong><strong>1</strong><strong>个省份(广东省,经济发达)</strong></p> </td></tr><tr><td style="background-color:#e7e7e7;text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第二类:</strong><strong>19</strong><strong>个省份(云南、西藏等地区,经济一般)</strong></p> </td></tr><tr><td style="text-align:center;vertical-align:middle;width:355pt;"> <p style="margin-left:0in;text-align:center;"><strong>第三类:</strong><strong>11</strong><strong>个省份(上海、北京等地区,经济较发达)</strong></p> </td></tr></tbody></table></div>
</div>
</template> </template>
</pop-model> </pop-model>
</template> </template>
<script setup> <script setup>
import popModel from "@/views/components/popModel.vue"; import popModel from "@/views/components/popModal.vue";
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import ecStat from 'echarts-stat'; import ecStat from 'echarts-stat';
import * as API from '@/api/AI.js' import * as API from '@/api/AI.js'
@ -204,6 +205,10 @@ const { proxy } = getCurrentInstance()
const tableLabel=reactive([ const tableLabel=reactive([
{prop:'date',label:''}, {prop:'date',label:''},
]) ])
const isFlag=ref(false)
const algorithmicKnowledge=()=>{
runResultShow.value = true
}
const getList=()=>{ const getList=()=>{
API.selectionMetrics({userId:JSON.parse(getUserInfo()).userId}).then((res)=>{ API.selectionMetrics({userId:JSON.parse(getUserInfo()).userId}).then((res)=>{
res.data.forEach(element => { res.data.forEach(element => {
@ -214,7 +219,6 @@ const { proxy } = getCurrentInstance()
}) })
}) })
} }
const showChart=ref(false)
const scrollbar = ref(null); const scrollbar = ref(null);
const fileList=ref([]) const fileList=ref([])
const handleChange=(info)=>{ const handleChange=(info)=>{
@ -394,6 +398,7 @@ const resTable2=ref()
} }
} }
const showChart=ref(false)
//生产表格 //生产表格
const nowData=ref([]) const nowData=ref([])
const computation=()=>{ const computation=()=>{
@ -474,22 +479,49 @@ const nowData=ref([])
} }
} }
const upLoad=()=>{ const upLoad=()=>{
const formData={ let formData=[
{
field:tableLabel.map(item=>item.label).join(','), field:tableLabel.map(item=>item.label).join(','),
lists:nowData.value camexports:[]
} }
// const formBody = Object.keys(formData) ]
// .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(formData[key])) nowData.value.forEach(item=>{
// .join('&'); item.forEach((item2,index)=>{
// fetch('http://192.168.2.28:9868/api/analysis/cAMExport', { item2.forEach((item3,index2)=>{
// method: 'POST', if (!formData[0].camexports[index]) {
// headers: { formData[0].camexports[index] = {}; // 如果不存在,则初始化为一个空对象
// 'Content-Type': 'application/x-www-form-urlencoded' }
// }, if(index2===0){
// body: formBody formData[0].camexports[index].fieldOne=item3
// }) }else if(index2===1){
API.downloadClusterAnalysisForm(formData).then(()=>{ formData[0].camexports[index].fieldTow=item3
}else if(index2===2){
formData[0].camexports[index].fieldThree=item3
}
})
})
})
API.downloadClusterAnalysisForm(formData).then((response)=>{
// 创建一个 Blob 对象
const blob = new Blob([response.data], { type: 'application/octet-stream' });
// 创建一个 URL 对象
const url = window.URL.createObjectURL(blob);
// 创建一个 <a> 标签并设置下载属性
const link = document.createElement('a');
link.href = url;
// 设置下载文件的默认名称
link.download = '聚类分析.xls';
// 触发点击事件,下载文件
document.body.appendChild(link);
link.click();
// 清理资源
window.URL.revokeObjectURL(url);
document.body.removeChild(link);
}) })
} }
const startOver=()=>{ const startOver=()=>{
@ -681,34 +713,3 @@ const nowData=ref([])
} }
} }
</style> </style>
<style lang="scss">
.dialogClass{
background:url('../../../assets/images/弹框.png') !important;
background-size: 100% 100% !important;
.el-dialog__header{
padding: 5px 0px;
margin-right: 5px !important;
.gbImg{
cursor: pointer;
width: 51px;
height: 31px;
background-size: 100% 100%;
}
}
.xtImg{
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
span{
color: #FFFFFF;
padding: 38px 20px 0;
}
}
</style>

@ -1,11 +1,11 @@
<template> <template>
<el-scrollbar height="800px"> <!-- <el-scrollbar height="800px" v-loading="loading"> -->
<div class="main-top"> <div class="main-top">
<span style="font-weight: bold; font-size: 18px; color: #3596eb">任务描述</span> <span style="font-weight: bold; font-size: 18px; color: #3596eb">任务描述</span>
<p style="font-weight: 400; font-size: 12px; color: #e6e6e6">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p> <p style="font-weight: 400; font-size: 12px; color: #e6e6e6">(给出任务清单参考,做哪些数据的统计分析)Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean euismod bibendum laoreet. Proin gravida dolor sit amet lacus accumsan et viverra justo commodo. Proin sodales pulvinar sic tempor. Sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam fermentum, nulla luctus pharetra vulputate, felis tellus mollis orci, sed rhoncus pronin sapien nunc accuan eget.</p>
</div> </div>
<div class="main-but"> <div class="main-but">
<el-button> <el-button @click="knowledgeImport">
<img src="../../../assets/images/导入.png" alt="" /> <img src="../../../assets/images/导入.png" alt="" />
算法知识导入 算法知识导入
</el-button> </el-button>
@ -21,12 +21,12 @@
<span>一、选择指标</span> <span>一、选择指标</span>
</div> </div>
<div class="metrics"> <div class="metrics">
<el-select v-model="input" placeholder="请选择数据" style="width: 180px" @change="selectType"> <el-select v-model="n_dataTableQuery.tableName" placeholder="请选择数据" style="width: 180px" @change="selectType">
<el-option v-for="item in algorithmStore.userDataLabel" :key="item" :label="item" :value="item" /> <el-option v-for="item in algorithmStore.userDataLabel" :key="item" :label="item" :value="item" />
</el-select> </el-select>
</div> </div>
<div class="metrics-table" style="margin-top: 10px"> <div class="metrics-table" style="margin-top: 10px">
<el-table border :data="algorithmStore.indexLibrary" style="width: 100%" :header-cell-style="headerCellStyle" @selection-change="handleSelectionChange"> <el-table border ref="multipleTableRef" :data="algorithmStore.indexLibrary" style="width: 100%" :header-cell-style="headerCellStyle" @selection-change="handleSelectionChange">
<el-table-column type="selection" prop="date" label="Date" align="center" /> <el-table-column type="selection" prop="date" label="Date" align="center" />
<el-table-column label="指标" align="center" prop="label" /> <el-table-column label="指标" align="center" prop="label" />
</el-table> </el-table>
@ -50,7 +50,7 @@
<span>三、模型参数设置</span> <span>三、模型参数设置</span>
</div> </div>
<div class="metrics-table" style="margin-top: 10px"> <div class="metrics-table" style="margin-top: 10px">
<el-table border :data="modelParams" style="width: 100%" :header-cell-style="headerCellStyle" @selection-change="handlemodelSelectionChange"> <el-table border ref="multipleTableRef" :data="modelParams" style="width: 100%" :header-cell-style="headerCellStyle" @selection-change="handlemodelSelectionChange">
<el-table-column type="selection" prop="date" label="Date" align="center" /> <el-table-column type="selection" prop="date" label="Date" align="center" />
<el-table-column prop="name" label="统计量" align="center" /> <el-table-column prop="name" label="统计量" align="center" />
</el-table> </el-table>
@ -58,7 +58,7 @@
</div> </div>
</div> </div>
<div style="margin-top: auto"> <div style="margin-top: auto">
<div class="startOver"> <div class="startOver" @click="restart">
<img src="../../../assets/images/重新开始.png" alt="" /> <img src="../../../assets/images/重新开始.png" alt="" />
<span>重新开始</span> <span>重新开始</span>
</div> </div>
@ -70,20 +70,19 @@
<el-table :data="analysisData" style="width: 100%; margin-top: 10px" :header-cell-style="headerCellStyle"> <el-table :data="analysisData" style="width: 100%; margin-top: 10px" :header-cell-style="headerCellStyle">
<el-table-column v-for="column in analysisHanderKry" :key="column" :prop="column" :label="column" align="center" /> <el-table-column v-for="column in analysisHanderKry" :key="column" :prop="column" :label="column" align="center" />
</el-table> </el-table>
<!-- <pagination v-show="datatotal > 0" :total="datatotal" v-model:page="dataqueryParams.index" v-model:limit="dataqueryParams.size" @pagination="submit" style="margin-top: 10px" /> --> <pagination v-show="n_analyzeTheNumberOfDataItems > 0" :total="n_analyzeTheNumberOfDataItems" v-model:page="n_dataTableQuery.index" v-model:limit="n_dataTableQuery.size" @pagination="analyzeDataNext" />
</div> </div>
<div class="analysisResults" style="margin-top: 20px"> <div class="analysisResults" style="margin-top: 20px">
<span style="font-weight: bold; font-size: 18px; color: #3596eb; display: block">分析结果:</span> <span style="font-weight: bold; font-size: 18px; color: #3596eb; display: block">分析结果:</span>
<el-button>下载</el-button> <el-button>下载</el-button>
<el-table :data="tableData" style="width: 94%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350"> <el-table :data="tableData" style="width: 100%; margin-top: 10px" :header-cell-style="headerCellStyle" height="350">
<el-table-column v-for="column in tableLabel" :key="column.label" :prop="column.label" :label="column.label" align="center"></el-table-column> <el-table-column v-for="column in tableLabel" :key="column.label" :prop="column.prop" :label="column.label" align="center"></el-table-column>
<p v-for="column in tableLabel" :key="column.label">{{ column.label }}</p>
</el-table> </el-table>
<el-pagination style="margin-top: 10px" background layout="prev, pager, next" :total="1000" /> <pagination v-show="nNumberOfAnalysisResults > 0" :total="nNumberOfAnalysisResults" v-model:page="gAnalysisResults.index" v-model:limit="gAnalysisResults.size" @pagination="updatePageAnalysisResults" />
</div> </div>
</div> </div>
</div> </div>
</el-scrollbar> <!-- </el-scrollbar> -->
<el-dialog v-model="dialogVisible" title="实训任务提交" width="565" custom-class="dialogClass" :show-close="false"> <el-dialog v-model="dialogVisible" title="实训任务提交" width="565" custom-class="dialogClass" :show-close="false">
<template #header="{ close, titleId, titleClass }"> <template #header="{ close, titleId, titleClass }">
<div class="my-header"> <div class="my-header">
@ -95,67 +94,95 @@
<div class="from-item"> <div class="from-item">
<el-form :inline="true" label-position="right" label-width="84px" :model="form" class="demo-form-inline"> <el-form :inline="true" label-position="right" label-width="84px" :model="form" class="demo-form-inline">
<el-form-item label="平均数:"> <el-form-item label="平均数:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.average" clearable />
</el-form-item> </el-form-item>
<el-form-item label="众数:"> <el-form-item label="众数:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.mode" clearable />
</el-form-item> </el-form-item>
<el-form-item label="中位数:"> <el-form-item label="中位数:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.median" clearable />
</el-form-item> </el-form-item>
<el-form-item label="标准差:"> <el-form-item label="标准差:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.standardDeviation" clearable />
</el-form-item> </el-form-item>
<el-form-item label="方差:"> <el-form-item label="方差:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.variance" clearable />
</el-form-item> </el-form-item>
<el-form-item label="峰度:"> <el-form-item label="峰度:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.kurtosis" clearable />
</el-form-item> </el-form-item>
<el-form-item label="标准误差:"> <el-form-item label="标准误差:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.standardError" clearable />
</el-form-item> </el-form-item>
<el-form-item label="偏度:"> <el-form-item label="偏度:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.skewness" clearable />
</el-form-item> </el-form-item>
<el-form-item label="最大值:"> <el-form-item label="最大值:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.max" clearable />
</el-form-item> </el-form-item>
<el-form-item label="最小值:"> <el-form-item label="最小值:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.min" clearable />
</el-form-item> </el-form-item>
<el-form-item label="求和:"> <el-form-item label="求和:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.summation" clearable />
</el-form-item> </el-form-item>
<el-form-item label="观测数:"> <el-form-item label="观测数:">
<el-input style="width: 120px" v-model="formInline.user" clearable /> <el-input style="width: 120px" v-model="formInline.observations" clearable />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="dialogVisible = false">确定</el-button> <el-button @click="submitTask">确定</el-button>
<el-button type="primary" @click="dialogVisible = false">返回</el-button> <el-button type="primary" @click="dialogVisible = false">返回</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
</template>
<el-dialog v-model="b_introductionOfAlgorithmKnowledge" title="算法知识导入" width="60%" :show-close="false">
<template #header="{ close, titleId, titleClass }">
<div class="my-header">
<span :id="titleId" :class="titleClass">实训任务提交</span>
<img class="gbImg" src="../../../assets/images/关闭.png" @click="close" alt="" />
</div>
<img class="xtImg" src="../../../assets/images/线条.png" alt="" />
</template>
<div class="from-item">
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="submitTask">确定</el-button>
<el-button type="primary" @click="dialogVisible = false">返回</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup> <script setup>
import * as portraitModel from "@/api/portraitModel";
import {paginate} from '@/utils/index.js'
import * as API from "@/api/AI.js"; import * as API from "@/api/AI.js";
import * as marketingAlgorithmApi from "@/api/marketing-algorithm.js"; import * as marketingAlgorithmApi from "@/api/marketing-algorithm.js";
import useAlgorithmStore from "@/store/modules/algorithm.js"; import useAlgorithmStore from "@/store/modules/algorithm.js";
import useUserStore from "@/store/modules/user"; import useUserStore from "@/store/modules/user";
import { onMounted, ref } from "vue"; import { getUserInfo } from "@/utils/auth";
const userInfo = JSON.parse(getUserInfo());
const loading = ref(false);
const { proxy } = getCurrentInstance();
const userStore = useUserStore(); const userStore = useUserStore();
const algorithmStore = useAlgorithmStore(); const algorithmStore = useAlgorithmStore();
const multipleTableRef = ref(null);
const b_introductionOfAlgorithmKnowledge = ref(false);
const n_dataTableQuery = ref({ const n_dataTableQuery = ref({
index: 1, index: 1,
size: 20, size: 5,
tableName: "用户属性表", tableName: "用户属性表",
userId: userStore.userInfo.userId, userId: userInfo.userId,
}); });
const gAnalysisResults=ref({
index: 1,
size: 5,
})
const dialogVisible = ref(false); const dialogVisible = ref(false);
// 模型参数 // 模型参数
const modelParams = reactive([ const modelParams = reactive([
@ -199,35 +226,60 @@ const modelParams = reactive([
const analysisData = ref([]); const analysisData = ref([]);
const analysisHanderKry = ref([]); const analysisHanderKry = ref([]);
const tableLabel = reactive([ const tableLabel = reactive([
{ prop: "date", label: "用户ID" }, { prop: "average", label: "平均数" },
{ prop: "name", label: "登录名" }, { prop: "median", label: "中位数" },
{ prop: "name", label: "用户姓名" }, { prop: "mode", label: "众数" },
{ prop: "name", label: "学号" }, { prop: "standardDeviation", label: "标准差" },
{ prop: "name", label: "班级" }, { prop: "variance", label: "方差" },
{ prop: "name", label: "专业" }, { prop: "standardError", label: "标准误差" },
{ prop: "name", label: "学校" }, { prop: "kurtosis", label: "峰度" },
{ prop: "name", label: "角色名称" }, { prop: "skewness", label: "偏度" },
{ prop: "name", label: "角色性别" }, { prop: "max", label: "最大值" },
{ prop: "name", label: "角色年龄" }, { prop: "min", label: "最小值" },
{ prop: "name", label: "注册时间" }, { prop: "summation", label: "求和" },
{ prop: "name", label: "所在地" }, { prop: "observations", label: "观测数" },
]); ]);
const formInline = ref({}); const formInline = ref({
average: "",
median: "",
mode: "",
standardDeviation: "",
variance: "",
standardError: "",
kurtosis: "",
skewness: "",
max: "",
min: "",
summation: "",
observations: "",
});
const input = ref(); const input = ref();
const g_indicatorData = ref([]); const g_indicatorData = ref([]);
const preProcessText = ref({ const preProcessText = ref({
text1: "数据去重", text1: "数据去重",
text2: "", text2: "",
}); });
// 分析数据
const n_analyzeTheNumberOfDataItems = ref(0);
const aAnalyzeTheRawData = ref([]);
//分析结果
const nNumberOfAnalysisResults=ref(0)
const aOriginalDataOfAnalysisResults=ref([])
// 模型参数 // 模型参数
const g_modelParameter = ref([]); const g_modelParameter = ref([]);
// 预处理 // 预处理
const preProcess = (tetx) => { const preProcess = (tetx) => {
if (analysisData.value.length == 0) {
proxy.$modal.msgWarning("请先选择指标进行数据分析!");
preProcessText.value.text2 = "";
}
API.dataPreprocessing({ API.dataPreprocessing({
mapList: analysisData.value, mapList: analysisData.value,
method: preProcessText.value.text2, method: preProcessText.value.text2,
userId: n_dataTableQuery.value.userId, userId: n_dataTableQuery.value.userId,
}).then((res) => { }).then((res) => {
proxy.$modal.msgSuccess("预处理成功");
analysisData.value = res.data; analysisData.value = res.data;
}); });
}; };
@ -235,28 +287,7 @@ const preProcess = (tetx) => {
const taskSubmit = () => { const taskSubmit = () => {
dialogVisible.value = true; dialogVisible.value = true;
}; };
const tableData = [ const tableData = ref([]);
{
date: "2016-05-03",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-02",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-04",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
{
date: "2016-05-01",
name: "Tom",
address: "No. 189, Grove St, Los Angeles",
},
];
const headerCellStyle = () => { const headerCellStyle = () => {
return { return {
backgroundColor: "#1882DE !important", // 设置表头背景颜色 backgroundColor: "#1882DE !important", // 设置表头背景颜色
@ -274,9 +305,16 @@ const handleSelectionChange = (type) => {
}; };
// 提交指標 // 提交指標
const submit = () => { const submit = () => {
if (g_indicatorData.value.length == 0) return proxy.$modal.msgWarning("请选择指标");
marketingAlgorithmApi.getMarketingAlgorithm({ userId: n_dataTableQuery.value.userId, tableName: n_dataTableQuery.value.tableName, fieldList: g_indicatorData.value }).then((res) => { marketingAlgorithmApi.getMarketingAlgorithm({ userId: n_dataTableQuery.value.userId, tableName: n_dataTableQuery.value.tableName, fieldList: g_indicatorData.value }).then((res) => {
analysisData.value = res.data; analysisData.value = res.data;
analysisHanderKry.value = Object.keys(res.data[0]); analysisHanderKry.value = Object.keys(res.data[0]);
if (res.data.length > 5) {
n_analyzeTheNumberOfDataItems.value = res.data.length;
aAnalyzeTheRawData.value = res.data;
analysisData.value = res.data.slice(0, 5);
}
proxy.$modal.msgSuccess("分析数据成功");
}); });
}; };
// 选择模型 // 选择模型
@ -285,8 +323,19 @@ const handlemodelSelectionChange = (type) => {
}; };
//计算 //计算
const modelCalculation = () => { const modelCalculation = () => {
if (analysisData.value.length == 0 && g_modelParameter.value.length == 0) {
proxy.$modal.msgWarning("请先分析数据/未选择模型参数!");
return;
}
const processedData = processArrayData(analysisHanderKry.value, analysisData.value); const processedData = processArrayData(analysisHanderKry.value, analysisData.value);
marketingAlgorithmApi.getMarketingAlgorithmPreprocessing(JSON.stringify({ map: processedData, statistic: g_modelParameter.value, userId: n_dataTableQuery.value.userId })); marketingAlgorithmApi.getMarketingAlgorithmPreprocessing(JSON.stringify({ map: processedData, statistic: g_modelParameter.value, userId: n_dataTableQuery.value.userId })).then((res) => {
tableData.value = res.data.map((item) => item.statistics);
if(res.data.length>5){
nNumberOfAnalysisResults.value=res.data.length
aOriginalDataOfAnalysisResults.value = res.data.map((item) => item.statistics)
tableData.value = res.data.map((item) => item.statistics).slice(0,5)
}
});
}; };
function processArrayData(keys, data) { function processArrayData(keys, data) {
// 创建结果对象 // 创建结果对象
@ -309,6 +358,65 @@ onMounted(() => {
const getIndicator = () => { const getIndicator = () => {
algorithmStore.getUserDatabase({ userId: n_dataTableQuery.value.userId, tableName: n_dataTableQuery.value.tableName }); algorithmStore.getUserDatabase({ userId: n_dataTableQuery.value.userId, tableName: n_dataTableQuery.value.tableName });
}; };
// 算法知识导入
const knowledgeImport = () => {
b_introductionOfAlgorithmKnowledge.value=true
};
// 实训任务提交
const submitTask = () => {
for (let key in formInline.value) {
if (formInline.value[key] == "") {
const label = tableLabel.find((item) => item.prop == key);
proxy.$modal.msgWarning(`${label.label}不能为空`);
return;
}
}
portraitModel
.submit({
userId: n_dataTableQuery.value.userId,
taskName: "描述性统计",
numberOfErrors: 0,
})
.then((res) => {
dialogVisible.value = false;
proxy.$modal.msgSuccess("提交成功");
});
};
// 重新开始
const restart = () => {
// 清空
formInline.value = {
average: "",
median: "",
mode: "",
standardDeviation: "",
variance: "",
standardError: "",
kurtosis: "",
skewness: "",
max: "",
min: "",
summation: "",
observations: "",
};
analysisData.value = [];
analysisHanderKry.value = [];
tableData.value = [];
g_indicatorData.value = [];
g_modelParameter.value = [];
preProcessText.value.text2 = "";
n_dataTableQuery.value.tableName = "用户属性表";
getIndicator();
proxy.$modal.msgSuccess("重新开始成功");
multipleTableRef.value.clearSelection();
};
//
const analyzeDataNext = () => {
analysisData.value =paginate(aAnalyzeTheRawData.value,n_dataTableQuery.value.index,n_dataTableQuery.value.size).data
};
const updatePageAnalysisResults=()=>{
tableData.value =paginate(aOriginalDataOfAnalysisResults.value,gAnalysisResults.value.index,gAnalysisResults.value.size).data
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -459,37 +567,3 @@ const getIndicator = () => {
margin-bottom: 20px; margin-bottom: 20px;
} }
</style> </style>
<style lang="scss">
.el-dialog {
background: url("../../../assets/images/弹框.png") !important;
background-size: 100% 100% !important;
.el-dialog__header {
padding: 5px 0px;
margin-right: 5px !important;
.gbImg {
cursor: pointer;
width: 51px;
height: 31px;
background-size: 100% 100%;
}
}
.xtImg {
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
span {
color: #ffffff;
padding: 38px 20px 0;
}
}
.el-table__body-wrapper {
// background: #020620 !important;
}
</style>

@ -645,34 +645,3 @@
} }
} }
</style> </style>
<style lang="scss">
.dialogClass{
background:url('../../../assets/images/弹框.png') !important;
background-size: 100% 100% !important;
.el-dialog__header{
padding: 5px 0px;
margin-right: 5px !important;
.gbImg{
cursor: pointer;
width: 51px;
height: 31px;
background-size: 100% 100%;
}
}
.xtImg{
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
span{
color: #FFFFFF;
padding: 38px 20px 0;
}
}
</style>

@ -41,6 +41,9 @@
img{ img{
margin-right: 5px; margin-right: 5px;
} }
.el-button{
padding-left: 49px !important;
}
.el-button:nth-child(1) { .el-button:nth-child(1) {
width: 170px; width: 170px;
height: 50px; height: 50px;
@ -87,7 +90,7 @@
background: url('../../assets/images/66.png'); background: url('../../assets/images/66.png');
color:#FFFFFF; color:#FFFFFF;
border-color:#FFFFFF00; border-color:#FFFFFF00;
padding:8px 5px 8px 30px; padding:8px 21px 8px 25px;
background-size: 100% 100%; background-size: 100% 100%;
} }
.el-button:nth-child(7) { .el-button:nth-child(7) {
@ -98,9 +101,9 @@
border-color:#FFFFFF00; border-color:#FFFFFF00;
padding:8px 5px 8px 20px; padding:8px 5px 8px 20px;
} }
// .active{ .active{
// background: url('../../assets/images/亮(钮).png'); background: url('../../assets/images/亮(钮).png');
// } }
} }
} }
</style> </style>

@ -55,7 +55,6 @@
}) })
const showResource=async(i)=>{ const showResource=async(i)=>{
console.log(i);
// const newWindow=window.open(`http://192.168.2.4:8800/api/stu/concept/block/getResource?`+`module=${data2.module}`+`&name=${i}`) // const newWindow=window.open(`http://192.168.2.4:8800/api/stu/concept/block/getResource?`+`module=${data2.module}`+`&name=${i}`)
// window.open(`http://qkljr.sztzjy.com:90/api/stu/concept/block/getResource?`+`module=${data2.module}`+`&name=${i}`) // window.open(`http://qkljr.sztzjy.com:90/api/stu/concept/block/getResource?`+`module=${data2.module}`+`&name=${i}`)
if(i.includes('mp4')){ if(i.includes('mp4')){

File diff suppressed because one or more lines are too long

@ -1,10 +1,10 @@
<template> <template>
<div class="content"> <div class="content">
<div class="import" @click="knowledgeFlag = !knowledgeFlag"> <div class="import" @click="dialogVisible = true">
<img src="@/assets/images/导入.png" alt="" /> <img src="@/assets/images/导入.png" alt="" />
<span>任务知识导入</span> <span>任务知识导入</span>
</div> </div>
<div v-if="knowledgeFlag"> <!-- <div v-if="knowledgeFlag">
<p> <p>
帕累托分析法源于经典的二八法则。意大利经济学家维尔弗雷多·帕累托于1906年提出了著名的关于意大利社会财务分配的研究结论:20%的人口掌握了80%的社会财富。这个结论对大多数国家的社会财富分配情况都成立。因此帕累托法则又被称为80/20法则。<br /><br /> 帕累托分析法源于经典的二八法则。意大利经济学家维尔弗雷多·帕累托于1906年提出了著名的关于意大利社会财务分配的研究结论:20%的人口掌握了80%的社会财富。这个结论对大多数国家的社会财富分配情况都成立。因此帕累托法则又被称为80/20法则。<br /><br />
帕累托分析的核心观点是:在许多情况下,大部分的问题、效益或成本都来自于少数的要素。换句话说,少数关键要素占据了绝大多数的结果。这一规律在许多领域都具有普适性,例如:<br /><br /> 帕累托分析的核心观点是:在许多情况下,大部分的问题、效益或成本都来自于少数的要素。换句话说,少数关键要素占据了绝大多数的结果。这一规律在许多领域都具有普适性,例如:<br /><br />
@ -17,8 +17,8 @@
</p> </p>
<img src="@/assets/images/u3323.png" alt="" /><br /> <img src="@/assets/images/u3323.png" alt="" /><br />
<img src="@/assets/images/u3324.png" alt="" /> <img src="@/assets/images/u3324.png" alt="" />
</div> </div> -->
<div v-if="!knowledgeFlag"> <div>
<div class="caseBack"> <div class="caseBack">
<div class="title"> <div class="title">
<img src="@/assets/images/caseIcon.png" alt="" /> <img src="@/assets/images/caseIcon.png" alt="" />
@ -344,13 +344,32 @@
</div> </div>
</div> </div>
</div> </div>
<pop-modal :showModel="dialogVisible" @closePop="dialogVisible = false">
<template v-slot:content>
<p>
帕累托分析法源于经典的二八法则。意大利经济学家维尔弗雷多·帕累托于1906年提出了著名的关于意大利社会财务分配的研究结论:20%的人口掌握了80%的社会财富。这个结论对大多数国家的社会财富分配情况都成立。因此帕累托法则又被称为80/20法则。<br /><br />
帕累托分析的核心观点是:在许多情况下,大部分的问题、效益或成本都来自于少数的要素。换句话说,少数关键要素占据了绝大多数的结果。这一规律在许多领域都具有普适性,例如:<br /><br />
在企业中,80%的利润可能来自于20%的产品或客户。<br />
在销售中,80%的销售额可能来自于20%的销售员或产品。<br />
在质量控制中,80%的缺陷可能来自于20%的原因或工序。<br /><br />
ABC 分类法全称应为 ABC 分类库存控制法。
又称帕累托分析法或巴雷托分析法、柏拉图分析、主次因分析法
、ABC分析法、ABC 管理法,平常也称之为「80 对 20」规则。
</p>
<img src="@/assets/images/u3323.png" alt="" /><br />
<img src="@/assets/images/u3324.png" alt="" />
</template>
</pop-modal>
</div> </div>
</template> </template>
<script setup> <script setup>
import popModal from "@/views/components/popModal.vue";
import { getUserInfo } from "@/utils/auth";
import * as portraitModel from "@/api/portraitModel"; import * as portraitModel from "@/api/portraitModel";
import { downBlobFile } from "@/utils/index.js"; import { downBlobFile } from "@/utils/index.js";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const dialogVisible = ref(false);
const knowledgeFlag = ref(false); const knowledgeFlag = ref(false);
const errorNum = ref(0); const errorNum = ref(0);
const step1Error = ref(0); const step1Error = ref(0);
@ -779,7 +798,7 @@ const saveData = () => {
}; };
portraitModel portraitModel
.saveData({ .saveData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "帕累托/ABC分析", module: "帕累托/ABC分析",
...params, ...params,
}) })
@ -789,7 +808,7 @@ const saveData = () => {
const getData = () => { const getData = () => {
portraitModel portraitModel
.getData({ .getData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "帕累托/ABC分析", module: "帕累托/ABC分析",
}) })
.then((res) => { .then((res) => {
@ -852,7 +871,7 @@ const submitData = () => {
console.log(errorNum.value, "总错误次数"); console.log(errorNum.value, "总错误次数");
portraitModel portraitModel
.submit({ .submit({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
taskName: "帕累托/ABC分析", taskName: "帕累托/ABC分析",
numberOfErrors: errorNum.value, numberOfErrors: errorNum.value,
}) })
@ -864,7 +883,7 @@ const submitData = () => {
const retrain = () => { const retrain = () => {
portraitModel portraitModel
.retrain({ .retrain({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "帕累托/ABC分析", module: "帕累托/ABC分析",
}) })
.then((res) => { .then((res) => {
@ -908,7 +927,7 @@ defineExpose({
font-weight: bold; font-weight: bold;
width: 180px; width: 180px;
height: 56px; height: 56px;
background-image: url("@/assets/images/01.png"); background-image: url("@/assets/images/taskImport.png");
background-size: 180px 56px; background-size: 180px 56px;
text-align: center; text-align: center;
align-items: center; align-items: center;

@ -1,11 +1,11 @@
<template> <template>
<div class="content"> <div class="content">
<div class="import" @click="knowledgeFlag = !knowledgeFlag"> <div class="import" @click="dialogVisible = true">
<img src="@/assets/images/导入.png" alt="" /> <img src="@/assets/images/导入.png" alt="" />
<span>任务知识导入</span> <span>任务知识导入</span>
</div> </div>
<div v-if="knowledgeFlag" v-html="knowledgeHtml"></div> <!-- <div v-if="knowledgeFlag" v-html="knowledgeHtml"></div> -->
<div v-if="!knowledgeFlag"> <div>
<div class="caseBack"> <div class="caseBack">
<div class="title"> <div class="title">
<img src="@/assets/images/caseIcon.png" alt="" /> <img src="@/assets/images/caseIcon.png" alt="" />
@ -277,10 +277,17 @@
</div> </div>
</div> </div>
</div> </div>
<pop-modal :showModel="dialogVisible" @closePop="dialogVisible = false">
<template v-slot:content>
<div v-html="knowledgeHtml"></div>
</template>
</pop-modal>
</div> </div>
</template> </template>
<script setup> <script setup>
import popModal from "@/views/components/popModal.vue";
import { getUserInfo } from "@/utils/auth";
import * as portraitModel from "@/api/portraitModel"; import * as portraitModel from "@/api/portraitModel";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { downBlobFile } from "@/utils/index.js"; import { downBlobFile } from "@/utils/index.js";
@ -292,6 +299,7 @@ const knowledgeHtml = ref(
const list = ref(["-"]); const list = ref(["-"]);
const combinationValue1 = ref(""); const combinationValue1 = ref("");
const combinationValue2 = ref(""); const combinationValue2 = ref("");
const dialogVisible = ref(false);
const knowledgeFlag = ref(false); const knowledgeFlag = ref(false);
const combinationRight = ref(["A—B", "A—C", "A—D", "B—C", "B—D", "C—D"]); const combinationRight = ref(["A—B", "A—C", "A—D", "B—C", "B—D", "C—D"]);
const step1Data = ref([ const step1Data = ref([
@ -768,7 +776,7 @@ const saveData = () => {
}; };
portraitModel portraitModel
.saveData({ .saveData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "购物篮分析", module: "购物篮分析",
...params, ...params,
}) })
@ -778,7 +786,7 @@ const saveData = () => {
const getData = () => { const getData = () => {
portraitModel portraitModel
.getData({ .getData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "购物篮分析", module: "购物篮分析",
}) })
.then((res) => { .then((res) => {
@ -851,7 +859,7 @@ const submitData = () => {
console.log(errorNum.value, "总错误次数"); console.log(errorNum.value, "总错误次数");
portraitModel portraitModel
.submit({ .submit({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
taskName: "购物篮分析", taskName: "购物篮分析",
numberOfErrors: errorNum.value, numberOfErrors: errorNum.value,
}) })
@ -864,7 +872,7 @@ const retrain = () => {
// console.log(66); // console.log(66);
portraitModel portraitModel
.retrain({ .retrain({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "购物篮分析", module: "购物篮分析",
}) })
.then((res) => { .then((res) => {
@ -912,7 +920,7 @@ defineExpose({
font-weight: bold; font-weight: bold;
width: 180px; width: 180px;
height: 56px; height: 56px;
background-image: url("@/assets/images/01.png"); background-image: url("@/assets/images/taskImport.png");
background-size: 180px 56px; background-size: 180px 56px;
text-align: center; text-align: center;
align-items: center; align-items: center;

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,11 +1,11 @@
<template> <template>
<div class="content"> <div class="content">
<div class="import" @click="knowledgeFlag = !knowledgeFlag"> <div class="import" @click="dialogVisible = true">
<img src="@/assets/images/导入.png" alt="" /> <img src="@/assets/images/导入.png" alt="" />
<span>任务知识导入</span> <span>任务知识导入</span>
</div> </div>
<div v-html="knowledge" v-if="knowledgeFlag"></div> <!-- <div v-html="knowledge" v-if="knowledgeFlag"></div> -->
<div v-if="!knowledgeFlag"> <div>
<div class="caseBack"> <div class="caseBack">
<div class="title"> <div class="title">
<img src="@/assets/images/caseIcon.png" alt="" /> <img src="@/assets/images/caseIcon.png" alt="" />
@ -93,7 +93,7 @@
<div style="margin-top: 10px; display: flex"> <div style="margin-top: 10px; display: flex">
<el-table <el-table
:data="step2Data" :data="step2Data"
style="width: 650px" style="width: 720px"
border border
:header-cell-style="{ :header-cell-style="{
color: '#fff', color: '#fff',
@ -105,7 +105,7 @@
</el-table-column> </el-table-column>
<el-table-column label="用户名称" align="center" prop="userName"> <el-table-column label="用户名称" align="center" prop="userName">
</el-table-column> </el-table-column>
<el-table-column label="最近一次消费时间间隔(R)" align="center"> <el-table-column label="最近一次消费时间间隔(R)" align="center" width="210">
<template #default="scope"> <template #default="scope">
<el-input <el-input
v-model="scope.row.params1" v-model="scope.row.params1"
@ -168,6 +168,7 @@
label="最近一次消费时间间隔(R)" label="最近一次消费时间间隔(R)"
align="center" align="center"
prop="data2" prop="data2"
width="210"
> >
</el-table-column> </el-table-column>
<el-table-column label="消费频率(F)" align="center" prop="data3"> <el-table-column label="消费频率(F)" align="center" prop="data3">
@ -189,7 +190,7 @@
<div style="margin-top: 10px; display: flex"> <div style="margin-top: 10px; display: flex">
<el-table <el-table
:data="step4Data" :data="step4Data"
style="width: 980px" style="width: 1080px"
border border
:header-cell-style="{ :header-cell-style="{
color: '#fff', color: '#fff',
@ -210,7 +211,7 @@
label="最近一次消费时间间隔(R)" label="最近一次消费时间间隔(R)"
align="center" align="center"
prop="data3" prop="data3"
width="150" width="210"
> >
</el-table-column> </el-table-column>
<el-table-column label="消费频率(F)" align="center" prop="data4"> <el-table-column label="消费频率(F)" align="center" prop="data4">
@ -511,13 +512,51 @@
</div> </div>
</div> </div>
</div> </div>
<el-dialog
v-model="dialogVisible"
title="任务知识导入"
style="width: 1108px; height: 798px"
custom-class="dialogClass"
:show-close="false"
class="dialog"
>
<template #header="{ close, titleId, titleClass }">
<div class="my-header">
<span :id="titleId" :class="titleClass">任务知识导入</span>
<img
class="gbImg"
src="../../../assets/images/关闭.png"
@click="close"
alt=""
/>
</div>
<img class="xtImg" src="../../../assets/images/线条.png" alt="" />
</template>
<div style="color:#fff;margin-top:-35px;padding:10px;padding-left:20px">
<el-scrollbar height="650px">
<div v-html="knowledge">
</div>
</el-scrollbar>
</div>
<!-- <template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">确定</el-button>
<el-button type="primary" @click="dialogVisible = false">
返回
</el-button>
</div>
</template> -->
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import { getUserInfo } from "@/utils/auth";
import * as portraitModel from "@/api/portraitModel"; import * as portraitModel from "@/api/portraitModel";
import { downBlobFile } from "@/utils/index.js"; import { downBlobFile } from "@/utils/index.js";
import { onBeforeUnmount, onMounted } from "vue"; import { onBeforeUnmount, onMounted } from "vue";
const dialogVisible = ref(false);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const errorNum = ref(0); //总错误次数 const errorNum = ref(0); //总错误次数
const stepError1 = ref(0); const stepError1 = ref(0);
@ -1067,7 +1106,7 @@ const submitData = () => {
console.log(errorNum.value, "总错误次数"); console.log(errorNum.value, "总错误次数");
portraitModel portraitModel
.submit({ .submit({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
taskName: "RFM分析", taskName: "RFM分析",
numberOfErrors: errorNum.value, numberOfErrors: errorNum.value,
}) })
@ -1121,7 +1160,7 @@ const saveData = () => {
}; };
portraitModel portraitModel
.saveData({ .saveData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "RFM分析", module: "RFM分析",
...params, ...params,
}) })
@ -1131,7 +1170,7 @@ const saveData = () => {
const getData = () => { const getData = () => {
portraitModel portraitModel
.getData({ .getData({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "RFM分析", module: "RFM分析",
}) })
.then((res) => { .then((res) => {
@ -1181,7 +1220,7 @@ const getData = () => {
const retrain = () => { const retrain = () => {
portraitModel portraitModel
.retrain({ .retrain({
userId: 492, userId: JSON.parse(getUserInfo()).userId,
module: "RFM分析", module: "RFM分析",
}) })
.then((res) => { .then((res) => {
@ -1243,7 +1282,7 @@ const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
font-weight: bold; font-weight: bold;
width: 180px; width: 180px;
height: 56px; height: 56px;
background-image: url("@/assets/images/01.png"); background-image: url("@/assets/images/taskImport.png");
background-size: 180px 56px; background-size: 180px 56px;
text-align: center; text-align: center;
align-items: center; align-items: center;
@ -1317,4 +1356,40 @@ const tableSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
background-color: #002652 !important; background-color: #002652 !important;
color: #fff; color: #fff;
} }
::v-deep .el-dialog {
background: url("../../../assets/images/弹框@2x.png") !important;
background-size: 1108px 798px !important;
.el-dialog__header {
padding: 5px 0px;
margin-right: 5px !important;
.gbImg {
cursor: pointer;
margin-top: 3px;
// margin-left: -30px;
width: 51px;
height: 35px;
background-size: 100% 100%;
}
}
.xtImg {
margin-left: 18px;
width: 530px;
}
}
.my-header {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 16px;
text-align: center;
margin-right: 9px;
margin-bottom: 0;
span {
color: #ffffff;
padding: 38px 20px 0;
margin-top: 10px;
margin-left: 20px;
}
}
</style> </style>

File diff suppressed because one or more lines are too long

@ -8,10 +8,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="btn" v-if="currentComponent">
<div class="submit" @click="submit">提交任务</div>
<div class="retrain" @click="retrain">重新实训</div>
</div>
<div class="container" v-if="menuIndex != 0"> <div class="container" v-if="menuIndex != 0">
<div class="leftContent"> <div class="leftContent">
<div class="title"> <div class="title">
@ -31,9 +28,9 @@
<el-menu-item index="4"> <el-menu-item index="4">
<span>用户行为表</span> <span>用户行为表</span>
</el-menu-item> </el-menu-item>
<el-menu-item index="5"> <!-- <el-menu-item index="5">
<span>用户评论表</span> <span>用户评论表</span>
</el-menu-item> </el-menu-item> -->
</el-menu> </el-menu>
</div> </div>
<div class="table"> <div class="table">
@ -47,18 +44,30 @@
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`, background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}" }"
> >
<el-table-column label="用户ID" align="center" prop="id"></el-table-column> <el-table-column label="用户ID" align="center" prop="userId">
<el-table-column label="登录名" align="center" prop="loginName"></el-table-column> </el-table-column>
<el-table-column label="用户姓名" align="center" prop="userName"></el-table-column> <el-table-column label="登录名" align="center" prop="loginName">
<el-table-column label="学号" align="center" prop="studentId"></el-table-column> </el-table-column>
<el-table-column label="班级" align="center" prop="stuClass"></el-table-column> <el-table-column label="用户姓名" align="center" prop="userName">
<el-table-column label="专业" align="center" prop="major"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="school"></el-table-column> <el-table-column label="学号" align="center" prop="studentId">
<el-table-column label="角色名称" align="center" prop="roleName"></el-table-column> </el-table-column>
<el-table-column label="角色性别" align="center" prop="roleGender"></el-table-column> <el-table-column label="班级" align="center" prop="stuClass">
<el-table-column label="角色年龄" align="center" prop="roleAge"></el-table-column> </el-table-column>
<el-table-column label="注册时间" align="center" prop="updateTime"></el-table-column> <el-table-column label="专业" align="center" prop="major">
<el-table-column label="所在地" align="center" prop="location"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="school">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="roleName">
</el-table-column>
<el-table-column label="角色性别" align="center" prop="roleGender">
</el-table-column>
<el-table-column label="角色年龄" align="center" prop="roleAge">
</el-table-column>
<el-table-column label="注册时间" align="center" prop="updateTime">
</el-table-column>
<el-table-column label="所在地" align="center" prop="location">
</el-table-column>
</el-table> </el-table>
<el-table <el-table
v-if="menuIndex == 2" v-if="menuIndex == 2"
@ -70,18 +79,30 @@
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`, background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}" }"
> >
<el-table-column label="用户ID" align="center" prop="a1"></el-table-column> <el-table-column label="用户ID" align="center" prop="userId">
<el-table-column label="登录名" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1"></el-table-column> <el-table-column label="登录名" align="center" prop="loginName">
<el-table-column label="学号" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="班级" align="center" prop="a1"></el-table-column> <el-table-column label="用户姓名" align="center" prop="userName">
<el-table-column label="专业" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="a1"></el-table-column> <el-table-column label="学号" align="center" prop="studentId">
<el-table-column label="角色名称" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="常登录地" align="center" prop="a1"></el-table-column> <el-table-column label="班级" align="center" prop="stuClass">
<el-table-column label="最近登录日期" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="登录频次" align="center" prop="a1"></el-table-column> <el-table-column label="专业" align="center" prop="major">
<el-table-column label="登录时长" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="school">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="roleName">
</el-table-column>
<el-table-column label="常登录地" align="center" prop="frequentLoginLocation">
</el-table-column>
<el-table-column label="最近登录日期" align="center" prop="lastLoginDate">
</el-table-column>
<el-table-column label="登录频次" align="center" prop="loginFrequency">
</el-table-column>
<el-table-column label="登录时长" align="center" prop="loginDuration">
</el-table-column>
</el-table> </el-table>
<el-table <el-table
v-if="menuIndex == 3" v-if="menuIndex == 3"
@ -93,21 +114,71 @@
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`, background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}" }"
> >
<el-table-column label="用户ID" align="center" prop="a1"></el-table-column> <el-table-column label="用户ID" align="center" prop="a1">
<el-table-column label="登录名" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1"></el-table-column> <el-table-column label="登录名" align="center" prop="a1">
<el-table-column label="学号" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="班级" align="center" prop="a1"></el-table-column> <el-table-column label="用户姓名" align="center" prop="a1">
<el-table-column label="专业" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="a1"></el-table-column> <el-table-column label="学号" align="center" prop="a1">
<el-table-column label="角色名称" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="消费商品小类" align="center" prop="a1" width="110"></el-table-column> <el-table-column label="班级" align="center" prop="a1">
<el-table-column label="消费商品类型" align="center" prop="a1" width="110"></el-table-column> </el-table-column>
<el-table-column label="累计消费金额" align="center" prop="a1" width="110"></el-table-column> <el-table-column label="专业" align="center" prop="a1">
<el-table-column label="累计消费次数" align="center" prop="a1" width="110"></el-table-column> </el-table-column>
<el-table-column label="近七天消费金额" align="center" prop="a1" width="130"></el-table-column> <el-table-column label="学校" align="center" prop="a1">
<el-table-column label="近七天消费次数" align="center" prop="a1" width="130"></el-table-column> </el-table-column>
<el-table-column label="最近消费时间" align="center" prop="a1" width="110"></el-table-column> <el-table-column label="角色名称" align="center" prop="a1">
</el-table-column>
<el-table-column
label="消费商品小类"
align="center"
prop="consumerGoods"
width="110"
>
</el-table-column>
<el-table-column
label="消费商品类型"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="累计消费金额"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="累计消费次数"
align="center"
prop="a1"
width="110"
>
</el-table-column>
<el-table-column
label="近七天消费金额"
align="center"
prop="a1"
width="130"
>
</el-table-column>
<el-table-column
label="近七天消费次数"
align="center"
prop="a1"
width="130"
>
</el-table-column>
<el-table-column
label="最近消费时间"
align="center"
prop="a1"
width="110"
>
</el-table-column>
</el-table> </el-table>
<el-table <el-table
v-if="menuIndex == 4" v-if="menuIndex == 4"
@ -119,23 +190,69 @@
background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`, background: `linear-gradient(0deg, #002651 0%, #0087F9 100%)`,
}" }"
> >
<el-table-column label="用户ID" align="center" prop="a1"></el-table-column> <el-table-column label="用户ID" align="center" prop="userId">
<el-table-column label="登录名" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="用户姓名" align="center" prop="a1"></el-table-column> <el-table-column label="登录名" align="center" prop="loginName">
<el-table-column label="学号" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="班级" align="center" prop="a1"></el-table-column> <el-table-column label="用户姓名" align="center" prop="userName">
<el-table-column label="专业" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="学校" align="center" prop="a1"></el-table-column> <el-table-column label="学号" align="center" prop="studentId">
<el-table-column label="角色名称" align="center" prop="a1"></el-table-column> </el-table-column>
<el-table-column label="商品名称" align="center" prop="a1" width="110"></el-table-column> <el-table-column label="班级" align="center" prop="stuClass">
<el-table-column label="商品小类" align="center" prop="a1" width="110"></el-table-column> </el-table-column>
<el-table-column label="商品类型" align="center" prop="a1" width="110"></el-table-column> <el-table-column label="专业" align="center" prop="major">
<el-table-column label="用户行为类型" align="center" prop="a1" width="110"></el-table-column> </el-table-column>
<el-table-column label="行为日期" align="center" prop="a1" width="130"></el-table-column> <el-table-column label="学校" align="center" prop="school">
</el-table-column>
<el-table-column label="角色名称" align="center" prop="roleName">
</el-table-column>
<el-table-column
label="商品名称"
align="center"
prop="goodsName"
width="110"
>
</el-table-column>
<el-table-column
label="商品小类"
align="center"
prop="goodsSubcategories"
width="110"
>
</el-table-column>
<el-table-column
label="商品类型"
align="center"
prop="goodsType"
width="110"
>
</el-table-column>
<el-table-column
label="用户行为类型"
align="center"
prop="userBehaviorType"
width="110"
>
</el-table-column>
<el-table-column
label="行为日期"
align="center"
prop="behaviorDate"
width="130"
>
</el-table-column>
</el-table> </el-table>
</div> </div>
</div> </div>
<main-content v-if="menuIndex == 0" :currentComponent="currentComponent" ref="contentRef"></main-content> <main-content
v-if="menuIndex == 0"
:currentComponent="currentComponent"
ref="contentRef"
></main-content>
<div class="btn" v-if="currentComponent">
<div class="submit" @click="submit">提交任务</div>
<div class="retrain" @click="retrain">重新实训</div>
</div>
</div> </div>
</template> </template>
@ -279,29 +396,33 @@ const retrain = () => {
color: #fff; color: #fff;
.tabList { .tabList {
// display: flex; // display: flex;
width: 1060px; // width: 1060px;
.tabs { .tabs {
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 12px;
margin-right: 20px; margin-right: 4px;
margin-bottom: 20px; margin-bottom: 20px;
width: 188px; width: 159px;
height: 61px; height: 56px;
background-image: url("@/assets/images/itembg1.png"); background-image: url("@/assets/images/itembg1.png");
background-size: 159px 56px;
// display: flex; // display: flex;
// justify-content: center; // justify-content: center;
// align-items: center; // align-items: center;
padding-left: 30px; padding-left: 15px;
line-height: 60px; line-height: 56px;
display: inline-block; display: inline-block;
img { img {
margin-right: 15px; margin-right: 5px;
} }
} }
.tabs:nth-of-type(2), .tabs:nth-of-type(2),
.tabs:nth-of-type(9) { .tabs:nth-of-type(9) {
background-image: url("@/assets/images/itembg2.png"); background-image: url("@/assets/images/itembg2.png");
} }
.tabs:nth-of-type(9) {
font-size: 11px;
}
.tabs:nth-of-type(3), .tabs:nth-of-type(3),
.tabs:nth-of-type(10) { .tabs:nth-of-type(10) {
background-image: url("@/assets/images/itembg3.png"); background-image: url("@/assets/images/itembg3.png");
@ -326,10 +447,13 @@ const retrain = () => {
} }
} }
.btn { .btn {
width: 220px;
margin: 0 auto;
display: flex; display: flex;
position: absolute; // position: absolute;
right: 70px; // right: 140px;
top: 110px; // bottom: 0px;
margin-top: 10px;
.submit { .submit {
width: 99px; width: 99px;
height: 31px; height: 31px;

Loading…
Cancel
Save