项目细节完善

This commit is contained in:
xiaozhang 2024-02-06 10:36:32 +08:00
commit 95a96dbbec
80 changed files with 7417 additions and 0 deletions

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.vscode
*.tsbuildinfo

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# vue3-etherealaquadance
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```

13
index.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>舞水云台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

8
jsconfig.json Normal file
View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

2549
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

30
package.json Normal file
View File

@ -0,0 +1,30 @@
{
"name": "vue3-etherealaquadance",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^0.27.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"element-plus": "^2.4.4",
"md5": "^2.3.0",
"mitt": "^3.0.1",
"qrcode": "^1.5.3",
"uuid": "^9.0.1",
"v-viewer": "^3.0.13",
"vue": "^3.3.11",
"vue-router": "^4.2.5",
"vue-viewer": "^1.0.4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.2",
"vite": "^5.0.10"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

11
src/App.vue Normal file
View File

@ -0,0 +1,11 @@
<template>
<div>
<RouterView />
</div>
</template>
<script lang="ts" setup>
</script>

147
src/assets/css/content.css Normal file
View File

@ -0,0 +1,147 @@
.button-container {
display: flex;
justify-content: center; /* 水平居中 */
}
.button-row{
width: 200px;
height: 60px;
}
.button-row-center{
width: 95%;
height: 100%;
box-shadow: 0px 2px 4px rgba(49, 49, 49, 0.2); /* 这里是阴影效果 */
font-size: 25px;
/* border: 3px solid rgba(47, 47, 47, 0.2); */
background-image: url('../../assets/headerBackgroungImg.png');
}
/*搜索 */
.input-select{
padding-top: 15px;
padding-bottom: 15px;
}
.input-select ::v-deep .el-input-group--append {
border: 1px solid rgba(138, 41, 36, 0.1);
box-shadow: 0px 2px 4px rgba(138, 41, 36, 0.2);
border-radius: 20px 0 0 20px;
}
.input-select ::v-deep .el-input__wrapper {
border-radius: 20px 0 0 20px;
}
.custom-border {
margin-bottom: 15px;
}
.custom-border ::v-deep .el-input__wrapper{
border-radius: 20px;
border: 1px solid rgba(138, 41, 36, 0.2);
box-shadow: 0px 2px 4px rgba(138, 41, 36, 0.2); /* 这里是阴影效果 */
}
.card {
margin-bottom: 40px;
margin-right: 40px;
position: relative;
border-radius: 20px 20px 5px 5px ;
}
.card-body{margin-left: 20px;}
.card:first-child {
margin-left: 20px; /* 调整第一个卡片的左边距 */
}
.card-header :hover{
cursor: pointer;
}
.card:hover{
box-shadow: 0px 2px 4px rgba(138, 41, 36, 0.8); /* 这里是阴影效果 */
}
.card-image {
width: 100%;
height: auto;
height: 280px; /* 调整图片高度 */
object-fit: cover; /* 保持图片比例并填充容器 */
border-radius: 20px 20px 0 0 ;
transition: transform 0.3s ease-in-out; /* 添加过渡效果 */
}
/* 当鼠标悬浮在包含图片的 .card 上时,图片会放大 */
.card:hover .card-image {
transform: scale(1.1); /* 放大比例例如设置为原尺寸的110% */
}
/* 设置 .card-header 为相对定位容器 */
.card-header {
position: relative;
text-align: center;
overflow: hidden; /* 隐藏超出的部分 */
}
/* 设置 ewm-image 的样式 */
.ewm-image img {
object-fit: cover; /* 确保图片适应容器尺寸而不变形 */
position: absolute;
bottom: 0;
right: 0;
width: 80px;
height: 80px
}
.card-description {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4em; /* 调整行高,确保两行文本完整显示 */
color:rgb(130, 125, 125);
font-size: 14px; /* 替换为你想要的字体大小 */
margin-top: 10px; /* 上边距,替换为你想要的值 */
margin-bottom: 10px; /* 下边距,替换为你想要的值 */
margin-right: 10px;
}
/* 使用绝对定位将 "收藏" 和 "浏览" 放置在右下角 */
.side-bar {
align-items: center; /* 垂直居中 */
display: flex;
justify-content: flex-end; /* 将内容靠右对齐 */
margin-right: 10px;
color: rgb(167, 167, 167);
}
/*弹窗*/
.grid-text-title{
text-align: center; /* 这会让图片的内联元素沿水平方向居中 */
font-size: 24px;
}
.grid-text-title-img{
width: 300px;
height: 300px;
object-fit: cover; /* 确保图片填满容器且保持宽高比 */
}
.grid-text-title-img-wenyang{
width: 80%;
height: 80%;
object-fit: cover; /* 确保图片填满容器且保持宽高比 */
}
.grid-text-title-img-wenyang img{
margin-left: 10%;
}
dialog-xiahuaxian{
border-bottom: 1px solid black; /* 添加一条黑色、1像素宽度的下边框 */
}
dialog-neirong{
}
dialog-goumai{
margin-top: 2%;
margin-left: 35%;
}

104
src/assets/css/header.css Normal file
View File

@ -0,0 +1,104 @@
/*
@author 罗佳鸿
@describe 这里的样式在首页关于物料领用成品入库页面的头部栏都进行了引用
*/
.header {
width: 100%;
height: 100px;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
padding: 10px;
color: #000000;
background-image: url(../../assets/headerBackgroungImg.png);
background-color: #8a2924;
z-index: 99;
}
.left,
.right {
display: flex;
align-items: center;
}
.icon {
margin-right: 10px;
cursor: pointer;
color: aliceblue;
font-size: 16px;
}
/* 首页头部栏,右侧的下拉框样式 */
.leftBox{
float: left;
display: flex;
justify-content: center;
align-items: center;
}
.titleOne {
display: flex;
justify-content: center;
align-items: center;
border-right: solid rgb(255, 255, 255,0.5) 1px;
width: 100px;
height: 60px;
margin: auto;
color: rgb(255, 255, 255);
cursor: pointer;
transition: background-color 0.3s ease;
font-weight: 600;
}
.titleTwo {
display: flex;
justify-content: center;
align-items: center;
border-right: solid rgb(255, 255, 255,0.5) 1px;
width: 60px;
height: 100px;
margin: auto;
color: white;
cursor: pointer;
font-weight: 200;
writing-mode: vertical-rl;
text-orientation: upright;
letter-spacing: 0.6em;
}
.titleThree {
display: flex;
justify-content: center;
align-items: center;
border-right: solid rgb(255, 255, 255,0.5) 1px;
width: 60px;
height: 100px;
margin: auto;
color: white;
cursor: pointer;
font-weight: 200;
writing-mode: vertical-rl;
text-orientation: upright;
letter-spacing: 0.2em;
}
.titleFour {
display: flex;
justify-content: center;
align-items: center;
border-right: solid rgb(255, 255, 255,0.5) 1px;
width: 60px;
height: 100px;
margin: auto;
color: white;
cursor: pointer;
font-weight: 200;
writing-mode: vertical-rl;
text-orientation: upright;
letter-spacing: 0.2em;
}
.dropdown {
float: left;
display: flex;
justify-content: center;
align-items: center;
}
.dropdown.show {
display: block;
}

BIN
src/assets/dy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
src/assets/gzh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

BIN
src/assets/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/image1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
src/assets/images/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
src/assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 449 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

BIN
src/assets/images/pic1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
src/assets/images/pic2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

1
src/assets/logo.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>

After

Width:  |  Height:  |  Size: 276 B

18
src/assets/main.css Normal file
View File

@ -0,0 +1,18 @@
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
margin: 0;
overflow: scroll; /* 允许滚动 */
}
body::-webkit-scrollbar {
width: 0; /* 隐藏滚动条 */
height: 0;
}
.router-link-exact-active, .router-link-active {
text-decoration: none !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/assets/pj.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

BIN
src/assets/pj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

BIN
src/assets/radio/123.mp4 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/背景2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

23
src/components/Viewer.vue Normal file
View File

@ -0,0 +1,23 @@
<template>
<Viewer :options="options" :images="images">
<template #default="scope">
<img v-for="src in scope.images" :key="src" :src="src" style="display: inline-block;width: 100%;height: 100%;">
</template>
</Viewer>
</template>
<script setup lang="ts">
import { component as Viewer } from 'v-viewer';
import 'viewerjs/dist/viewer.css'
//
const images: string[] = []
//
const options: object = {
// ,
button: true, //
navbar:false,//
title:false,// alt
toolbar:false //
}
</script>

344
src/components/dialog.vue Normal file
View File

@ -0,0 +1,344 @@
<template>
<!--弹窗-->
<el-dialog
v-model="dialogVisible"
width="95%"
destroy-on-close
center
style="font-weight: 400;"
>
<h1 style="text-align: center;margin-top: -40px;padding-bottom:10px; font-size: 30px;letter-spacing: 4px;" >{{titletxt}}</h1>
<hr>
<br><br>
<el-row>
<el-col :span="12" v-if="danganleixing == zuopinleixing.纹样">
<div class="grid-text-title">效果图</div>
<br />
<el-image
class="grid-text-title-img-wenyang"
:src="dialogImgUrl_xiaoguo"
fit="contain"
/>
<!-- <el-image style="width: 300px; height: 300px" :src="dialogImgUrl_xiaoguo" fit="contain" />-->
</el-col>
<el-col :span="6" v-if="danganleixing == zuopinleixing.作品">
<div class="grid-text-title">效果图</div>
<el-image
class="grid-text-title-img"
:src="dialogImgUrl_xiaoguo"
fit="contain"
/>
<!-- <el-image style="width: 300px; height: 300px" :src="dialogImgUrl_xiaoguo" fit="contain" />-->
</el-col>
<el-col v-if="danganleixing == zuopinleixing.作品" :span="6">
<div class="grid-text-title">纹样图</div>
<el-image
style="width: 300px; height: 300px"
:src="dialogImgUrl_wenyang"
fit="contain"
/>
<!--<el-image style="width: 300px; height: 300px" :src="dialogImgUrl_wenyang" fit="contain" />-->
</el-col>
<el-col :span="12">
<div style="padding-bottom: 5px;">
<el-row tag="dialog-xiahuaxian" :gutter="0">
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>时期</b><span>{{ shiqi }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>类型</b><span>{{ zpinleixing }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>地域</b><span>{{ diyu }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>材料类型</b><span>{{ cailiaoleixing }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>支系</b><span>{{ zhixi }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>刺绣工艺</b><span>{{ cixiugongyi }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样 && zhixi == qtzx"
><b>其它支系说明</b><span>{{ qitazhixishuoming }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>做工</b><span>{{ zuogong }}</span></el-text
>
</el-col>
</el-row>
</div>
<el-row tag="dialog-xiahuaxian">
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>民族</b><span>{{ minzu }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>绣娘</b><span>{{ xiuniang }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>种类</b><span>{{ zhonglei }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>绣娘级别</b><span>{{ xiuniangjibie }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.纹样"
><b>技法</b><span>{{ jifa }}</span></el-text
>
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>传承人级别</b><span>{{ chuanchengrenjibie }}</span></el-text
>
</el-col>
<el-col :span="6">
<el-text v-if="danganleixing == zuopinleixing.作品"
><b>设计师</b><span>{{ shejishi }}</span></el-text
>
</el-col>
</el-row>
<br />
<div class="box" style="width: 680px">
<el-col :span="24" style="min-height: 150px">
<h3 v-if="danganleixing == zuopinleixing.作品" style=" width: 100px;border-bottom: 1px solid black;padding-bottom: 10px;margin-bottom: 10px;letter-spacing:2px;">
<span style="font-size: 19px;"></span>品介绍
</h3>
<el-text
v-if="danganleixing == zuopinleixing.作品"
tag="dialog-neirong"
><p style="text-indent: 2em;line-height: 25px;font-weight: 400;">{{ neirong }}</p></el-text
>
<el-text
v-if="danganleixing == zuopinleixing.纹样"
tag="dialog-neirong"
><h3 style=" width: 100px;border-bottom: 1px solid black;padding-bottom: 10px;margin-bottom: 10px;letter-spacing:2px;"><span style="font-size: 19px;"></span>景故事</h3></el-text
>
<el-text
v-if="danganleixing == zuopinleixing.纹样"
tag="dialog-neirong"
><p style="text-indent: 2em;line-height: 25px;font-weight: 400;">{{ beijinggushi }}</p></el-text
>
<el-text
v-if="danganleixing == zuopinleixing.纹样"
tag="dialog-neirong"
><h3 style=" width: 100px;border-bottom: 1px solid black;padding-bottom: 10px;margin-bottom: 10px;letter-spacing:2px;"><span style="font-size: 19px;"></span>片说明</h3></el-text
>
<el-text
v-if="danganleixing == zuopinleixing.纹样"
tag="dialog-neirong"
><p style="text-indent: 2em;line-height: 25px;font-weight: 400;">{{ tupianshuoming }}</p></el-text
>
</el-col>
</div>
<br />
<el-row tag="dialog-xiahuaxian">
<el-col :span="24">   </el-col>
</el-row>
<el-row v-if="danganleixing == zuopinleixing.作品">
<el-col :span="24">
<div style="margin-left: 580px;">
<el-button
type="warning"
round
size="large"
tag="dialog-goumai"
@click="goumai"
>购买联系
</el-button>
</div>
</el-col>
</el-row>
<el-row v-else-if="danganleixing == zuopinleixing.纹样">
<el-col :span="12">
<el-row>
<el-col :span="12">
<b>矢量图</b><br />
<el-text>图形可以无限放大不变色不模糊</el-text>
</el-col>
<el-col :span="12">
<b>可无缝导入</b><br />
<el-text>PS/CAD/CDR/AI/ID/PDF······</el-text>
</el-col>
</el-row>
<br>
<el-button type="warning" round size="large" tag="dialog-goumai"
>下载矢量图</el-button
>
</el-col>
<el-col :span="12">
<el-row>
<el-col :span="12">
<b>  大图</b><br />
<el-text>  2954*2954px</el-text>
</el-col>
<el-col :span="12">
<b> </b><br />
<el-text>50*50cm150dpi<br /></el-text>
</el-col> </el-row
><br />
<br>
<el-button type="warning" round size="large" tag="dialog-goumai"
>下载原图</el-button
>
</el-col>
</el-row>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { onMounted, ref, toRefs } from "vue";
import { Calendar, Search } from "@element-plus/icons-vue";
import { ElMessageBox } from "element-plus";
import emitter from "@/util/emitter";
import { zuopinleixing, EnumCodeMap } from "@/util/Resource";
// props
const props = defineProps({
valueFromParent: String,
});
// setup使props.valueFromParent
const receivedValue = ref(props.valueFromParent);
//
let neirong = ref("");
//
const dialogVisible = ref(false);
let danganleixing = ref("");
/*
作品库
*/
let zpinleixing = ref("");
let cailiaoleixing = ref("");
let cixiugongyi = ref("");
let zuogong = ref("");
//let wenyangzhonglei=ref("")
let xiuniang = ref("");
let xiuniangjibie = ref("");
let chuanchengrenjibie = ref("");
let shejishi = ref("");
/**
* 纹样库
*/
let shiqi = ref("");
let diyu = ref("");
let zhixi = ref("");
let qitazhixishuoming = ref("");
let minzu = ref("");
let zhonglei = ref("");
let jifa = ref("");
let beijinggushi = ref("");
let tupianshuoming = ref("");
const qtzx = "其它支系";
//
const dialogImgUrl_xiaoguo = ref("");
const dialogImgUrl_wenyang = ref("");
//
let titletxt = ref(receivedValue.value);
//
const fits = ["contain"];
emitter.on("dialogV", (value) => {
dialogVisible.value = true;
const handleFilterDataArray = value[1];
for (const key in handleFilterDataArray) {
//
if (handleFilterDataArray[key]["id"] == value[0]) {
//
if (handleFilterDataArray[key]["danganleixing"] == zuopinleixing.作品) {
danganleixing.value = handleFilterDataArray[key]["danganleixing"];
titletxt.value = handleFilterDataArray[key]["mingcheng"];
neirong.value = handleFilterDataArray[key]["zuopinjieshao"];
dialogImgUrl_xiaoguo.value = handleFilterDataArray[key]["xiaoguotu"];
dialogImgUrl_wenyang.value =
handleFilterDataArray[key]["wenyangtupian"];
zpinleixing.value = "作品";
cailiaoleixing.value = EnumCode(
handleFilterDataArray[key]["cailiaoleixing"]
).join(",");
cixiugongyi.value = EnumCode(
handleFilterDataArray[key]["cixiugongyi"]
).join(",");
if (handleFilterDataArray[key]["zuogong"] == zuopinleixing.手工绣) {
zuogong.value = "手工绣";
} else {
zuogong.value = "机绣";
}
//wenyangzhonglei.value=EnumCode(handleFilterDataArray[key]['wenyangmingcheng'])
xiuniang.value = handleFilterDataArray[key]["xiuniangCode"];
xiuniangjibie.value = EnumCode(
handleFilterDataArray[key]["xiuniangjibie"]
).join(",");
chuanchengrenjibie.value = EnumCode(
handleFilterDataArray[key]["chuanchengrenjibie"]
).join(",");
shejishi.value = handleFilterDataArray[key]["shejishiCode"];
} else if (
handleFilterDataArray[key]["danganleixing"] == zuopinleixing.纹样
) {
danganleixing.value = handleFilterDataArray[key]["danganleixing"];
titletxt.value = handleFilterDataArray[key]["mingcheng"];
dialogImgUrl_xiaoguo.value =
handleFilterDataArray[key]["yuanshitupian"];
shiqi.value = handleFilterDataArray[key]["shiqi"];
diyu.value = handleFilterDataArray[key]["diyu"];
if (handleFilterDataArray[key]["zhixi"] == "QIANDONGNANZHIXI") {
zhixi.value = "黔东南支系";
} else if (handleFilterDataArray[key]["zhixi"] == "QITAZHIXI") {
zhixi.value = "其它支系";
qitazhixishuoming.value =
handleFilterDataArray[key]["qitazhixishuoming"];
}
minzu.value = EnumCodeMap.get(handleFilterDataArray[key]["minzu"]);
zhonglei.value = handleFilterDataArray[key]["zhonglei"];
jifa.value = EnumCodeMap.get(handleFilterDataArray[key]["jifa"]);
beijinggushi.value = handleFilterDataArray[key]["beijinggushi"];
tupianshuoming.value = handleFilterDataArray[key]["tupianshuoming"];
}
}
}
});
//
function EnumCode(value) {
//
const splitStr = value.split(",");
let str = ref([]);
for (const key in splitStr) {
str.value.push(EnumCodeMap.get(splitStr[key]));
}
return str.value;
}
function goumai() {
emitter.emit("goumai");
}
</script>
<style scoped>
.zuopingneirong {
}
/* @import "../assets/css/dialog.css"; */
</style>

68
src/components/footer.vue Normal file
View File

@ -0,0 +1,68 @@
<template>
<div class="footer">
<div class="left">
<p>联系人龙宇</p>
<p>联系电话15185614561</p>
<p> &nbsp &nbsp 1608101203@qq.com</p>
<p> &nbsp &nbsp 贵州省施秉县城关镇桃子湾工业园区</p>
<p>Copyright &copy; 2024 工诚云网技术支持.</p>
</div>
<div class="right">
<div class="social">
<img src="../assets/dy.png" alt="">
<p style="font-size: 12px;">抖音号</p>
</div>
<div class="social">
<img src="../assets/gzh.png" alt="">
<p style="font-size: 12px;">公众号</p>
</div>
</div>
</div>
</template>
<style scoped>
.footer {
/* height: 100px; */
background-image: url(../assets/headerBackgroungImg.png);
padding: 10px;
background-color:#8a2924; /* 底部背景颜色 */
color: #fff; /* 文字颜色 */
}
.footer {
overflow: hidden; /* 清除浮动 */
}
.footer .left {
float: left;
text-align: left;
}
.footer .right {
float: right;
text-align: right;
}
.right img{
width: 80px;
margin-right: 10px;
}
.left p {
font-size: 14px;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
}
.right {
display: flex;
}
.social {
display: flex;
flex-direction: column; /* 将子元素垂直排列 */
align-items: center;
margin-right: 20px; /* 可选:在社交图标之间添加间距 */
}
</style>

134
src/components/header.vue Normal file
View File

@ -0,0 +1,134 @@
<template>
<div>
<div class="header">
<div class="left">
<!-- 目录和搜索 -->
<!-- <el-icon color="white"><OfficeBuilding /></el-icon>
<div class="icon" @click="about" style="margin-left: 4px;">关于</div>
<el-icon color="white"><Guide /></el-icon>
<div class="icon" @click="pickingDetails" style="margin-left: 4px;">领料详情</div> -->
<div class="leftBox">
<div
class="titleOne"
@click="toggleDropdown"
@mousemove="changeBackgroundColorMove1()"
@mouseleave="changeBackgroundColorLeave1()"
:style="backgroundColor1"
>
目录<el-icon style="padding-left: 5px;"><ArrowRight /></el-icon>
</div>
<div class="dropdown" v-if="showDropdown">
<div
class="titleTwo"
@click="about()"
@mousemove="changeBackgroundColorMove2()"
@mouseleave="changeBackgroundColorLeave2()"
:style="backgroundColor2"
>
关于
</div>
<div
class="titleThree"
@click="pickingDetails()"
@mousemove="changeBackgroundColorMove3()"
@mouseleave="changeBackgroundColorLeave3()"
:style="backgroundColor3"
>
物料申请
</div>
<div
class="titleFour"
@click="finishedProduct()"
@mousemove="changeBackgroundColorMove4()"
@mouseleave="changeBackgroundColorLeave4()"
:style="backgroundColor4"
>
成品入库
</div>
</div>
</div>
</div>
<div class="center">
<img src="../assets/logo.png" style="width: 80px; height: 80px" :style="{'margin-left':leftWidth}" />
</div>
<div class="right">
<!-- 注册和登录 -->
<el-icon color="white"><Coin /></el-icon>
<div class="icon" @click="register">注册</div>
<el-icon color="white"><Check /></el-icon>
<div class="icon" @click="login">登录</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
clickNum:0,
leftWidth:'0px',
showDropdown: false,
backgroundColor1:'',
backgroundColor2:'',
backgroundColor3:'',
backgroundColor4:''
};
},
methods: {
changeBackgroundColorMove1(){
this.backgroundColor1 = 'background-color: black;'
},
changeBackgroundColorLeave1(){
this.backgroundColor1 = ''
},
changeBackgroundColorMove2(){
this.backgroundColor2 = 'background-color:black;'
},
changeBackgroundColorLeave2(){
this.backgroundColor2 = ''
},
changeBackgroundColorMove3(){
this.backgroundColor3 = 'background-color: black;'
},
changeBackgroundColorLeave3(){
this.backgroundColor3 = ''
},
changeBackgroundColorMove4(){
this.backgroundColor4 = 'background-color: black;'
},
changeBackgroundColorLeave4(){
this.backgroundColor4 = ''
},
toggleDropdown() {
this.showDropdown = !this.showDropdown;
this.clickNum++
if(this.clickNum%2 == 1){
this.leftWidth = '-130px'
}else{
this.leftWidth = '0px'
}
},
//
pickingDetails() {
this.$router.push({ name: "pickingDetails" });
},
login() {
this.$router.push({ name: "login" });
},
register() {
this.$router.push({ name: "register" });
},
about() {
this.$router.push({ name: "about" });
},
finishedProduct(){
this.$router.push({ name: "finishedProduct" });
}
},
};
</script>
<style scoped>
@import "../assets/css/header.css";
</style>

View File

@ -0,0 +1,101 @@
<template>
<el-row>
<el-col :span="6" :xs="{ span: 6 }" ></el-col>
<el-col :span="12" :xs="{ span: 12 }" >
<div class="input-select">
<el-input
v-model="inputSouSuo"
placeholder="搜索"
>
<template #append>
<el-button type="primary" :icon="Search" @click="search" />
</template>
</el-input>
</div>
</el-col>
<el-col :span="6" :xs="{ span: 6 }" ></el-col>
<el-col :span="6" :xs="{ span: 6 }" ></el-col>
<el-col :span="12" :xs="{ span: 12 }" >
<el-select class="custom-border"
v-model="options_value_minzu"
clearable
placeholder="民族"
style="width: 100px;"
@click="getoptions_minzu"
>
<el-option
v-for="item in options_minzu"
:key="item.value"
:label="item.label"
:value="item.value"
@click="xiala(options_value_minzu,'民族')"
/>
</el-select>
<el-select class="custom-border"
v-model="options_value_jifa"
clearable
placeholder="技法"
style="width: 100px;margin-left: 10px;"
@click="getoptions_jifa"
>
<el-option
v-for="items in options_jifa"
:key="items.value"
:label="items.label"
:value="items.value"
@click="xiala(options_value_jifa,'技法')"
/>
</el-select>
</el-col>
<el-col :span="6" :xs="{ span: 6 }" ></el-col>
</el-row>
</template>
<script setup lang="ts">
import { Search } from '@element-plus/icons-vue'
import { ref } from 'vue';
import {EnumCodeoPtionsMap} from '@/util/Resource'
import emitter from "@/util/emitter";
//
let inputSouSuo = ref('')
//
const options_value_minzu = ref('')
const options_value_jifa = ref('')
const options_minzu =ref([])
const options_jifa =ref([])
async function getoptions_minzu(){
const temp =EnumCodeoPtionsMap.get('民族')
for (const key in temp) {
options_minzu.value.push({value: temp[key],label: temp[key]})
}
}
async function getoptions_jifa(){
const temp =EnumCodeoPtionsMap.get('技法')
for (const key in temp) {
options_jifa.value.push({value: temp[key],label: temp[key]})
}
}
function xiala(value1,value2){
const data =[value1,value2]
//emit
emitter.emit('xiala',data)
}
//content
function search() {
const data =[inputSouSuo.value]
//emit
emitter.emit('sousuo',data)
}
</script>
<style scoped>
@import '@/assets/css/content.css';
</style>

View File

@ -0,0 +1,38 @@
<template>
<div class="box">
<a href="##"><div class="left"><img src="../../assets//images/master2.png" alt=""></div></a>
<a href="##"><div class="right"><img src="../../assets//images/master1.png" alt=""></div></a>
</div>
</template>
<script>
export default {
props:['v8MultipleImgPathList']
}
</script>
<style scoped>
.box {
border-radius: 10px;
background-color: #1f1f1f;
display: flex;
justify-content: center;
width: 100%;
height: 100%;
max-width: 1700px;
padding-left: 50px;
}
.box img{
width: 100%;
max-width: 850px;
}
.left {
cursor: pointer;
align-self: flex-start;
}
.right {
cursor: pointer;
align-self: flex-end;
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<div class="image-container">
<img src='../../assets/images/banner2.jpg' alt="Image" @mouseover="showBlur" @mouseout="hideBlur" style="500px" >
<div class="blur-layer" :class="{ active: isHover }">
<div class="text-wrapper">
<p class="title">
<!-- {{textTitle}} -->
绣彩生花璀璨艺术
</p>
<p></p>
<div class="textBox">
<!-- {{textValue}}
{{heightValue}} -->
细腻的针线穿梭宛若魔术般地勾勒出了一幅幅栩栩如生的图案
</div>
</div>
</div>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
// props: ['imgPath', 'textValue', 'textTitle','heightValue'],
setup(){
const isHover = ref(false)
function showBlur() {
isHover.value = true;
}
function hideBlur() {
isHover.value = false;
}
return{isHover,showBlur,hideBlur}
}
}
</script>
<style scoped>
.image-container {
position: relative;
display: inline-block;
}
.image-container img{
border-radius: 20px;
width: 100%;
max-width: 1700px;
}
.blur-layer {
border-radius: 10px;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 59, 59, 0.1);
backdrop-filter: blur(8px);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
/* text-align: center; */
}
.blur-layer.active {
opacity: 1;
}
.title {
font-weight: bold;
font-size: 20px;
margin-bottom: 10px;
}
.textBox{
width: 200px;
text-align: center;
color: white;
}
.text-wrapper p{
color: white;
text-align: center;
}
</style>

View File

@ -0,0 +1,88 @@
<template>
<div class="image-container">
<img src='../../assets/images/pic2.jpg' alt="Image" @mouseover="showBlur" @mouseout="hideBlur">
<div class="blur-layer" :class="{ active: isHover }">
<div class="text-wrapper">
<p class="title">
<!-- {{textTitle}} -->
欢迎
</p>
<p></p>
<div class="textBox">
欢迎致电舞水云台欢迎大家来探索苗绣的奇妙
<!-- {{textValue}}
{{heightValue}} -->
</div>
</div>
</div>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
// props: ['imgPath', 'textValue', 'textTitle','heightValue'],
setup(){
const isHover = ref(false)
function showBlur() {
isHover.value = true;
}
function hideBlur() {
isHover.value = false;
}
return{isHover,showBlur,hideBlur}
}
}
</script>
<style scoped>
.image-container {
position: relative;
display: inline-block;
height: 200px;
}
.image-container img{
/* height: 600px; */
border-radius: 20px;
width:100%;
max-width: 1700px;
}
.blur-layer {
border-radius: 10px;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 59, 59, 0.1);
backdrop-filter: blur(8px);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
/* text-align: center; */
}
.blur-layer.active {
opacity: 1;
}
.title {
font-weight: bold;
font-size: 20px;
margin-bottom: 10px;
}
.textBox{
width: 200px;
text-align: center;
color: white;
}
.text-wrapper p{
color: white;
text-align: center;
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<div class="image-container">
<img src='../../assets/images/banner1.jpg' alt="Image" @mouseover="showBlur" @mouseout="hideBlur" style="500px" >
<div class="blur-layer" :class="{ active: isHover }">
<div class="text-wrapper">
<p class="title">
<!-- {{textTitle}} -->
針織寶藏時尚温馨
</p>
<p></p>
<div class="textBox">
<!-- {{textValue}}
{{heightValue}} -->
這件針織作品彷彿從仙境中跳脫而出散發著一股溫暖和時尚的魅力
</div>
</div>
</div>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
// props: ['imgPath', 'textValue', 'textTitle','heightValue'],
setup(){
const isHover = ref(false)
function showBlur() {
isHover.value = true;
}
function hideBlur() {
isHover.value = false;
}
return{isHover,showBlur,hideBlur}
}
}
</script>
<style scoped>
.image-container {
position: relative;
display: inline-block;
}
.image-container img{
border-radius: 20px;
width: 100%;
max-width: 1700px;
}
.blur-layer {
border-radius: 10px;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 59, 59, 0.1);
backdrop-filter: blur(8px);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
/* text-align: center; */
}
.blur-layer.active {
opacity: 1;
}
.title {
font-weight: bold;
font-size: 20px;
margin-bottom: 10px;
}
.textBox{
width: 200px;
text-align: center;
color: white;
}
.text-wrapper p{
color: white;
text-align: center;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div>
<div class="header">
<div class="left">
<!-- 目录和搜索 -->
<!-- <el-icon color="#fee7aa"><Menu /></el-icon>
<div class="icon" @click="about">目录</div> -->
<el-page-header
@click="home()"
:icon="ArrowLeft"
title="返回"
style="color: rgb(255, 255, 255);"
>
<template #content></template>
</el-page-header>
</div>
<div class="center">
<!-- 中间的艺术字 -->
<img src="../../assets/logo.png" style="width: 80px; height: 80px ; margin-left: -27px;" />
</div>
<div class="right">
<!-- 注册和登录 -->
<el-icon color="white"><Coin /></el-icon>
<div class="icon" @click="register">注册</div>
<el-icon color="white"><Check /></el-icon>
<div class="icon" @click="login">登录</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
//
pickingDetails() {
this.$router.push({ name: "pickingDetails" });
},
login() {
this.$router.push({ name: "login" });
},
register() {
this.$router.push({ name: "register" });
},
about() {
this.$router.push({ name: "about" });
},
home() {
this.$router.push({ name: "home" });
}
},
};
</script>
<style scoped>
@import "../../assets/css/header.css";
</style>

View File

@ -0,0 +1,42 @@
<template>
<div class="demo-image__lazy">
<el-image v-for="url in urls" :key="url" :src="url" lazy />
</div>
</template>
<script lang="ts" setup>
const urls = [
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
]
</script>
<style scoped>
.demo-image__lazy {
height: 530px;
overflow-y: auto;
scrollbar-width: none;
-ms-overflow-style: none;
}
.demo-image__lazy::-webkit-scrollbar {
display: none;
}
.demo-image__lazy .el-image {
display: block;
min-height: 200px;
margin-bottom: 10px;
}
.demo-image__lazy .el-image:last-child {
margin-bottom: 0;
}
/* @media screen and (max-width: 1600px){
.demo-image__lazy {
height: 790px;
}
} */
</style>

View File

@ -0,0 +1,112 @@
<template>
<!-- {{screenHeight}}
{{screenWidth}} -->
<!-- {{AutoHeightValue}} -->
<el-carousel :interval="5000" :height="screenWidth>=1910?'470px':AutoHeightMethon" arrow="always" class="box">
<el-carousel-item v-for="item in 1" :key="item">
<div class="image-wrapper">
<img src="../../assets/images/person1.jpg" alt="">
</div>
</el-carousel-item>
<el-carousel-item v-for="item in 1" :key="item">
<div class="image-wrapper">
<img src="../../assets/images/person2.jpg" alt="">
</div>
</el-carousel-item>
<el-carousel-item v-for="item in 1" :key="item">
<div class="image-wrapper">
<img src="../../assets/images/person3.jpg" alt="">
</div>
</el-carousel-item>
<el-carousel-item v-for="item in 1" :key="item">
<div class="image-wrapper">
<img src="../../assets/images/person4.jpg" alt="">
</div>
</el-carousel-item>
</el-carousel>
</template>
<script>
import { computed,onMounted, onBeforeUnmount, ref } from 'vue';
export default {
setup() {
const screenWidth = ref(0)
const screenHeight = ref(0)
// const AutoHeightValue = ref('')
const AutoHeightMethon = computed(() => {
let heightValue = '';
if (1698 <= screenWidth.value && screenWidth.value < 1910 ) {
heightValue ="600px";
} else if (1528 <= screenWidth.value && screenWidth.value < 1698) {
heightValue = "700px";
} else if (1389 <= screenWidth.value && screenWidth.value < 1528) {
heightValue = "630px";
} else if (1222 <= screenWidth.value && screenWidth.value < 1389) {
heightValue = "550px";
} else if (1018 <= screenWidth.value && screenWidth.value < 1222) {
heightValue = "455px";
} else if(873 <= screenWidth.value && screenWidth.value <1018 ){
heightValue = "385px"
}else if(screenWidth.value <873){
heightValue = "460px"
}
return "470px";
});
const handleResize = () => {
getScreenSize()
}
const getScreenSize = () => {
screenWidth.value = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
screenHeight.value = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
onMounted(() => {
window.addEventListener('resize', handleResize)
getScreenSize()
})
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize)
})
return {
screenWidth,
screenHeight,
AutoHeightMethon
}
}
}
</script>
<style scoped>
.box{
/* border: solid 1px red; */
}
.image-wrapper img{
width: 100%;
}
.el-carousel__item .image-wrapper {
transition: transform 0.3s;
}
.el-carousel__item .image-wrapper:hover {
transform: scale(1.05);
}
.el-carousel__item h3 {
color: #ffffff;
opacity: 0.75;
line-height: 300px;
margin: 0;
text-align: center;
}
.el-carousel__item:nth-child(2n) {
background-color: #ffffff;
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #ffffff;
}
</style>

View File

@ -0,0 +1,39 @@
<template>
<el-carousel :interval="5000" arrow="always" height="360px" class="box">
<el-carousel-item v-for="item in 4" :key="item">
<!-- <h3 text="2xl" justify="center">{{ item }}</h3> -->
<img src="../../assets/images/2.jpg" alt="">
<img src="../../assets/images/2.jpg" alt="">
<img src="../../assets/images/2.jpg" alt="">
</el-carousel-item>
</el-carousel>
</template>
<style scoped>
.box{
width: 100%;
}
.el-carousel__item h3 {
color: #475669;
opacity: 0.75;
line-height: 300px;
margin: 0;
text-align: center;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #d3dce6;
}
@media screen and (max-width: 1700px){
.boxCapital{
width: 100%;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,46 @@
<template>
<div class="box">
<video class="video" src="../../assets/radio/123.mp4" autoplay muted></video>
<div class="describe">
<p class="title">艺术典藏</p>
<p>从工到艺从艺到术</p>
<p>让中国5000年文化幻化生机</p>
<el-button>查看更多</el-button>
</div>
</div>
</template>
<script>
export default{
}
</script>
<style scoped>
.box {
position: relative;
background-color: #f0f0f0;
}
.video {
width: 100%;
height: 100%;
object-fit: contain;
}
.describe {
position: absolute;
top: 35%; /* 调整垂直位置 */
right: 20%; /* 调整水平位置 */
color: white;
text-align: right;
}
.title {
font-size: 18px;
font-weight: bold;
margin-bottom: 10px;
}
.describe p {
margin: 0;
}
</style>

28
src/main.js Normal file
View File

@ -0,0 +1,28 @@
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import axios from 'axios'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(ElementPlus)
//全局配置axios
app.config.globalProperties.axios = axios;
app.use(router)
app.mount('#app')

20
src/router/index.js Normal file
View File

@ -0,0 +1,20 @@
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{ path: '/', name: 'home', component: () => import('../views/home.vue')},
{ path: '/content', name: 'content', component: () => import('../views/content.vue')},
{ path: '/storage', name: 'storage', component: () => import('../views/storage.vue')},
{ path: '/materials', name: 'materials', component: () => import('../views/materials.vue')},
{ path: '/dialog', name: 'dialog', component: () => import('../views/dialog.vue')},
{ path: '/images', name: 'images', component: () => import('../views/images.vue')},
{ path: '/about', name: 'about', component: () => import('../views/about.vue')},
{ path: '/login', name: 'login', component: () => import('../views/login.vue')},
{ path: '/register', name: 'register', component: () => import('../views/register.vue')},
{ path: '/pickingDetails', name: 'pickingDetails', component: () => import('../views/pickingDetails.vue')},
{ path: '/finishedProduct', name: 'finishedProduct', component: () => import('../views/finishedProduct.vue')},
]
})
export default router

View File

@ -0,0 +1,25 @@
// useQRCodeGenerator.js
//二维码生成器
import { ref, onMounted } from 'vue';
import qrcode from 'qrcode';
export default function useQRCodeGenerator(initialUrl) {
const qrCodeUrl = ref('');
onMounted(() => {
generateQRCode(initialUrl);
});
const generateQRCode = (url) => {
qrcode.toDataURL(url, (error, dataUrl) => {
if (error) {
console.error(error);
return;
}
qrCodeUrl.value = dataUrl;
});
};
return {
qrCodeUrl,
generateQRCode,
};
}

21
src/util/QRUtilHook.js Normal file
View File

@ -0,0 +1,21 @@
import { ref, onMounted } from 'vue';
import qrcode from 'qrcode';
function useQRCodeGenerator(url) {
const qrCodeUrl = ref(''); // 用于存储二维码的DataURL
const generateQRCode = () => {
qrcode.toDataURL(url, (error, dataUrl) => {
if (error) {
console.error(error);
return;
}
qrCodeUrl.value = dataUrl; // 将生成的二维码的数据URL保存到ref
});
};
onMounted(generateQRCode); // 在组件挂载时调用生成二维码的函数
return {
qrCodeUrl,
};
}

69
src/util/Resource.ts Normal file
View File

@ -0,0 +1,69 @@
//欧政铭
import { reactive } from 'vue'
//appKey
export const appKey="c7d9decc0ccb4b6da81a9f65aea29ed3";
//appSecret
export const appSecret="8299e69f17d943f59109a79d73e80da5";
//正式环境与开发环境正式为true
export const isEnvironment = false;
//文件请求头正式环境
export const serviceUrl="http://openapi-cop.qdniiot.com/";
//文件请求头开发环境
export const FserviceUrl="https://openapi-apaas.seeyonv8.com/";
//真实文件请求头地址正式环境
export const filiServiceUrl="http://cop.qdniiot.com/service/";
//真实文件请求头地址开发环境
export const FfiliServiceUrl="https://apaas.seeyonv8.com/service/";
//文件下载url
export const filiStorageKeyUrl="api/wushuiyuntai3071243142359302596/FileAppService/generateShareUrl";
// 请求头
export const headers = {
'Content-Type': 'application/json',
'app-key': appKey,
'sign-type': 'MD5',
'sign': '', // 先留空,稍后计算并填充
};
//纹案与作品分页查询接口url
export const wazpApiUrl="api/wushuiyuntai3071243142359302596/WenyangzuopinguanliAppServiceImpl/selectPageByConditions";
//作品分页查询接口url
//export const zuopingApiUrl="wushuiyuntai9146708742788827704/ZuopindanganAppServiceImpl/selectPageByConditions";
//人员档案查询接口url
export const renyuanApiUrl="api/wushuiyuntai3071243142359302596/Renyuandangan11AppServiceImpl/selectById";
//根据枚举ID和枚举值查询下级枚举项
export const EnumApiUrl="api/wushuiyuntai3071243142359302596/CtpEnumItemAppService/selectByEnumCodesAndAppId";
//搜索接口url
export const sousuoUrl="api/wushuiyuntai3071243142359302596/WenyangzuopinguanliAppServiceImpl/selectPageByComplexConditions";
//更新作品接口url
export const wazpApiUpdateUrl="apiwushuiyuntai3071243142359302596/WenyangzuopinguanliAppServiceImpl/update";
//实物与纹案(样品)
interface zuopingData{
id:number,
zuopinleixing:string,
wenyangtupian:string,
xiaoguotu:string,
zuogong:string,
zuopinjieshao:string,
zuopinmingcheng:string,
gongyibaojia:string
}
export enum zuopinleixing{
= "SHIWU",
="YANGPIN",
="SHOUGONGXIU",
="JIXIU",
="ZUOPIN",
="WENYANG"
}
//定义要查询的枚举codes
export const Enums=['wuliaoguanli','xiuniangzhichengjibie','minzu','jifa','xiuniangchuanchengrenjibie'];
//[id,name]
export const EnumCodeMap=reactive(new Map<string, any>());
export const EnumCodeoPtionsMap=reactive(new Map<string, any>());
export const EnumCodeoPtionsMapS=reactive(new Map<string, any>());

View File

@ -0,0 +1,34 @@
/**
* version:1.0
* author:luojiahong
* @description: 调用接口方法
* @apiUrl:接口地址
* @requestBody:请求体
* @returns:返回接口调出数据
*/
import axios from 'axios'
import {ref} from 'vue'
import { calculateSignature } from './md5Util';
export default function(){
async function callApi (apiUrl, requestBody) {
// console.log("方法调取成功")
try {
const headers = {
'Content-Type': 'application/json',
'app-key': 'c7d9decc0ccb4b6da81a9f65aea29ed3',
'sign-type': 'MD5',
'sign': '',
};
const appSecret = '8299e69f17d943f59109a79d73e80da5';
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
const response = await axios.post(apiUrl, requestBody, { headers });
return response.data;
}catch (error) {
console.error('调用接口发生错误:', error);
throw error;
}
}
return {callApi}
}

34
src/util/apiUtil.js Normal file
View File

@ -0,0 +1,34 @@
import { calculateSignature } from './md5Util';
export default {
methods: {
async callApi(apiEndpoint, requestBody) {
try {
// 请求头
const headers = {
'Content-Type': 'application/json',//输出的数据格式是json
'app-key': 'c7d9decc0ccb4b6da81a9f65aea29ed3',//appkey编码
'sign-type': 'MD5',//MD5进行格式
'sign': '', // 先留空,稍后计算并填充 数据加密
};
//加密认证
const appSecret = '8299e69f17d943f59109a79d73e80da5';
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
// 发送 POST 请求 请求接口 请求体 请求头
const response = await this.axios.post(apiEndpoint, requestBody, { headers });
// 处理返回的数据
return response.data;
} catch (error) {
// 处理错误
console.error('调用接口发生错误:', error);
//抛出数据异常结果
throw error;
}
},
//定义新的数据方方法对其方法调用
generateApiEndpoint() {
return 'https://openapi-apaas.seeyonv8.com/wushuiyuntai3071243142359302596/FileAppService/generateShareUrl';
},
},
};

7
src/util/emitter.ts Normal file
View File

@ -0,0 +1,7 @@
// 引入mitt
import mitt from "mitt";
// 创建emitter
const emitter = mitt()
// 创建并暴露mitt
export default emitter

368
src/util/indexApi.ts Normal file
View File

@ -0,0 +1,368 @@
//欧政铭
import { ref } from 'vue';
import axios from 'axios';
import { v4 as uuidv4 } from 'uuid';//需要安装npm install uuid
import { calculateSignature } from '@/util/md5Util'; // 修改为实际的路径
import {headers,appSecret, Enums, isEnvironment, renyuanApiUrl} from '@/util/Resource';
import {filiStorageKeyUrl,serviceUrl,FserviceUrl,
wazpApiUpdateUrl,filiServiceUrl,FfiliServiceUrl,EnumApiUrl,
EnumCodeMap,EnumCodeoPtionsMap,EnumCodeoPtionsMapS
} from '@/util/Resource';
//分页查询API 封装
/**
* @param leixing "{"danganleixing": "ZUOPIN"},如果是""
* @param pageNumber
* @param pageSize
* @param apiurl
* @param isEnvironment true为正式环境false为开发环境
*/
export async function selectApi(leixing,pageNumber,pageSize,apiurl){
//分割字符串leixing
// const split = leixing.split("-");
//随机32位请求流水号
const randomUUID = uuidv4();
let randomNum = randomUUID.substr(0, 32);
// 请求头headers在Resource.ts文件里面
//// 请求体部分参数
let requestBody =null;
let pageInfo =
{
//总记录数
"total": "0",
//是否需要查询总记录数
"needTotal": "true",
//当前页数
"pageNumber": pageNumber,
// 总页数
"pages": "0",
//每页记录数
"pageSize": pageSize
}
//判断 leixing的值
if(leixing !=""){
// 请求体
requestBody = {
requestId: randomNum,
timestamp: Date.now(),
"pageInfo":pageInfo,
//异步回调URL
"notifyUrl": "",
//排序
"sort": {
"orders": [
{
"property": "createTime",
"direction": "ASC"
}
]
},
// 条件
"params":leixing
};
}
else{
requestBody = {
requestId: randomNum,
timestamp: Date.now(),
pageInfo,
//异步回调URL
"notifyUrl": "",
//排序
"sort": {
"orders": [
{
"property": "createTime",
"direction": "ASC"
}
]
},
};
}
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
// 发送 POST 请求api/wushuiyuntai9146708742788827704/Renyuandangan11AppServiceImpl/selectById
//调用本地+serviceUrl
let response =null;
if(isEnvironment){
response = await axios.post(serviceUrl+apiurl, requestBody, { headers });
}else{
response = await axios.post(apiurl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const responseData = response.data;
//return parseJson( responseData['data']['content']);
return responseData;
}else{console.log(response.data);}
} catch (error) {
console.error('调用接口发生错误:', error);
}
}
//枚举查询接口
/**
*
* @param codes code
* @param apiurl url
* @param isEnvironment true
* @returns
*/
export async function selectEnumApi(codes,apiurl){
//随机32位请求流水号
const randomUUID = uuidv4();
let randomNum = randomUUID.substr(0, 32);
// 请求头headers在Resource.ts文件里面
// 请求体部分参数
let requestBody =null;
requestBody = {
requestId: randomNum,
timestamp: Date.now(),
//异步回调URL
"notifyUrl": "",
//排序
"sort": {
"orders": [
{
"property": "createTime",
"direction": "ASC"
}
]
},
// 条件
"params":{"enumCodes": [codes]}
};
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
// 发送 POST 请求api/wushuiyuntai9146708742788827704/Renyuandangan11AppServiceImpl/selectById
//调用本地+serviceUrl
let response =null;
if(isEnvironment){
response = await axios.post(serviceUrl+apiurl, requestBody, { headers });
}else{
response = await axios.post(apiurl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const responseData = response.data;
const temp1 =ref([])
const temp2 =ref([])
for (const key in responseData['data']['content']) {
//把得到的枚举存到map里面
EnumCodeMap.set(responseData['data']['content'][key]['id'],responseData['data']['content'][key]['name']);
//存给下拉选项用
if(responseData['data']['content'][key]['enumCode']=='minzu')
{
temp1.value.push(responseData['data']['content'][key]['name']);
EnumCodeoPtionsMapS.set(responseData['data']['content'][key]['name'],responseData['data']['content'][key]['id'])
}
if(responseData['data']['content'][key]['enumCode']=='jifa')
{
temp2.value.push(responseData['data']['content'][key]['name']);
EnumCodeoPtionsMapS.set(responseData['data']['content'][key]['name'],responseData['data']['content'][key]['id'])
}
}
if(codes=='minzu')
EnumCodeoPtionsMap.set('民族',temp1.value);
if(codes=='jifa')
EnumCodeoPtionsMap.set('技法',temp2.value);
//return parseJson( responseData['data']['content']);
return responseData;
}else{console.log('枚举',EnumCodeMap);}
} catch (error) {
console.error('调用枚举接口发生错误:', error);
}
}
/** id
* @param uid id
*/
export async function selectUserApi(uid){
//随机32位请求流水号
const randomUUID = uuidv4();
let randomNum = randomUUID.substr(0, 32);
// 请求体
const requestBody = {
requestId: randomNum,
timestamp: Date.now(),
"notifyUrl": "",
"data":uid
}
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
// 发送 POST 请求api
let response=null;
try {
if(isEnvironment){
response = await axios.post(serviceUrl+renyuanApiUrl, requestBody, { headers });
}else{
response = await axios.post(renyuanApiUrl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const responseData = response.data;
return responseData;
}
else{console.log(response.data);}
} catch (error) {
}
}
/** id
* @param data id{{"liulanliang":"123456"},{"id":"123456"}}
*/
export async function UP_WAZP_Api(data){
//随机32位请求流水号
const randomUUID = uuidv4();
let randomNum = randomUUID.substr(0, 32);
// 请求体
const requestBody = {
requestId: randomNum,
timestamp: Date.now(),
"notifyUrl": "",
"data":{"id":data[0],"liulanliang":data[1]}
}
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
// 发送 POST 请求api
let response=null;
try {
if(isEnvironment){
response = await axios.post(serviceUrl+wazpApiUpdateUrl, requestBody, { headers });
}else{
response = await axios.post(wazpApiUpdateUrl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const responseData = response.data;
console.log('gengx:',responseData)
return responseData;
}
else{console.log(response.data);}
} catch (error) {
}
}
//获取文件真实路径
/**
* @param StorageKeyUrl StorageKey
*/
export async function getFiliUrl(StorageKeyUrl){
if(StorageKeyUrl=="")
return null;
//随机32位请求流水号
const randomUUID = uuidv4();
let randomNum = randomUUID.substr(0, 32);
//字符串分割
const splitStr = StorageKeyUrl.split(",");
if(splitStr.length>1){
let arr=[];
for (const key in splitStr) {
// 请求体
const requestBody = {
requestId: randomNum,
timestamp: Date.now(),
data:splitStr[key]
}
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
// 发送 POST 请求api
let response=null;
if(isEnvironment){
response = await axios.post(serviceUrl+filiStorageKeyUrl, requestBody, { headers });
}else{
response = await axios.post(filiStorageKeyUrl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const {data} = response.data;
const {content} = data;
if(isEnvironment){
arr.push(filiServiceUrl+content);
}else
{
arr.push(FfiliServiceUrl+content);
}
}
} catch (error) {
console.error('文件调用接口发生错误1:', error);
}
}
//把arr数组转为字符串并返回
return arr.join(",");
}else{
// 请求体
const requestBody = {
requestId: randomNum,
timestamp: Date.now(),
data:splitStr[0]
}
// 计算 MD5 签名
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
let response=null;
// 发送 POST 请求api
if(isEnvironment){
response = await axios.post(serviceUrl+filiStorageKeyUrl, requestBody, { headers });
}else{
response = await axios.post(filiStorageKeyUrl, requestBody, { headers });
}
// 处理返回的数据
if(response.status === 200){
const {data} = response.data;
const {content} = data;
if(isEnvironment){return filiServiceUrl+content;}
else
{
return FfiliServiceUrl+content;
}
}
} catch (error) {
console.error('文件调用接口发生错误2:', error);
}
}
}
//解析JSON接口
/**
*
* @param arr1
* @param arr2
* @returns
*/
export function calculateUnion(arr1: string[], arr2: string[]): string[] {
arr1.push(...arr2);
return arr1.filter((item, index, arr) => arr.indexOf(item) === index);
}

13
src/util/md5Util.js Normal file
View File

@ -0,0 +1,13 @@
// md5Util.js
import CryptoJS from 'crypto-js';
// 计算 MD5 签名
export function calculateSignature(requestBody, appSecret) {
// 将请求体转换为 JSON 字符串
const requestBodyString = JSON.stringify(requestBody);
// 使用 CryptoJS 计算 MD5 签名
const signature = CryptoJS.MD5(appSecret + requestBodyString + appSecret).toString(CryptoJS.enc.Hex);
return signature;
}

143
src/views/about.vue Normal file
View File

@ -0,0 +1,143 @@
<template>
<div class="common-layout">
<el-container>
<el-header>
<headerComponet style="margin-left: -20px;"></headerComponet>
</el-header>
<video src="../assets/radio/舞水云台宣传片.mp4" autoplay muted style="width: 100%;height: 100%;" loop controls></video>
<el-main>
<div class="boxCapital">
<el-row :gutter="10">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24"><greatMaster :v8MultipleImgPathList="v8MultipleImgPathList"></greatMaster></el-col>
</el-row>
<el-row :gutter="10" style="margin-top: 5px;">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12"><groundGlassOne ></groundGlassOne></el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12"><groundGlassTwo ></groundGlassTwo></el-col>
</el-row>
<el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="12" :lg="8" :xl="8"><longPicture></longPicture></el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="16" :xl="16"><smallVideo></smallVideo></el-col>
</el-row>
<el-row :gutter="10">
<el-col :xs="24" :sm="8" :md="8" :lg="8" :xl="8"><slidingWindow></slidingWindow></el-col><br>
<el-col :xs="24" :sm="16" :md="16" :lg="16" :xl="16"><img src="../assets/images/pic1.png" alt="" style="width: 100%;"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="24"></el-col>
</el-row>
<el-row :gutter="10">
<el-col :xs="24" :sm="12" :md="16" :lg="16" :xl="16"><slidingWindowTow></slidingWindowTow></el-col>
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8"><groundGlassThree ></groundGlassThree></el-col>
</el-row>
</div>
</el-main>
<footerComponent></footerComponent>
</el-container>
</div>
</template>
<script setup>
import headerComponet from '../components/promotionalPageComponents/header.vue'
import greatMaster from '../components/promotionalPageComponents/greatMaster.vue'
import groundGlassOne from '../components/promotionalPageComponents/groundGlassOne.vue'
import slidingWindow from '../components/promotionalPageComponents/slidingWindow.vue'
import smallVideo from '../components/promotionalPageComponents/smallVideo.vue'
import longPicture from '../components/promotionalPageComponents/longPicture.vue'
import slidingWindowTow from '../components/promotionalPageComponents/slidingWindowTwo.vue'
import groundGlassThree from '../components/promotionalPageComponents/groundGlassThree.vue'
import groundGlassTwo from '../components/promotionalPageComponents/groundGlassTwo.vue'
import { onBeforeMount, reactive, ref } from 'vue';
import callApi from '../util/apiConnectHook'
import footerComponent from '../components/footer.vue'
/**
* @description [方法]通过宣传页名称调取v8宣传页数据目前仅能调取数据还无法使用
*/
let v8MultipleImgPathList = reactive([])
const V8Data = ref('');
const v8ImgPathObj = reactive({})
let v8TextObj = reactive({
maobolibiaotiyou:'',
maoboliwenbenyou:'',
maobolibiaotizuo:'',
maoboliwenbenzuo:'',
jingtaishipinbiaoti:'',
jingtaishipinwenben:'',
xuanchuantubiaoti:'',
xuanchuantuwenben:'',
})
onBeforeMount(async () => {
let apiConnectHook = callApi();
const url = "api/wushuiyuntai3071243142359302596/XuanchuanyemianAppServiceImpl/selectListByComplexConditions";
const body = {
"requestId": "1841793038809039082",
"params": {'xuanchuanyemingcheng':'开发人员使用数据'},
"timestamp": Date.now()
}
const promise = apiConnectHook.callApi(url, body);
await promise.then(responseData => {
const flyerData = responseData.data.content[0]
console.log("v8宣传页整体数据", flyerData);
v8TextObj = {
maobolibiaotiyou:flyerData.maobolibiaotiyou,
maoboliwenbenyou:flyerData.maoboliwenbenyou,
maobolibiaotizuo:flyerData.maobolibiaotizuo,
maoboliwenbenzuo:flyerData.maoboliwenbenzuo,
jingtaishipinbiaoti:flyerData.jingtaishipinbiaoti,
jingtaishipinwenben:flyerData.jingtaishipinwenben,
xuanchuantubiaoti:flyerData.xuanchuantubiaoti,
xuanchuantuwenben:flyerData.xuanchuantuwenben,
}
V8Data.value = flyerData;
const valueList = flyerData;
const pattern = /^\d+\/[a-zA-Z0-9\-]+\/\d+$/;
const regex = /\d+\/v8-seeyon-demo-private\/\d+,/;
Object.keys(valueList).forEach(key => {
if(regex.test(valueList[key])){
// console.log(key,'',valueList[key])
const imgPathList = valueList[key].split(",");
imgPathList.forEach(imgPath => {
let strMerge = "https://apaas.seeyonv8.com/service/"+imgPath
v8MultipleImgPathList.push(strMerge)
})
}
if (pattern.test(valueList[key])) {
console.log(key,"====",valueList[key])
const body2 = {
"data": valueList[key],
"requestId": "1841909510134825194",
"timestamp": Date.now()
}
const url2 = "api/wushuiyuntai3071243142359302596/FileAppService/generateShareUrl"
const promise2 = apiConnectHook.callApi(url2, body2)
promise2.then(responseData => {
const strMerge = "https://apaas.seeyonv8.com/service/"+responseData.data.content
v8ImgPathObj[key] = strMerge
});
}
});
});
});
setTimeout(()=>{
console.log("V8Data",V8Data)
console.log("")
},10000)
</script>
<style scoped>
.boxCapital{
/* display: flex; */
/* border: red solid 10px; */
width: 1000px;
margin: auto auto;
margin-top: -10px;
}
@media screen and (max-width: 1000px){
.boxCapital{
width: 100%;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<div class="common-layout">
<el-container>
<el-header>
<headerComponet/>
</el-header>
<el-main>
<div class="box">
<banner :bannerList = "bannerList"></banner>
<CompanyPrafile :introduceText="introduceText" :videoPath="videoPath"></CompanyPrafile>
<br>
<dataDisplay :titleTextOne="titleTextOne" :numOne="numOne" :titleTextTwo="titleTextTwo" :numTwo1="numTwo1" :numTwo2="numTwo2" :titleTextThree="titleTextThree" :numThree="numThree" :titleTextFour="titleTextFour" :numFour="numFour"></dataDisplay>
<br>
<excelllentWord :imgPathObj="imgPathObj"></excelllentWord>
<teamIntroduction :textValue="textValue" :videoUrl="videoUrl" ></teamIntroduction>
<br>
<photosOfPeople></photosOfPeople>
</div>
</el-main>
<el-footer height="100px">
<footerComponet></footerComponet>
</el-footer>
</el-container>
</div>
</template>
<script setup>
import {ref} from "vue"
import headerComponet from "../components/flyerComponents/header.vue"
import banner from "../components/flyerComponents/banner.vue"
import CompanyPrafile from "../components/flyerComponents/companyProfile.vue"
import dataDisplay from "../components/flyerComponents/dataDisplay.vue"
import excelllentWord from "../components/flyerComponents/excellentWork.vue"
import teamIntroduction from "../components/flyerComponents/teamIntroduction.vue"
import apiUtil from "../util/apiUtil"
import photosOfPeople from '../components/flyerComponents/photosOfPeople.vue'
import footerComponet from '../components/flyerComponents/footer.vue'
import header from "../components/flyerComponents/header.vue"
// banner
// let bannerList = ref(['src/assets/images/13.jpg','src/assets/images/10.jpg','src/assets/images/2.jpg'])
//
let introduceText = ref(`贵州省施秉县舞水云台旅游商品开发有限公司于2006年注册成立
位于贵州省施秉县城桃子湾园区是我省内集刺绣生产销售研发
培训非物质文化遗产传承旅游观光策划等为一体的民族品牌文化
企业`)
let videoPath = ref("src/assets/radio/舞水云台宣传片.mp4")
//
let titleTextOne = ref("客户累计量在全国超过")
let numOne = ref(8273)
let titleTextTwo = ref("高级刺绣师在全国占比")
let numTwo1 = ref(73)
let numTwo2 = ref(100)
let titleTextThree = ref("企业累计积年营业总额超过")
let numThree = ref(172800)
let titleTextFour = ref("企业绣娘人数累计超过")
let numFour = ref(162730)
//
let masterList = ref([
{
// imgUrl:'src/assets/images/p1.jpg',
name: '苹果派',
grade:'国家级',
tip:'刺绣是一门传承久远的技艺,每一个刺绣作品都是一份坚持与执着的体现'
},
{
// imgUrl:
// 'src/assets/images/p2.jpg',
name: '西瓜霜',
grade:'国家级',
tip:'刺绣是一门传承久远的技艺,每一个刺绣作品都是一份坚持与执着的体现'
},
{
// imgUrl:
// 'src/assets/images/p3.jpg',
name: '黄桃雾',
grade:'国家级',
tip:'刺绣是一门传承久远的技艺,每一个刺绣作品都是一份坚持与执着的体现'
},
{
// imgUrl:
// 'src/assets/images/p7.jpg',
name: '黄桃雾',
grade:'国家级',
tip:'刺绣是一门传承久远的技艺,每一个刺绣作品都是一份坚持与执着的体现'
},
{
// imgUrl:
// 'src/assets/images/p5.jpg',
name: '黄桃雾',
grade:'国家级',
tip:'刺绣是一门传承久远的技艺,每一个刺绣作品都是一份坚持与执着的体现'
}
])
//
// let imgPathObj = ref({
// img01:"src/assets/images/12.jpg",
// img02:"src/assets/images/11.jpg",
// img03:"src/assets/images/10.jpg",
// img04:"src/assets/images/9.jpg",
// img04:"src/assets/images/7.jpg",
// img04:"src/assets/images/6.jpg",
// })
//
let textValue = ref("用一针一线,实现乡村振兴”,舞水云台的初衷正在实现,一挑一串之间,绣娘手心的温度正在被传递,一件件绣品,就是带着各自故事的见证。")
// let videoUrl = ref("src/assets/radio/.mp4")
</script>
<style scoped>
/* 全局样式 */
common-layout {
overflow-x: hidden;
position: fixed;
width: 100%;
}
.box{
margin: auto auto;
width: 100%;
}
/* 排版样式 */
.common-layout header{
background-color: rgb(235, 235, 235);
}
.common-layout main{
background-color: white;
}
.common-layout footer{
background-color: rgb(234, 234, 234);
}
</style>

462
src/views/content.vue Normal file
View File

@ -0,0 +1,462 @@
<!--//-->
<template>
<!-- <video autoplay loop muted playsinline src="../assets/bj.mp4" style="width: 100%;object-fit: cover;"></video> -->
<div>
<div>
<div>
<div class="button-container">
<el-row :gutter="20" class="center-button-row">
<el-col :span="6" :xs="{ span: 12 }" class="button-row">
<el-button
color="#a02f23"
type="warning"
round
class="button-row-center"
@click="allcon"
plain
>全部</el-button
>
</el-col>
<el-col :span="6" :xs="{ span: 12 }" class="button-row">
<el-button
color="#a02f23"
type="warning"
round
class="button-row-center"
@click="zuopincon"
plain
>作品</el-button
>
</el-col>
<el-col :span="6" :xs="{ span: 12 }" class="button-row">
<el-button
color="#a02f23"
type="warning"
round
class="button-row-center"
@click="wenyangcon"
plain
>纹样</el-button
>
</el-col>
<el-col :span="6" :xs="{ span: 12 }" class="button-row">
<el-button
color="#a02f23"
type="warning"
round
class="button-row-center"
@click="chengmingzuocon"
plain
>成名作品</el-button
>
</el-col>
</el-row>
</div>
<!--搜索及筛选--->
<input_select />
</div>
<div>
<el-row>
<el-col :sm="6" v-for="item in handleFilterDataArray" :key="item.id">
<el-card class="card" :body-style="{ padding: '0px' }">
<div slot="header" class="card-header">
<img
v-if="item.danganleixing == zuopinleixing.作品"
:src="item.xiaoguotu"
alt="作品图片"
class="card-image"
@click="dialogV(item.id)"
/>
<img
v-else-if="item.danganleixing == zuopinleixing.纹样"
:src="item.yuanshitupian"
alt="作品图片"
class="card-image"
@click="dialogV(item.id)"
/>
</div>
<div class="card-body">
<h4>{{ item.mingcheng }}</h4>
<hr>
<el-row>
<el-col :span="18" v-if="item.chengmingzuo == true">
<p
v-if="item.danganleixing == zuopinleixing.作品"
class="card-description"
truncated
>
{{ item.zuopinjieshao }}
</p>
<p
v-else-if="item.danganleixing == zuopinleixing.纹样"
class="card-description"
truncated
>
{{ item.tupianshuoming }}
</p>
<!--<el-image v-if="item.chengmingzuo==true" :src="qrCodeUrl" :preview-src-list="srcList" alt="作品图片" class="ewm-image" :style="{ position: 'absolute', bottom: 0, right: 0, width: '80px', height: '80px' }"></el-image>-->
<Viewer
v-if="item.chengmingzuo == true"
class="ewm-image"
:images="srcList"
:style="{
position: 'absolute',
bottom: 0,
right: 0,
width: '80px',
height: '80px',
}"
/>
</el-col>
<el-col :span="24" v-else>
<p
v-if="item.danganleixing == zuopinleixing.作品"
class="card-description"
truncated
>
{{ item.zuopinjieshao }}
</p>
<p
v-else-if="item.danganleixing == zuopinleixing.纹样"
class="card-description"
truncated
>
{{ item.tupianshuoming }}
</p>
</el-col>
</el-row>
<p>
<span class="side-bar">
<el-icon><View /></el-icon>{{ item.liulanliang }}
</span>
</p>
</div>
</el-card>
</el-col>
</el-row>
<el-row>
<el-col :span="24" class="add" style="text-align: center"
><el-button type="primary" @click="addcon"
>加载更多</el-button
></el-col
>
</el-row>
</div>
</div>
</div>
<!--弹窗-->
<div><el_dialog /></div>
</template>
<script name="content" setup lang="ts">
import { onMounted, ref } from "vue";
import {
zuopinleixing,
wazpApiUrl,
EnumApiUrl,
Enums,
sousuoUrl,
EnumCodeoPtionsMapS,
} from "@/util/Resource";
import {
selectApi,
getFiliUrl,
selectEnumApi,
selectUserApi,
UP_WAZP_Api,
} from "@/util/indexApi";
import useQRCodeGenerator from "../util/QRCodeGenerator";
import el_dialog from "../components/dialog.vue";
import input_select from "@/components/input_select.vue";
import emitter from "@/util/emitter";
import Viewer from "@/components/Viewer.vue";
//
//let zuopingDataArray:zuopingData = {} as zuopingData;
// 使 ref
let zuopingDataArray = ref([]);
let wenyangDataArray = ref([]);
//
let handleFilterDataArray = ref([]);
//
let DataArray = ref([]);
let num = ref(8);
let onM = ref("全部");
let yenum = ref(1);
let Tsousuo = ref("");
let Txiala = ref("");
//
let srcList = ref([
"https://cdn.oozm.top/file/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20240115110846.png",
]);
//
const { qrCodeUrl } = useQRCodeGenerator("https://wsyt.guizhoujc.com/about");
//
function redirectToExternalLink() {
// 使 window.location.href
window.location.href = "brief";
}
//emit
function dialogV(id) {
const data = [id, handleFilterDataArray.value];
//emit
emitter.emit("dialogV", data);
//
//
const itemToUpdate = handleFilterDataArray.value.find(
(item) => item.id === id
);
if (itemToUpdate) {
const num = parseInt(itemToUpdate.liulanliang, 10) + 1;
itemToUpdate.liulanliang = num.toString(); // API
UP_WAZP_Api([id, num]); // API
}
}
//
onMounted(async () => {
//
for (const key in Enums) {
await selectEnumApi(Enums[key], EnumApiUrl);
}
//{"danganleixing": "WENYANG"}
//await getSelectApi({"and_like_mingcheng": ""},1,10,sousuoUrl);
await getSelectApi({ danganleixing: "ZUOPIN" }, 1, 10, wazpApiUrl);
await getSelectApi({ danganleixing: "WENYANG" }, 1, 10, wazpApiUrl);
});
/**
* 分页查询
* @param str 查询条件可""或者{"danganleixing": "WENYANG"}
* @param pageNumber 查询页数
* @param pageSize 每页的数量
* @param wazpApiUrl 纹案与作品分页查询接口url
*/
async function getSelectApi(str, pageNumber, pageSize, wazpApiUrl) {
try {
//
//let str =ref({"danganleixing": "WENYANG"});
const result = await selectApi(str, pageNumber, pageSize, wazpApiUrl);
console.log(result.data);
//
if (DataArray.value == "") {
// DataArray
DataArray.value = result.data.content;
} else {
//DataArray
// DataArrayDataArray
const uniqueItems = result.data.content.filter(
(item) => !DataArray.value.some((arrayItem) => arrayItem.id === item.id)
);
DataArray.value.push(...uniqueItems);
}
//
handleFilterDataArray.value = DataArray.value.slice(0, num.value);
//
wazpfenlei(result.data.content);
//
srcList.value = [qrCodeUrl.value];
} catch (error) {}
}
function startsWithHttpOrHttps(url) {
return /^https?:\/\//.test(url);
}
//
async function wazpfenlei(result) {
const getFiliUrlPromise = (url) =>
getFiliUrl(url).then((res) => res.split(",")[0]);
for (const item of result) {
const dataIndex = DataArray.value.findIndex((data) => data.id === item.id);
if (dataIndex !== -1) {
// xiaoguotu
if (!startsWithHttpOrHttps(DataArray.value[dataIndex]["xiaoguotu"])) {
DataArray.value[dataIndex]["xiaoguotu"] = item.xiaoguotu
? await getFiliUrlPromise(item.xiaoguotu)
: "";
}
// wenyangtupian
if (!startsWithHttpOrHttps(DataArray.value[dataIndex]["wenyangtupian"])) {
DataArray.value[dataIndex]["wenyangtupian"] = item.wenyangtupian
? await getFiliUrlPromise(item.wenyangtupian)
: "";
}
//
if (
item.danganleixing === zuopinleixing.作品 &&
item.xiuniangID &&
item.xiuniangID !== "0"
) {
const user = await selectUserApi(item.xiuniangID);
DataArray.value[dataIndex]["xiuniangCode"] =
user.data.content["xingming"];
}
if (
item.danganleixing === zuopinleixing.作品 &&
item.shejishiID &&
item.shejishiID !== "0"
) {
const user = await selectUserApi(item.shejishiID);
DataArray.value[dataIndex]["shejishiCode"] =
user.data.content["xingming"];
}
// yuanshitupian
if (item.danganleixing === zuopinleixing.纹样 && item.yuanshitupian) {
if (
!startsWithHttpOrHttps(DataArray.value[dataIndex]["yuanshitupian"])
) {
DataArray.value[dataIndex]["yuanshitupian"] = item.yuanshitupian
? await getFiliUrlPromise(item.yuanshitupian)
: "";
}
}
}
}
}
//
function wenyangcon() {
onM.value = "纹样";
num.value = 8;
const temp = ref([]);
for (const key in DataArray.value) {
if (DataArray.value[key].danganleixing == zuopinleixing.纹样) {
temp.value.push(DataArray.value[key]);
}
}
console.log("纹样:", temp.value);
handleFilterDataArray.value = temp.value.slice(0, num.value);
}
function zuopincon() {
onM.value = "作品";
num.value = 8;
const temp = ref([]);
for (const key in DataArray.value) {
if (DataArray.value[key].danganleixing === zuopinleixing.作品) {
temp.value.push(DataArray.value[key]);
}
}
handleFilterDataArray.value = temp.value.slice(0, num.value);
}
function chengmingzuocon() {
onM.value = "成名作品";
num.value = 8;
const temp = ref([]);
for (const key in DataArray.value) {
if (DataArray.value[key].chengmingzuo) {
temp.value.push(DataArray.value[key]);
}
}
handleFilterDataArray.value = temp.value.slice(0, num.value);
}
function allcon() {
onM.value = "全部";
num.value = 8;
handleFilterDataArray.value = DataArray.value.slice(0, num.value);
}
//
function addcon() {
let targetArray;
switch (onM.value) {
case "作品":
targetArray = DataArray.value.filter(
(item) => item.danganleixing === zuopinleixing.作品
);
break;
case "纹样":
targetArray = DataArray.value.filter(
(item) => item.danganleixing === zuopinleixing.纹样
);
break;
case "成名作品":
targetArray = DataArray.value.filter((item) => item.chengmingzuo == true);
break;
default:
targetArray = DataArray.value;
break;
}
const initialLength = targetArray.length;
const desiredLength = Math.ceil(initialLength / 4) * 4;
if (initialLength >= 8 || initialLength % 4 === 0) {
num.value += 4;
} else {
num.value += num.value % 4;
}
handleFilterDataArray.value = targetArray.slice(
0,
Math.min(desiredLength, num.value)
);
}
//
emitter.on("sousuo", async (value) => {
try {
await getSelectApi({ and_like_mingcheng: Tsousuo.value }, 1, 8, sousuoUrl);
handleFilterDataArray.value = DataArray.value
.filter((item) => item.mingcheng.includes(value[0]))
.slice(0, num.value);
console.log(
"搜索:",
DataArray.value.filter((item) => item.mingcheng.includes(value[0]))
);
} catch (error) {
console.error("搜索时发生错误:", error);
}
});
emitter.on("xiala", async (value) => {
try {
await filterAndSetData(value, sousuoUrl);
} catch (error) {
console.error("筛选数据时发生错误:", error);
}
});
async function filterAndSetData(value, sousuoUrl) {
let conditionKey;
let enumValue = EnumCodeoPtionsMapS.get(value[0]);
if (value[1] === "民族") {
conditionKey = "minzu";
await getSelectApi({ [conditionKey]: enumValue }, 1, 8, sousuoUrl);
} else if (value[1] === "技法") {
conditionKey = "jifa";
await getSelectApi({ [conditionKey]: enumValue }, 1, 8, sousuoUrl);
}
const filteredData = [];
for (const key in DataArray.value) {
if (DataArray.value[key][conditionKey] === enumValue) {
filteredData.push(DataArray.value[key]);
}
}
handleFilterDataArray.value = filteredData.slice(0, num.value);
}
</script>
<style scoped>
@import "@/assets/css/content.css";
</style>

154
src/views/dialog.vue Normal file
View File

@ -0,0 +1,154 @@
//
<template>
<div>
<div class="button-container">
<el-button type="primary" @click="openDialog" class="circle-button">
<el-icon size="32"><Headset /></el-icon>
</el-button>
</div>
<el-dialog v-model="dialogVisible" title="立即联系" :before-close="beforeDialogClose" style="width: 500px; height: auto;">
<div>
<el-card>
<div>
<h3>联系信息</h3><br>
</div>
<div>
<span>
公司名称贵州省施秉县舞水云台旅游商品开发有限公司<br>
&nbsp 贵州省施秉县城关镇桃子湾工业园区<br>
联系人龙宇<br>
联系电话15185614561<br>
Q Q邮箱1608101203@qq.com<br>
</span>
</div>
<br>
<p style="color: #f20000;">请输入您的联系方式我们会有专人联系您</p>
</el-card>
</div>
<el-main>
<el-form ref="form" :model="formData" label-width="80px" class="input-form">
<el-form-item label="姓名" prop="liuyanyonghuming" :rules="[{ required: true, message: '请输入生产人', trigger: 'blur' }]">
<el-input v-model="formData.liuyanyonghuming"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="lianxidianhua" :rules="[{ required: true, message: '请输入联系电话', trigger: 'blur' }]">
<el-input v-model="formData.lianxidianhua"></el-input>
</el-form-item>
<el-form-item label="留言内容" prop="liuyanneirong">
<el-input type="textarea" v-model="formData.liuyanneirong"></el-input>
</el-form-item>
<el-form-item class="i-button">
<el-button type="primary" @click="submitForm">发送</el-button>
</el-form-item>
</el-form>
</el-main>
</el-dialog>
</div>
</template>
<script>
import apiUtil from '../util/apiUtil';
import dayjs from 'dayjs';
import emitter from '@/util/emitter';
export default {
name: 'test',
mixins: [apiUtil],
data() {
return {
dialogVisible: false,
formData: {
liuyanyonghuming: '',
lianxidianhua: '',
liuyanneirong: '',
liuyanshijian: '',
},
};
},
methods: {
openDialog() {
this.dialogVisible = true;
},
beforeDialogClose(done) {
// Reset the form when the dialog is closed
this.resetForm();
done();
},
async submitForm() {
try {
await this.$refs.form.validate();
await this.fetchData();
//
this.dialogVisible = false;
this.$message.success('提交成功');
//
this.resetForm();
// console.log('', this.formData);
} catch (error) {
// console.log('', error);
this.$message.error('提交失败,请重试');
}
},
getCurrentTime() {
const currentTime = dayjs();
const formattedTime = currentTime.format('YYYY-MM-DD HH:mm:ss');
this.liuyanshijian = formattedTime;
},
async fetchData() {
const apiEndpoint =
'api/wushuiyuntai3071243142359302596/LiuyanguanliAppServiceImpl/create';
const requestBody = {
data: {
liuyanyonghuming: this.formData.liuyanyonghuming,
lianxidianhua: this.formData.lianxidianhua,
liuyanneirong: this.formData.liuyanneirong,
},
requestId: '1734240913900666688',
timestamp: Date.now(),
};
try {
const response = await this.callApi(apiEndpoint, requestBody);
// console.log(':', response);
} catch (error) {
console.error('发生错误:', error);
}
},
resetForm() {
//
Object.keys(this.formData).forEach((key) => {
this.formData[key] = '';
});
},
},
mounted() {
this.getCurrentTime();
emitter.on('goumai',()=>{
this.dialogVisible = true;
})
},
};
</script>
<style scoped>
.input-form {
max-width: 400px;
margin: 20px auto;
}
.button-container {
position: fixed;
right: 20px; /* 调整按钮离右边的距离 */
bottom: 120px; /* 调整按钮离底部的距离 */
display: flex;
align-items: center;
}
.circle-button {
border-radius: 50%; /* 将按钮设置为圆形 */
padding: 24px; /* 调整按钮内部图标的位置 */
background-color: #a02a24; /* 鼠标悬停时按钮背景颜色变为橙红色 */
}
.i-button {
position: fixed;
right: 48%;
}
</style>

View File

@ -0,0 +1,91 @@
<template>
<div class="common-layout">
<el-container>
<el-header><headerComponent></headerComponent></el-header>
<el-main><br>
<!-- <h1>扫码领料</h1><br>
<el-steps :active="active" finish-status="success">
<el-step title="扫描二维码" />
<el-step title="填写个人信息" />
<el-step title="填写物料领用信息" />
<el-step title="提交申请" />
</el-steps>
<div class="imgBox">
<img src="../assets/images/detailOne.png" alt="" class="detailOne"><br><br>
<img :src="qrCodeUrls[0].qrCodeUrl" alt="" class="QRImgOne">
</div>
<br><br><br> -->
<h1>扫码入库</h1><br>
<el-steps :active="active" finish-status="success">
<el-step title="扫描二维码" />
<el-step title="填写个人信息" />
<el-step title="填写成品信息" />
<el-step title="提交申请" />
</el-steps>
<div class="imgBox2">
<img src="../assets/images/detailTwo.png" alt="" class="detailTwo"><br><br>
<img :src="qrCodeUrls[1].qrCodeUrl" alt="" class="QRImgTwo">
</div>
</el-main>
</el-container>
<footerCompoent></footerCompoent>
</div>
</template>
<script setup>
import headerComponent from '../components/promotionalPageComponents/header.vue'
import footerCompoent from '../components/footer.vue'
import useQRCodeGenerator from '../util/QRCodeGenerator';
import { ref, onMounted } from 'vue'
const qrCodeUrls = ref([
useQRCodeGenerator('https://wsyt.guizhoujc.com/materials'),
useQRCodeGenerator('https://wsyt.guizhoujc.com/storage')
]);
onMounted(() => {
qrCodeUrls.value.forEach((generator) => {
generator.generateQRCode();
});
});
</script>
<style scoped>
.imgBox2 {
position: relative;
margin-top: 2rem;
}
.imgBox2 .detailTwo {
width: 100%;
border-radius: 20px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}
.imgBox2 .QRImgTwo {
width: 220px;
position: absolute;
top: 39%;
left: 18%;
z-index: 2;
}
.imgBox {
position: relative;
margin-top: 2rem;
}
.imgBox .detailOne {
width: 100%;
border-radius: 20px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}
.imgBox .QRImgOne {
width: 220px;
position: absolute;
top: 40%;
left: 4%;
z-index: 2;
}
</style>

56
src/views/home.vue Normal file
View File

@ -0,0 +1,56 @@
<template>
<div class="common-layout">
<video
autoplay
loop
muted
playsinline
src="../assets/radio/舞水云台宣传片1.mp4"
style="width: 100%; object-fit: cover"
></video>
<el-container>
<!-- 头部部分-->
<Header />
<!-- 内容部分 -->
<el-main class="contents">
<!-- 基础内容 -->
<div>
<Content />
</div>
<!-- 立即联系栏目 -->
<div>
<Dialog />
</div>
<!-- 下一栏展示内容 -->
<div></div>
</el-main>
<!-- 尾部部分 -->
<el-footer>
<Footer />
</el-footer>
</el-container>
</div>
</template>
<script lang="ts" setup name="home">
import Header from "../components/header.vue";
import Footer from "../components/footer.vue";
import Content from "./content.vue";
import Dialog from "./dialog.vue";
</script>
<style scoped>
.el-footer {
--el-footer-padding: 0 0px;
}
.contents {
background-image: url(../assets/mainBackgroundPic.png) ;
/* background-repeat: no-repeat; */
/* background-size: 100% 100%; */
}
</style>

39
src/views/images.vue Normal file
View File

@ -0,0 +1,39 @@
<template>
<div>
<div class="qr-code-container">
<img :src="qrCodeUrls[0].qrCodeUrl" class="custom-qr-code" />
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import useQRCodeGenerator from '../util/QRCodeGenerator';
const qrCodeUrls = ref([
useQRCodeGenerator('http://127.0.0.1/')
]);
onMounted(() => {
qrCodeUrls.value.forEach((generator) => {
generator.generateQRCode();
});
});
</script>
<style scoped>
.qr-code-container {
display: flex;
justify-content: center;
align-items: center;
height: 60vh;
}
.custom-qr-code {
border: 3px solid #2312c0;
border-radius: 10px;
box-shadow: 0 0 10px rgba(33, 33, 33, 0.3);
width: 200px;
height: 200px;
object-fit: cover;
cursor: pointer; /* 添加指针样式,表示可点击 */
}
</style>

215
src/views/login.vue Normal file
View File

@ -0,0 +1,215 @@
<template>
<div>
<!--头部标签 -->
<div class="header">
<img src="/src/assets/logo.png" alt="" style="width: 80px; height:80px; display: block;margin: 0 auto;" @click="forgotHome">
</div>
</div>
<!-- 登录表单的外层包裹容器 -->
<div class="login-wrap">
<div>
<!-- <Header /> -->
</div>
<!-- 登录表单 -->
<el-form class="login-container">
<!-- 标题 -->
<!-- <h1 class="title">用户登录</h1> -->
<img src="/src/assets/image.png" alt="" style="margin-bottom: 15px;">
<!-- 用户名输入框 -->
<el-form-item label="">
<el-input type="text" v-model="contact" placeholder="手机号" autocomplete="off"></el-input>
</el-form-item>
<!-- 密码输入框 -->
<el-form-item label="">
<el-input type="password" v-model="password" placeholder="密码" autocomplete="off"></el-input>
</el-form-item>
<!-- 登录按钮 -->
<el-form-item>
<el-button type="primary" @click="callApi" style="width: 100%;">登录</el-button>
</el-form-item>
<!-- 忘记密码和用户注册链接 -->
<el-row style="text-align: center;margin-top:-10px;">
<el-link type="primary" @click="forgotPassword()">忘记密码</el-link>
<el-link type="primary" @click="gotoRegister()" style="margin-left:59%">用户注册</el-link>
</el-row>
</el-form>
</div>
<FooterCompoent></FooterCompoent>
</template>
<script>
import axios from 'axios';
import { calculateSignature } from '../util/md5Util'; //
import Header from '../components/header.vue';
import FooterCompoent from '../components/footer.vue'
// cookie
document.cookie = "cookieName=cookieValue; expires=Wed, 30 Jun 2023 12:00:00 UTC; path=/";
export default {
components: {
//
// Header
FooterCompoent
},
name: 'Login',
data() {
return {
contact: '',
password: '' //
}
},
methods: {
forgotHome() {
// logo
// 使 Vue Router home
this.$router.push({ name: 'home' });
},
forgotPassword() {
//
// 使 Vue Router
this.$router.push({ name: 'content' });
},
gotoRegister() {
//
// 使 Vue Router
this.$router.push({ name: 'register' });
},
// API
async callApi() {
//
const headers = {
'Content-Type': 'application/json',
'app-key': 'c7d9decc0ccb4b6da81a9f65aea29ed3',
'sign-type': 'MD5',
'sign': '', //
};
const appSecret = '8299e69f17d943f59109a79d73e80da5';
//
const requestBody = {
"data": {
"mima": this.password,
"shoujihao": this.contact
},
"requestId": "1819824560967516370",
"timestamp": Date.now(),
"notifyUrl": "",
};
console.log(requestBody)
// MD5
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
// POST
const response = await axios.post('api/wushuiyuntai3071243142359302596/MicroFlowAppServiceImpl/loginIn', requestBody, { headers });
//
const responseData = response.data;
console.log('接口返回的数据:', responseData);
// true
// localStorage
localStorage.setItem('contact', JSON.stringify(this.contact));
// // localStorage
// mounted() {
// const user = JSON.parse(localStorage.getItem('contact'));
// if (user) {
// //
// } else {
// //
// }
// }
console.log(JSON.parse(localStorage.getItem('contact')));
console.log(responseData.data.content);
if (responseData.data.content == true) {
this.$message({
showClose: true,
message: '登录成功!',
type: 'success'
});
this.$router.push({
name: 'home',
params: {
username: this.contact,
password: this.password,
},
}
);
} else {
//false
this.$message({
showClose: true,
message: '用户名或密码错误!',
type: 'error'
});
}
// this.gotoLogin();
} catch (error) {
console.error('调用接口发生错误:', error);
}
},
}
}
</script>
<style scoped>
/* 样式 */
.header {
width: 100%;
height: 100px;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
padding: 10px;
/*border-bottom: 1px solid #ddd; /* 根据实际情况设置头部底边框 */
transition: background-color 0.3s ease; /* 添加过渡效果 */
color: #000000; /* 文字颜色 */
background-image:url(../assets/headerBackgroungImg.png);
background-color: #8a2924;
z-index: 99;
}
.login-wrap {
box-sizing: border-box;
width: 100%;
height: 100vh;
padding-top: 15%;
background-position: center right;
background-image: url("/src/assets/mainBackgroundPic.png");
/* background-repeat: no-repeat; */
/* background-position: center right; */
/* background-size: cover; */
}
.login-container {
opacity: 0.96;
border-radius: 10px;
margin: 0px auto;
width: 400px;
padding: 30px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
text-align: left;
box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}
.title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
</style>

631
src/views/materials.vue Normal file
View File

@ -0,0 +1,631 @@
<template>
<div class="common-layout">
<el-container>
<div class="header">
<div class="logo">
<h1>领料系统</h1>
</div>
</div>
<el-main>
<br><br>
<el-form
ref="form"
:model="formData"
label-width="80px"
class="input-form"
>
<!-- 用户信息 -->
<div class="userInfoBox">
<h4>个人信息</h4><br><hr><br>
<el-form-item label="姓名" prop="xingming" >
<el-input v-model="formData.xingming" style="width: 145px;"></el-input>
<div style="display: flex; align-items: center" >
<el-popover placement="bottom" :width="400">
<template #reference>
<el-button type="primary" @click.once="getUserInfoMethod()" style="width: 20px;" plain>快填</el-button>
</template>
<!-- 弹出列表 -->
<el-table :data="filterTableData" style="width: 100%" height="250">
<el-table-column label="姓名" prop="xingming" width="100px"/>
<el-table-column label="联系方式" prop="dianhua" width="130px"/>
<el-table-column label="id" prop="id" v-if="false"/>
<el-table-column label="地址" prop="dizhi" v-if="false"/>
<el-table-column label="备注" prop="beizhu" v-if="false"/>
<el-table-column align="right">
<template #header>
<el-input v-model="search" size="small" placeholder="请输入姓名" />
</template>
<template #default="scope">
<el-button size="small" @click="handleConfirm(scope.$index, scope.row)"
>确认</el-button>
</template>
</el-table-column>
</el-table>
</el-popover>
</div>
</el-form-item>
<el-form-item label="联系电话" prop="mingcheng">
<el-input v-model="formData.dianhua"></el-input>
</el-form-item>
<el-form-item label="地址" prop="mingcheng">
<el-input v-model="formData.dizhi"></el-input>
</el-form-item>
<el-form-item label="申请人ID" prop="mingcheng">
<el-input v-model="formData.id"></el-input>
</el-form-item>
<el-form-item label="备注" prop="tupianshuoming">
<el-input type="textarea" v-model="formData.beizhu"></el-input>
</el-form-item>
<el-form-item label="是否物料申请任务" prop="mingcheng" label-width="160px">
<el-switch v-model="formData.lingliaofangshi" />
</el-form-item>
</div>
<!--工单申请物料 -->
<div class="ticketsBox" v-show="formData.lingliaofangshi">
<h4>生产工单</h4><br><hr><br>
<!-- 弹出表格 -->
<el-form-item label="任务名称" prop="xingming" >
<el-input v-model="formData.shengchangongdan.chanpingmingcheng" style="width: 145px;"></el-input>
<div style="display: flex; align-items: center" >
<el-popover placement="bottom" :width="400">
<template #reference>
<el-button type="primary" @click.once="getTicketsInfoMethod()" style="width: 20px;" plain>快填</el-button>
</template>
<!-- 弹出列表 -->
<el-table :data="filterTicketData" style="width: 100%" height="250">
<el-table-column label="产品名称" prop="chanpingmingcheng" width="100px"/>
<el-table-column label="数量" prop="shuliang" width="130px"/>
<el-table-column label="规格" prop="guige" v-if="false"/>
<el-table-column label="开始时间" prop="scsjks" v-if="false"/>
<el-table-column label="结束时间" prop="scsjjs" v-if="false"/>
<el-table-column label="备注" prop="beizhu" v-if="false"/>
<el-table-column label="id" prop="id" v-if="false"/>
<el-table-column align="right">
<template #header>
<el-input v-model="searchTicket" size="small" placeholder="请输入姓名" />
</template>
<template #default="scope">
<el-button size="small" @click="ticketHandleConfirm(scope.$index, scope.row)"
>确认</el-button>
</template>
</el-table-column>
</el-table>
</el-popover>
</div>
</el-form-item>
<el-form-item label="数量" prop="mingcheng">
<el-input v-model="formData.shengchangongdan.shuliang"></el-input>
</el-form-item>
<el-form-item label="单据编号" prop="mingcheng">
<el-input v-model="formData.shengchangongdan.billCode"></el-input>
</el-form-item>
<el-form-item label="规格" prop="mingcheng">
<el-input v-model="formData.shengchangongdan.guige"></el-input>
</el-form-item>
<el-form-item label="开始日期" prop="mingcheng">
<div class="block">
<span class="demonstration"></span>
<el-date-picker
v-model="formData.shengchangongdan.scsjks"
type="date"
placeholder="开始日期"
:default-value="new Date(2010, 9, 1)"
style="width: 100%"
/>
</div>
</el-form-item>
<el-form-item label="结束日期" prop="mingcheng">
<div class="block">
<span class="demonstration"></span>
<el-date-picker
v-model="formData.shengchangongdan.scsjjs"
type="date"
placeholder="结束日期"
:default-value="new Date(2010, 9, 1)"
style="width: 100%"
/>
</div>
</el-form-item>
<el-form-item label="任务备注" prop="tupianshuoming">
<el-input type="textarea" v-model="formData.shengchangongdan.beizhu"></el-input>
</el-form-item>
<el-form-item label="任务ID" prop="mingcheng">
<el-input v-model="formData.shengchangongdan.id"></el-input>
</el-form-item>
</div>
<!-- 物料材料展示列表 -->
<div class="materalBox">
<h4>物料领用</h4><br><hr><br>
<el-form-item label="材料" prop="cailiao">
<div class="m-4">
<el-cascader v-model="materialObj.cailiao" :options="emunValueList" @focus.once="getMateralEnum()"/>
</div>
</el-form-item>
<el-form-item label="规格" prop="guige">
<el-input v-model="materialObj.guige"></el-input>
</el-form-item>
<el-form-item label="数量" prop="shuliang">
<el-input v-model="materialObj.shuliang"></el-input>
</el-form-item>
<el-form-item>
</el-form-item>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="cailiaomingcheng" label="材料" width="80" />
<el-table-column prop="guige" label="规格" width="80" />
<el-table-column prop="shuliang" label="数量" width="80" />
<el-table-column fixed="right" label="操作" width="60">
<template #default="scope">
<el-button
link
type="primary"
size="small"
@click.prevent="deleteRow(scope.$index)"
style="width: 30px;"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button @click="tableDataDddObj" round style="width: 100%;color: rgb(64, 159, 237);">添加</el-button>
</div>
<br><br>
<!-- 提交按钮 -->
<div class="buttonBox">
<el-button type="primary" style="width:100% ;border-radius:10px" @click="submitDataMethod()">提交</el-button>
</div>
</el-form>
</el-main>
<el-footer>
<footerCompoent></footerCompoent>
</el-footer>
</el-container>
</div>
</template>
<script lang="ts" setup>
import {computed,reactive, ref, watch} from 'vue'
import { ElTable } from 'element-plus'
import callApi from '../util/apiConnectHook'
import apiConnectHook from '../util/apiConnectHook'
import headerComponet from '../components/promotionalPageComponents/header.vue'
import footerCompoent from '../components/footer.vue'
/**
* 用户姓名弹窗element-plus配置代码
* @search [参数] 用户模糊搜索的双向绑定数据
* @filterTableData [方法] 根据用户的搜索值进行过滤
* @handleConfirm [方法] 用户点击行的确认就把行里面的数据映射到输入框中
* @userInfoTableData [参数]弹出窗里面的数据就存储到这个列表中
* @getUserInfoMethod [方法]调用这个方法从v8中调出所有用户档案的数据,把数据装入userInfoTableData进行展示
* --------------------------------------------------------------------------______________________________________________________________
*/
interface User {
xingming: string
dianhua: string
}
const search = ref('')
const filterTableData = computed(() =>
userInfoTableData.value.filter(
(data) =>
!search.value ||
data.xingming.toLowerCase().includes(search.value.toLowerCase())
)
)
const handleConfirm = (index: number, row: User) => {
console.log(index, row)
formData.xingming = row.xingming
formData.dianhua = row.dianhua
formData.dizhi = row.dizhi
formData.id = row.id
formData.beizhu = row.beizhu
}
const userInfoTableData = ref([])
function getUserInfoMethod(){
let apiConnectHook = callApi()
const requestBody = {
"requestId": "1833161472545390812",
"params": {'renyuanfenlei':"XIUNIANG"},
"timestamp": Date.now()
}
const apiUrl = "api/wushuiyuntai3071243142359302596/Renyuandangan11AppServiceImpl/selectListByComplexConditions"
//""
const promise = apiConnectHook.callApi(apiUrl,requestBody)
promise.then((result) => {
console.log('用户数据信息',result.data);
result.data.content.forEach(element => {
const obj = {
xingming:element.xingming,
dianhua:element.dianhua,
dizhi : element.dizhi,
id : element.renyuanID,
beizhu : element.beizhu,
}
userInfoTableData.value.push(obj)
});
}).catch((error) => {
console.log(error);
});
}
/**
* 任务名称弹窗数据获取
* @searchTicket [参数] 用户模糊搜索的双向绑定数据
* @ticketData [参数]弹出列表数据就存储到这个列表中
* @filterTicketData [方法]根据用户搜索信息对ticketData进行模糊查询过滤
* @ticketHandleConfirm [方法]用户点击确认就把选中的行里面的数据映射到对应的输入框中
* @getTicketsInfoMethod [方法]用户点击快填就调用方法从v8中抽取数据然后把数据赋值给ticketData之后弹出列表就更新数据
* _______________________________________________________________________________________________________________________________________________
*/
const searchTicket = ref('')
const ticketData = ref([])
const filterTicketData = computed(() =>
ticketData.value.filter(
(data) =>
!searchTicket.value ||
data.chanpingmingcheng.toLowerCase().includes(searchTicket.value.toLowerCase())
)
)
const ticketHandleConfirm = (index:number,row:User)=>{
formData.shengchangongdan.chanpingmingcheng = row.chanpingmingcheng
formData.shengchangongdan.shuliang = row.shuliang
formData.shengchangongdan.guige = row.guige
formData.shengchangongdan.scsjks = row.scsjks
formData.shengchangongdan.scsjjs = row.scsjjs
formData.shengchangongdan.billCode = row.billCode
formData.shengchangongdan.beizhu = row.beizhu
formData.shengchangongdan.id = row.id
}
function getTicketsInfoMethod(){
let apiConnectHook = callApi()
const body = {
"data": {
"jinririqi": Date.now()
},
"requestId": "1836097485093732586",
"timestamp": Date.now()
}
const url = "api/wushuiyuntai3071243142359302596/MicroFlowAppServiceImpl/productiontask"
//
const promise = apiConnectHook.callApi(url,body)
promise.then((result) => {
console.log("任务名称数据",result.data);
result.data.content.forEach(element => {
const obj = {
chanpingmingcheng:element.chanpinmingcheng,
shuliang:element.shuliang,
guige:element.guige,
scsjks:element.scsjks,
scsjjs:element.scsjjs,
beizhu:element.beizhu,
id:element.id,
billCode:element.billCode
}
ticketData.value.push(obj)
});
console.log("ticketDate",ticketData.value)
})
}
/**
* @description 领料列表中有一个删除按钮点击按钮就触发这个方法这个方法就是删除选中行
*
*/
const deleteRow = (index: number) => {
tableData.splice(index, 1)
}
/**
* @formData [参数]个人信息生产工单的输入框字段映射
* @materialObj [参数]物料领用输入框映射字段
* @tableData [参数]物料表的映射字段
* ___________________________________________________________________________________________________________________
*/
const formData = reactive({
xingming:'',
dianhua:'',
dizhi:'',
id:'',
beizhu:'',
lingliaofangshi:false,
shengchangongdan:{
chanpingmingcheng:'',
shuliang:'',
billCode:'',
guige:'',
scsjks:'',
scsjjs:'',
beizhu:'',
id:'',
},
})
watch(()=>formData.lingliaofangshi, (newVal, oldVal) => {
if(newVal===false){
formData.shengchangongdan = {
chanpingmingcheng:'',
shuliang:'',
billCode:'',
guige:'',
scsjks:'',
scsjjs:'',
beizhu:'',
id:'',
}
}
})
const materialObj = reactive({
cailiao:'',
guige:'',
shuliang:''
})
//[][]
const tableData = reactive([
])
//[][id]
const tableDataSubmit = reactive([
])
/**
* 添加按钮方法点击添加按钮就往tableDate表中添加数据表中的数据就会增加一行
* @descriped 对于材料列表点击添加就从输入框的双向绑定数据拉取值到弹窗列表中
* @cailiaomingchengid 这里针对二级枚举选项框选项框的双向绑定数据只能获取到所选枚举的id但是我的材料列表需要的是中文名称
* 所以这里获取了所选的二级枚举的id通过所选二级枚举id同所有的二级枚举做if判断来获取二级枚举的中文名称
* 然后把这个中文名称放到弹窗列表中
*/
function tableDataDddObj(){
const cailiaomingchengid = materialObj.cailiao[1]
let cailiaomingcheng = ''
TwoLevelEmun.forEach(element => {
if(element.value === cailiaomingchengid){
cailiaomingcheng = element.label
}
});
const obj = {
cailiaomingcheng:cailiaomingcheng,
shuliang:materialObj.shuliang,
guige:materialObj.guige,
// createTime:Date.now()
}
const objTwoSubmit = {
cailiaomingcheng:materialObj.cailiao[1],
shuliang:materialObj.shuliang,
guige:materialObj.guige,
}
tableData.push(obj)
tableDataSubmit.push(objTwoSubmit)
materialObj.cailiao = ''
materialObj.guige = ''
materialObj.shuliang = ''
}
/**
* 提交按钮触发方法
* 提交触发方法进行提交
* @apiConnectHook [参数]导入调用接口钩子函数
* @requestInsertBody [参数]请求体
* @url [参数]api地址
*
*
*/
function submitDataMethod(){
let apiConnectHook = callApi()
// const requestInsertBody = {
// "data": {
// "shifoushengchanrenwu": formData.shifou,
// "mobanbianhao": "Materialrequest",
// "faqirenID": "1709976317081944296",
// "wuliaoshenqing": {
// "mingcheng": formData.shengchangongdan.id,
// "shuliang": formData.shengchangongdan.shuliang,
// "guige": formData.shengchangongdan.guige,
// "kaishishijian": formData.shengchangongdan.scsjks,
// "jieshushijian": formData.shengchangongdan.scsjjs,
// "renwubeizhu": formData.shengchangongdan.beizhu,
// "renwuID": formData.shengchangongdan.id,
// "wuliaoDtoList": tableDataSubmit,
// "xingmingCode": formData.xingming,
// "lianxidianhua": formData.dianhua,
// "dizhi": formData.dizhi,
// "beizhu": formData.beizhu,
// "shenqingrenID": "1831623715373187904"
// }
// },
const requestInsertBody = {
"data": {
"faqirenID": "1709976317081944296",
"wuliaoshenqing": {
"lingliaofangshi": formData.lingliaofangshi,
"wuliaoDtoList": tableDataSubmit,
"renwuID": "",
"beizhu": "123",
"shenqingrenID": formData.id
},
"moban": "Materialrequest"
},
"requestId": "1843191758947614954",
"timestamp": Date.now()
}
console.log("requestInsertBody",requestInsertBody)
const url = "api/wushuiyuntai3071243142359302596/MicroFlowAppServiceImpl/materiel"
const promise = apiConnectHook.callApi(url,requestInsertBody)
promise.then((result)=>{
console.log('插入数据返回数据',result)
if(result.message === "SUCCESS"){
alert("数据提交成功")
}else{
alert("数据提交失败,请联系管理员")
}
})
}
/**
* @description 材料二级单选框
* @value [参数] 与单选框的值做双向数据绑定
* @getMateralEnum [方法]从v8获取二级枚举的值的api接口
* @emunValue [参数]二级枚举中具体的值
*/
const emunValueList = reactive([])
/**
* 1调用接口工具调出v8接口获取二级联集选项框的值
* 2根据itemLevel的值将一级选项值放到primaryList数组中
* 3通过嵌套循环外层遍历一级枚举值数据内层遍历二级数组通过子级的parentid和父级的id做if结合在一起
*/
const TwoLevelEmun = []
function getMateralEnum(){
const body = {
"requestId": "1840125578808656106",
"params": {'enumCode':'wuliaoguanli'},
"timestamp": Date.now()
}
const url = "api/wushuiyuntai3071243142359302596/CtpEnumItemAppService/selectChildByEnumCodeAndItemValue"
let apiConnectHook = callApi()
const responseValue = apiConnectHook.callApi(url,body)
const primaryList = []
responseValue.then((emunListResult) => {
const emunList = emunListResult.data.content
emunList.forEach((emun)=>{
//
if(emun.itemLevel === 1){
const emunName = JSON.parse(emun.name).zh_CN;
const emunId = emun.id
const enumObj = {
value: emunId,
label: emunName,
}
primaryList.push(enumObj)
}
})
//
primaryList.forEach((oneEmun)=>{
const children = []
emunList.forEach((twoEnum)=>{
if(twoEnum.itemLevel == 2 && twoEnum.parentId == oneEmun.value){
const twoObj = {
value:twoEnum.id,
label:JSON.parse(twoEnum.name).zh_CN
}
children.push(twoObj)
TwoLevelEmun.push(twoObj)
}
})
const oneEmunObj = {
value: oneEmun.value,
label: oneEmun.label,
children: children
}
emunValueList.push(oneEmunObj)
})
}
)}
</script>
<style scoped>
.header {
text-align: center;
position: fixed;
top: 0;
width: 100%;
height: 60px;
display: flex;
align-items: center;
background-color: #a02f23;
z-index: 99999;
/* 其他样式属性... */
}
.logo {
margin: 0 auto;
text-align: center;
width: 100%;
}
.logo h1 {
font-size: 24px;
font-weight: bold;
color: #ffffff;
margin: 0;
}
.input-form {
max-width: 300px;
margin: 20px auto;
}
.common-layout header{
background-color: antiquewhite;
}
/* 日期选取样式 */
.demo-date-picker {
display: flex;
width: 100%;
padding: 0;
flex-wrap: wrap;
}
.demo-date-picker .block {
padding: 30px 0;
text-align: center;
border-right: solid 1px var(--el-border-color);
flex: 1;
}
.demo-date-picker .block:last-child {
border-right: none;
}
.demo-date-picker .demonstration {
display: block;
color: var(--el-text-color-secondary);
font-size: 14px;
margin-bottom: 20px;
}
/* */
.userInfoBox{
padding: 20px;
border-radius: 20px;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3);
}
.ticketsBox{
margin-top: 20px;
padding: 20px;
border-radius: 20px;
box-shadow: 0px 0px 20px rgba(121, 121, 121, 0.3);
}
.materalBox{
margin-top: 20px;
padding: 20px;
border-radius: 20px;
box-shadow: 0px 0px 20px rgba(121, 121, 121, 0.3);
}
.buttonBox{
margin-top: -30px;
padding: 20px;
border-radius: 20px;
box-shadow: 0px 0px 20px rgba(121, 121, 121, 0.3);
}
.mandatesBox {
border: red solid 2px;
background-color: aliceblue;
width: 400px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3);
border-radius: 10px;
}
.iconBox{
height: 40px;
width: 40px;
float: right;
/* margin-right: 20px; */
}
</style>

View File

@ -0,0 +1,89 @@
<template>
<div class="common-layout">
<el-container>
<el-header><headerComponent></headerComponent></el-header>
<el-main><br>
<h1>扫码领料</h1><br>
<el-steps :active="active" finish-status="success">
<el-step title="扫描二维码" />
<el-step title="填写个人信息" />
<el-step title="填写物料领用信息" />
<el-step title="提交申请" />
</el-steps>
<!-- <el-button style="margin-top: 12px" @click="next">已完成</el-button><br><br><br> -->
<div class="imgBox">
<img src="../assets/images/detailOne.png" alt="" class="detailOne"><br><br>
<img :src="qrCodeUrl" alt="" class="QRImgOne">
</div>
<!-- <br><br><br>
<h1>扫码成品入库</h1><br>
<el-steps :active="active" finish-status="success">
<el-step title="扫描二维码" />
<el-step title="填写个人信息" />
<el-step title="填写成品信息" />
<el-step title="提交申请" />
</el-steps>
<div class="imgBox2">
<img src="../assets/images/detailTwo.png" alt="" class="detailTwo"><br><br>
<img :src="qrCodeUrl" alt="" class="QRImgTwo">
</div> -->
</el-main>
</el-container>
<footerCompoent></footerCompoent>
</div>
</template>
<script setup>
import headerComponent from '../components/promotionalPageComponents/header.vue'
import footerCompoent from '../components/footer.vue'
import useQRCodeGenerator from '../util/QRCodeGenerator';
import { reactive, ref } from 'vue'
const active = ref(0)
const next = () => {
if (active.value++ > 2) active.value = 0
}
const { qrCodeUrl } = useQRCodeGenerator('https://wsyt.guizhoujc.com/materials');
</script>
<style scoped>
.imgBox2 {
position: relative;
margin-top: 2rem;
}
.imgBox2 .detailTwo {
width: 100%;
border-radius: 20px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}
.imgBox2 .QRImgTwo {
width: 220px;
position: absolute;
top: 39%;
left: 18%;
z-index: 2;
}
.imgBox {
position: relative;
margin-top: 2rem;
}
.imgBox .detailOne {
width: 100%;
border-radius: 20px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}
.imgBox .QRImgOne {
width: 220px;
position: absolute;
top: 40%;
left: 4%;
z-index: 2;
}
</style>

359
src/views/register.vue Normal file
View File

@ -0,0 +1,359 @@
<template>
<div>
<!--头部标签 -->
<div class="header">
<img src="/src/assets/logo.png" alt="" style="width: 80px; height:80px; display: block;margin: 0 auto;" @click="forgotHome">
</div>
</div>
<!-- 注册表单的外层包裹容器 -->
<div class="register-wrap">
<!-- 注册表单 -->
<el-form class="register-container" label-position="top" status-icon>
<!-- 标题 -->
<!-- <h1 class="title">用户注册</h1> -->
<img src="/src/assets/image1.png" alt="" style="margin-bottom: 15px;">
<!-- 选择用户角色 -->
<!-- <el-form-item label="用户角色">
<el-radio-group v-model="userType">
<el-radio label="SHEJISHI">设计师</el-radio>
<el-radio label="YOUKE">普通用户</el-radio>
</el-radio-group>
</el-form-item> -->
<!-- 共同信息 -->
<!-- 上传头像 -->
<!-- <el-form-item label="头像">
<el-upload class="avatar-uploader" action="/upload" :show-file-list="false" :on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar"> 如果有图片则显示预览
<plus/>
<el-icon v-else class="avatar-uploader-icon">
<Plus />
</el-icon>
</el-upload>
</el-form-item> -->
<el-form-item label="联系方式:">
<el-input v-model="contact" placeholder="手机号" autocomplete="off" minlength="11" maxlength="11" show-word-limit
:rules="[{ required: true, message: '手机号不能为空', trigger: 'change' }, { validator: validateMobile, trigger: 'change' }]"></el-input>
</el-form-item>
<el-form-item label="密码:" class="left-top-label">
<el-input type="password" v-model="password" placeholder="设置密码" autocomplete="off" show-password
:rules="[{ required: true, message: '密码不能为空', trigger: 'change' }, { validator: validatePassword, trigger: 'change' }]"></el-input>
</el-form-item>
<el-form-item label="确认密码:">
<el-input type="password" v-model="confirmPassword" placeholder="确认密码" autocomplete="off" show-password
:rules="[{ required: true, message: '确认密码不能为空', trigger: 'blur' }, { validator: validateConfirmPassword, trigger: 'blur' }]"></el-input>
</el-form-item>
<!-- <el-form-item label="联系方式:">
<el-input v-model="contact" placeholder="手机号" autocomplete="off" ></el-input>
</el-form-item>
<el-form-item label="密码:" class="left-top-label">
<el-input type="password" v-model="password" placeholder="设置密码" autocomplete="off" show-password></el-input>
</el-form-item>
<el-form-item label="确认密码:">
<el-input type="password" v-model="confirmPassword" placeholder="确认密码" autocomplete="off" show-password></el-input>
</el-form-item> -->
<el-form-item label="姓名:">
<el-input v-model="name" placeholder="姓名" autocomplete="off"></el-input>
</el-form-item>
<!-- <el-form-item label="地址:">
<el-input v-model="address" placeholder="地址" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-radio-group v-model="gender">
<el-radio label="NAN"></el-radio>
<el-radio label="NV"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="userType === 'SHEJISHI'" label="品牌方及简介">
<el-input type="textarea" v-model="brandIntro" placeholder="品牌方及简介" autocomplete="off"></el-input>
</el-form-item>
<el-form-item v-if="userType === 'SHEJISHI'" label="设计方向">
<el-input v-model="designDirection" placeholder="设计方向" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="单位名称">
<el-input v-model="companyName" placeholder="单位名称" autocomplete="off"></el-input>
</el-form-item>-->
<!-- 注册按钮 -->
<el-form-item>
<el-button type="primary" @click="callApi" style="width: 100%;">注册</el-button>
<el-link type="primary" @click="gotoLogin()" style="margin: auto;">返回登录</el-link>
</el-form-item>
</el-form>
</div>
<FooterCompoent></FooterCompoent>
</template>
<script>
import axios from 'axios';
import { calculateSignature } from '../util/md5Util'; //
import { Plus } from '@element-plus/icons-vue'
import FooterCompoent from '../components/footer.vue'
export default {
components: {
//
Plus,FooterCompoent
},
name: 'Register',
data() {
return {
//
// username: '', //
password: '', //
confirmPassword: '', //
name: '', //
contact: '', //
// address: '', //
// //
// brandIntro: '', //
// designDirection: '', //
// //
// gender: '', //
// companyName: '', //
userType: 'YOUKE',
// imageUrl: '' //
}
},
methods: {
forgotHome() {
// logo
// 使 Vue Router home
this.$router.push({ name: 'home' });
},
gotoLogin() {
//
// 使 Vue Router
this.$router.push({ name: 'login' });
},
// 8-16
validatePassword(rule, value, callback) {
const passwordReg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$/;
if (!passwordReg.test(value)) {
callback(new Error('密码格式不正确需为8-16位数字和字母的组合'));
} else {
callback();
}
},
//
validateConfirmPassword(rule, value, callback) {
if (value !== this.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
},
// 11
validateMobile(rule, value, callback) {
const mobileReg = /^1[3-9]\d{9}$/;
if (!mobileReg.test(value)) {
callback(new Error('手机号格式不正确'));
} else {
callback();
}
},
// //
// handleAvatarSuccess(response, file) {
// this.imageUrl = URL.createObjectURL(file.raw);
// },
// //
// beforeAvatarUpload(file) {
// const isJPG = file.type === 'image/jpeg';
// const isJPEG = file.type === 'image/jpeg';
// const isPNG = file.type === 'image/png';
// const isLt2M = file.size / 1024 / 1024 < 2;
// if (!(isJPG || isJPEG || isPNG)) {
// this.$message.error(' JPGJPEG PNG !');
// }
// if (!isLt2M) {
// this.$message.error(' 2MB!');
// }
// return isJPG && isLt2M;
// },
//
// gotoLogin() {
// },
// API
async callApi() {
// let data = [
// "dianhua:" + this.contact,
// "mima:" + this.password,
// "xingming:" + this.name,
// // "dizhi:" + this.address,
// // "pinpaimingjijianjie:" + this.brandIntro,
// // "sjfxsz:" + this.designDirection,
// // "xingbie:" + this.gender,
// // "danweimingcheng:" + this.companyName,
// "renyuanfenlei:" + this.userType]
// ;
// let result = {};
// data.forEach(item => {
// let [key, value] = item.split(':');
// result[key] = value;
// });
// // console.log(result)
// const jsonObject = JSON.stringify(result);
// // console.log(jsonObject);
// const parsedObject = JSON.parse(jsonObject);
// console.log(parsedObject)
//
const headers = {
'Content-Type': 'application/json',
'app-key': 'c7d9decc0ccb4b6da81a9f65aea29ed3',
'sign-type': 'MD5',
'sign': '', //
};
const appSecret = '8299e69f17d943f59109a79d73e80da5';
//
const requestBody = {
"data": {
"zhanghao1": this.contact,
"mima1": this.password,
"mingzi": this.name,
"renyuanfenlei": this.userType
},
"requestId": "181142053210554392",
"timestamp": Date.now()
};
console.log(requestBody)
// MD5
const signature = calculateSignature(requestBody, appSecret);
headers['sign'] = signature;
try {
// POST
// const response = await axios.post('api/wushuiyuntai9146708742788827704/Renyuandangan11AppServiceImpl/create', requestBody, { headers });
const response = await axios.post('api/wushuiyuntai3071243142359302596/MicroFlowAppServiceImpl/register', requestBody, { headers });
//
const responseData = response.data;
console.log('接口返回的数据:', responseData);
console.log(responseData.data.content);
// true
if (responseData.data.content == true) {
this.$message({
showClose: true,
message: '注册成功,返回登录页面',
type: 'success'
});
this.$router.push({ name: 'login' });
} else {
//false
this.$message({
showClose: true,
message: '注册失败',
type: 'error'
});
}
} catch (error) {
console.error('调用接口发生错误:', error);
}
},
},
}
</script>
<style scoped>
/* 样式 */
.header {
width: 100%;
height: 100px;
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
top: 0;
left: 0;
padding: 10px;
/*border-bottom: 1px solid #ddd; /* 根据实际情况设置头部底边框 */
transition: background-color 0.3s ease; /* 添加过渡效果 */
color: #000000; /* 文字颜色 */
background-image:url(../assets/headerBackgroungImg.png);
background-color: #8a2924;
z-index: 99;
}
/* .register-wrap {
padding-left: 60%;
box-sizing: border-box;
width: 100%;
height: 100%;
padding-top: 6%;
background-repeat: no-repeat;
background-position: center right;
background-size: 100%;
width: 100%;
height: 730px;
background-image: url("/src/assets/pj.jpg");
background-repeat: no-repeat;
background-position: center right;
background-size: cover;
} */
.register-wrap {
box-sizing: border-box;
width: 100%;
height: 100vh;
padding-top: 10%;
/* background-repeat: no-repeat; */
background-position: center right;
background-image: url("/src/assets/mainBackgroundPic.png");
/* background-repeat: no-repeat;
background-position: center right;
background-size: cover; */
}
.register-container {
border-radius: 10px;
margin: 0 auto;
width: 400px ;
padding: 30px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
text-align: left;
box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}
.title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
/* 样式 */
.avatar-uploader {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100px;
border: 1px dashed #D9D9D9;
border-radius: 6px;
overflow: hidden;
position: relative;
}
.avatar {
width: 100px;
height: 100px;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
}
</style>

183
src/views/storage.vue Normal file
View File

@ -0,0 +1,183 @@
//
<template>
<div>
<div class="header">
<div class="logo">
<h1 style="color: #ffffff;">成品入库</h1>
</div>
</div>
<div>
<el-container>
<el-main>
<el-form
ref="form"
:model="formData"
label-width="80px"
class="input-form"
>
<el-form-item label="生产人" prop="shengchanren" :rules="[{ required: true, message: '请输入生产人', trigger: 'blur' }]">
<el-input v-model="formData.shengchanren"></el-input>
</el-form-item>
<el-form-item label="联系电话" prop="lianxidianhua" :rules="[{ required: true, message: '请输入联系电话', trigger: 'blur' }]">
<el-input v-model="formData.lianxidianhua"></el-input>
</el-form-item>
<el-form-item label="地址" prop="dizhi" :rules="[{ required: true, message: '请输入地址', trigger: 'blur' }]">
<el-input v-model="formData.dizhi"></el-input>
</el-form-item>
<el-form-item label="成品名称" prop="chengpinmingcheng" :rules="[{ required: true, message: '请输入成品名称', trigger: 'blur' }]">
<el-input v-model="formData.chengpinmingcheng"></el-input>
</el-form-item>
<el-form-item label="规格" prop="guige" :rules="[{ required: true, message: '请输入规格', trigger: 'blur' }]">
<el-input v-model="formData.guige"></el-input>
</el-form-item>
<el-form-item label="入库数量" prop="ruku" :rules="[{ required: true, message: '请输入入库数量', trigger: 'blur' }]">
<el-input v-model="formData.ruku"></el-input>
</el-form-item>
<el-form-item label="单价">
<el-input v-model="formData.danjia"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="formData.beizhu"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">提交</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</div>
</div>
</template>
<script>
import apiUtil from '../util/apiUtil';
import useQRCodeGenerator from '../util/QRCodeGenerator';
import dayjs from 'dayjs';
export default {
name: 'materiel',
mixins: [apiUtil],
data() {
return {
formData: {
rukushijian: '',
beizhu: '',
guige: '',
shengchanren: '',
ruku: '',
dizhi: '',
chengpinmingcheng: '',
lianxidianhua: '',
danjia: '',
},
};
},
//
setup() {
const { qrCodeUrl} = useQRCodeGenerator('materiel');
return {
qrCodeUrl,
};
},
methods: {
async submitForm() {
try {
await this.$refs.form.validate();
await this.fetchData();
//
this.$message.success('提交成功');
//
this.resetForm();
console.log('提交成功', this.formData);
} catch (error) {
// console.log('', error);
this.$message.error('提交失败,请重试');
}
},
getCurrentTime() {
const currentTime = dayjs(); //
const formattedTime = currentTime.format('YYYY-MM-DD HH:mm:ss'); //
this.rukushijian = formattedTime;
},
async fetchData() {
const apiEndpoint =
'api/wushuiyuntai3071243142359302596/MicroFlowAppServiceImpl/beputinstorage';
const requestBody = {
data: {
rukudata: {
rukushijian: this.formData.rukushijian,
beizhu: this.formData.beizhu,
guige: this.formData.guige,
guige: this.formData.guige,
shengchanren: this.formData.shengchanren,
ruku: this.formData.ruku,
dizhi: this.formData.dizhi,
chengpinmingcheng: this.formData.chengpinmingcheng,
lianxidianhua: this.formData.lianxidianhua,
danjia: this.formData.danjia,
},
mobanbianhao: "Finishedproductwarehousing",
faqirenID: "1709974799515648232"
},
requestId: '1734240913900666688',
timestamp: Date.now(),
};
try {
const response = await this.callApi(apiEndpoint, requestBody);
console.log('接口返回的数据:', response);
} catch (error) {
console.error('发生错误:', error);
}
},
resetForm() {
//
Object.keys(this.formData).forEach((key) => {
this.formData[key] = '';
});
},
},
mounted() {
this.getCurrentTime();
},
};
</script>
<style scoped>
.header {
text-align: center;
position: fixed;
top: 0;
width: 100%;
height: 60px;
display: flex;
align-items: center;
background-color: #a02f23;
z-index: 99999;
/* 其他样式属性... */
}
.logo {
margin: 0 auto;
text-align: center;
width: 100%;
}
.input-form {
max-width: 400px;
margin: 20px auto;
margin-top: 85px;
}
.qr-code-container {
display: flex;
justify-content: center;
align-items: center;
height: 20vh; /* 设置容器高度,可以根据需要调整 */
}
.custom-qr-code {
border: 5px solid #2dc0fe; /* 添加白色边框 */
border-radius: 10px; /* 圆角边框 */
box-shadow: 0 0 10px rgba(33, 33, 33, 0.3); /* 添加阴影效果 */
width: 200px; /* 设置二维码宽度,可以根据需要调整 */
height: 200px; /* 设置二维码高度,可以根据需要调整 */
object-fit: cover; /* 避免拉伸变形 */
}
</style>

29
vite.config.js Normal file
View File

@ -0,0 +1,29 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
// vite 相关配置
server: {
// port: 80,
// host: true,
// open: true,
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/api': {
target: 'https://openapi-apaas.seeyonv8.com',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, '')
}
}
}
})