一大波修改 #1
2
.gitignore
vendored
@ -12,6 +12,8 @@ dist
|
|||||||
dist-ssr
|
dist-ssr
|
||||||
.history
|
.history
|
||||||
*.local
|
*.local
|
||||||
|
*.zip
|
||||||
|
*.rar
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
@ -6,6 +6,7 @@ VITE_APP_SUB_OA = '//localhost:8090/sub-operation-admin/'
|
|||||||
VITE_APP_SUB_GAS = '//localhost:8090/sub-government-affairs-service/'
|
VITE_APP_SUB_GAS = '//localhost:8090/sub-government-affairs-service/'
|
||||||
VITE_APP_SUB_GAA = '//localhost:8090/sub-government-admin/'
|
VITE_APP_SUB_GAA = '//localhost:8090/sub-government-admin/'
|
||||||
VITE_APP_SUB_GSS = '//localhost:8090/sub-government-screen-service/'
|
VITE_APP_SUB_GSS = '//localhost:8090/sub-government-screen-service/'
|
||||||
|
VITE_APP_VIST_URL = 'http://localhost'
|
||||||
# 接口
|
# 接口
|
||||||
VITE_APP_BASE_API = '/apis'
|
VITE_APP_BASE_API = '/apis'
|
||||||
VITE_APP_BASE_URL = ''
|
VITE_APP_BASE_URL = ''
|
||||||
|
@ -12,4 +12,5 @@ VITE_APP_BASE_API = '/apis'
|
|||||||
VITE_APP_BASE_URL = ''
|
VITE_APP_BASE_URL = ''
|
||||||
VITE_APP_UPLOAD_API = '/uploadApis'
|
VITE_APP_UPLOAD_API = '/uploadApis'
|
||||||
VITE_APP_UPLOAD_URL = ''
|
VITE_APP_UPLOAD_URL = ''
|
||||||
|
VITE_APP_VIST_URL = 'http://47.109.205.240'
|
||||||
|
|
||||||
|
@ -12,3 +12,4 @@ VITE_APP_BASE_API = '/apis'
|
|||||||
VITE_APP_BASE_URL = ''
|
VITE_APP_BASE_URL = ''
|
||||||
VITE_APP_UPLOAD_API = '/uploadApis'
|
VITE_APP_UPLOAD_API = '/uploadApis'
|
||||||
VITE_APP_UPLOAD_URL = ''
|
VITE_APP_UPLOAD_URL = ''
|
||||||
|
VITE_APP_VIST_URL = 'http://192.168.18.99'
|
2
main/.gitignore
vendored
@ -23,3 +23,5 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
|
*.zip
|
||||||
|
*.rar
|
@ -1,6 +1,6 @@
|
|||||||
import actions from './actions';
|
import actions from './actions';
|
||||||
|
|
||||||
const { VITE_APP_SUB_OS, VITE_APP_SUB_OA, VITE_APP_SUB_ADMIN, VITE_APP_SUB_GAS, VITE_APP_SUB_GSS, VITE_APP_SUB_GSR } = import.meta.env;
|
const { VITE_APP_SUB_OS, VITE_APP_SUB_OA, VITE_APP_SUB_ADMIN, VITE_APP_SUB_GAS, VITE_APP_SUB_GSS, VITE_APP_SUB_GSR, VITE_APP_VIST_URL } = import.meta.env;
|
||||||
|
|
||||||
export const leftApps = [
|
export const leftApps = [
|
||||||
{
|
{
|
||||||
@ -13,7 +13,7 @@ export const leftApps = [
|
|||||||
{
|
{
|
||||||
name: 'sub-operation-admin',
|
name: 'sub-operation-admin',
|
||||||
entry: VITE_APP_SUB_OA,
|
entry: VITE_APP_SUB_OA,
|
||||||
activeRule: '/sub-operation-admin',
|
activeRule: `${VITE_APP_VIST_URL}:82/login`,
|
||||||
title: '管理后台',
|
title: '管理后台',
|
||||||
icon: 'images/platform/icon-admin.png',
|
icon: 'images/platform/icon-admin.png',
|
||||||
},
|
},
|
||||||
@ -44,7 +44,7 @@ export const rightApps = [
|
|||||||
{
|
{
|
||||||
name: 'sub-government-admin',
|
name: 'sub-government-admin',
|
||||||
entry: VITE_APP_SUB_GAS,
|
entry: VITE_APP_SUB_GAS,
|
||||||
activeRule: '/sub-government-affairs-service',
|
activeRule: `${VITE_APP_VIST_URL}:81/login`,
|
||||||
title: '管理后台',
|
title: '管理后台',
|
||||||
icon: 'images/platform/icon-admin.png',
|
icon: 'images/platform/icon-admin.png',
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
VITE_APP_MIAN = 'daimp-front-main'
|
VITE_APP_MIAN = 'daimp-front-main'
|
||||||
VITE_APP_MIAN_URL = 'http://47.109.205.240:88'
|
VITE_APP_MIAN_URL = 'http://47.109.205.240:88'
|
||||||
VITE_APP_NAME = 'new-digital-agriculture-screen'
|
VITE_APP_NAME = 'new-digital-agriculture-screen'
|
||||||
|
VITE_APP_TITLE = '政务云数字农业智慧大屏'
|
||||||
# 接口
|
# 接口
|
||||||
VITE_APP_BASE_API = '/apis'
|
VITE_APP_BASE_API = '/apis'
|
||||||
VITE_APP_BASE_URL = ''
|
VITE_APP_BASE_URL = ''
|
||||||
|
2
new-digital-agriculture-screen/.gitignore
vendored
@ -64,6 +64,8 @@ web_modules/
|
|||||||
|
|
||||||
# Output of 'npm pack'
|
# Output of 'npm pack'
|
||||||
*.tgz
|
*.tgz
|
||||||
|
*.zip
|
||||||
|
*.rar
|
||||||
|
|
||||||
# Yarn Integrity file
|
# Yarn Integrity file
|
||||||
.yarn-integrity
|
.yarn-integrity
|
||||||
|
@ -4,6 +4,7 @@ VITE_APP_MIAN = 'daimp-front-main'
|
|||||||
VITE_APP_MIAN_URL = 'http://localhost:9000'
|
VITE_APP_MIAN_URL = 'http://localhost:9000'
|
||||||
VITE_APP_NAME = 'sub-operation-service'
|
VITE_APP_NAME = 'sub-operation-service'
|
||||||
VITE_APP_BASE_API = '/apis'
|
VITE_APP_BASE_API = '/apis'
|
||||||
VITE_APP_BASE_URL = 'http://192.168.18.99:88'
|
# VITE_APP_BASE_URL = 'http://192.168.18.99:88'
|
||||||
|
VITE_APP_BASE_URL = 'http://192.168.18.99:8080'
|
||||||
VITE_APP_UPLOAD_API = '/uploadApis'
|
VITE_APP_UPLOAD_API = '/uploadApis'
|
||||||
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300'
|
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300'
|
||||||
|
@ -4,7 +4,7 @@ import request from '@/utils/axios';
|
|||||||
|
|
||||||
//获取农资分类查询数据
|
//获取农资分类查询数据
|
||||||
export function transaction(params = {}) {
|
export function transaction(params = {}) {
|
||||||
return request('goods/business/category/transactionType?type=1', {
|
return request('goods/goodInfoManage/transactionType?type=1', {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
@ -12,7 +12,15 @@ export function transaction(params = {}) {
|
|||||||
|
|
||||||
//获取农资列表数据
|
//获取农资列表数据
|
||||||
export function agriculturalList(params) {
|
export function agriculturalList(params) {
|
||||||
return request('goods/business/category/transactionGoodInfo', {
|
return request('goods/goodInfoManage/transactionGoodInfo?type=1', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取商品详情接口
|
||||||
|
export function getGoodDetail(id, params) {
|
||||||
|
return request(`goods/goodInfoManage/getGoodInfo/${id}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
@ -20,7 +28,7 @@ export function agriculturalList(params) {
|
|||||||
|
|
||||||
// 获取用户评价列表
|
// 获取用户评价列表
|
||||||
export function agriculturalContent(params) {
|
export function agriculturalContent(params) {
|
||||||
return request('goods/business/category/contentPage', {
|
return request('goods/goodInfoManage/contentPage', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// src/apis/brand.js
|
// src/apis/brand.js
|
||||||
import axios from '@/utils/axios';
|
import axios from '@/utils/axios';
|
||||||
|
import request from '@/utils/axios.js';
|
||||||
|
|
||||||
export const getProducts = (params) => {
|
export const getProducts = (params) => {
|
||||||
return axios.get('/api/brand/products', {
|
return axios.get('/api/brand/products', {
|
||||||
@ -19,3 +20,29 @@ export const getMonitorList = () => {
|
|||||||
apisType: 'mock',
|
apisType: 'mock',
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function brandList(params) {
|
||||||
|
return request('brand/brandbase/page?status=1&auditStatus=2', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function goodList(params) {
|
||||||
|
return request('brand/applicationrecord/getGoodsListByUserId', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function authList(params) {
|
||||||
|
return request('brand/applicationrecord/page', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function saveRecords(data) {
|
||||||
|
return request('brand/applicationrecord/save', {
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
19
sub-operation-service/src/apis/supplier.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import request from '@/utils/axios';
|
||||||
|
|
||||||
|
//农资
|
||||||
|
|
||||||
|
//获取农资分类查询数据
|
||||||
|
export function transaction(params = {}) {
|
||||||
|
return request('goods/goodInfoManage/transactionType?type=2', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取农资列表数据
|
||||||
|
export function agriculturalList(params) {
|
||||||
|
return request('goods/goodInfoManage/transactionGoodInfo?type=2', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
106
sub-operation-service/src/apis/user.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import request from '@/utils/axios';
|
||||||
|
//购物车列表
|
||||||
|
export function shoppingCart(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/page', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//删除购物车
|
||||||
|
export function deleteChooseGoods(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/deleteChooseGoods', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//商品添加数量
|
||||||
|
export function addToCart(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/addToCart', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//商品减数量
|
||||||
|
export function delCartGood(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/delCartGood', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//获取地址列表
|
||||||
|
export function userPostAddress(params = {}) {
|
||||||
|
return request('user-center/userPostAddress/page', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//修改购物车数量
|
||||||
|
export function setGoodsCount(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/setGoodsCount', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//新增地址
|
||||||
|
export function addUserPostAddress(params = {}) {
|
||||||
|
return request('user-center/userPostAddress/add', {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//删除地址
|
||||||
|
export function deleteAddress(params = {}) {
|
||||||
|
return request(`user-center/userPostAddress/delete/${params}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//修改地址信息
|
||||||
|
export function userPostAddressed(params = {}) {
|
||||||
|
return request('user-center/userPostAddress/edit', {
|
||||||
|
method: 'PUT',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//提交订单
|
||||||
|
export function commitOrder(params = {}) {
|
||||||
|
return request('user-center/shoppingCart/commitOrder', {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//获取订单列表
|
||||||
|
export function upOrderInfoList(params = {}) {
|
||||||
|
return request('user-center/orderInfo/getById', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//确认订单
|
||||||
|
export function confirmOrder(params = {}) {
|
||||||
|
return request('user-center/orderInfo/confirmOrder', {
|
||||||
|
method: 'POST',
|
||||||
|
data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//获取订单列表
|
||||||
|
export function orderInfo(params = {}) {
|
||||||
|
return request('/user-center/orderInfo/page', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//取消订单
|
||||||
|
export function cancelOrder(params = {}) {
|
||||||
|
return request(`/user-center/orderInfo/cancelOrder/${params.id}`, {
|
||||||
|
method: 'PUT',
|
||||||
|
// data: params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//品牌列表
|
||||||
|
export function mainPage(params = {}) {
|
||||||
|
return request('/brand/applicationrecord/mainPage', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
39
sub-operation-service/src/apis/warehouseLogistics.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import request from '@/utils/axios';
|
||||||
|
|
||||||
|
// 获取仓储查询数据
|
||||||
|
export function warehouseList(params = {}) {
|
||||||
|
return request('logistics/logisticwarehouse/page?status=1', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 获取仓储查询数据
|
||||||
|
export function logisticList(params = {}) {
|
||||||
|
return request('logistics/logisticlogistic/page?', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取仓储详情
|
||||||
|
export function warehouseDetail(id, params = {}) {
|
||||||
|
return request(`logistics/logisticwarehouse/detail/${id}`, {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 获取物流详情
|
||||||
|
export function logisticDetail(id, params = {}) {
|
||||||
|
return request(`logistics/logisticlogistic/detail/${id}`, {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取仓储详情
|
||||||
|
export function getWarehouseInfo(data = {}) {
|
||||||
|
return request(`logistics/getwarehouseinfo/save`, {
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
14780
sub-operation-service/src/assets/address.json
Normal file
BIN
sub-operation-service/src/assets/images/carton.png
Normal file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
sub-operation-service/src/assets/images/empty.png
Normal file
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
BIN
sub-operation-service/src/assets/images/film.png
Normal file
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
sub-operation-service/src/assets/images/fruit.png
Normal file
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
BIN
sub-operation-service/src/assets/images/inputs/1.png
Normal file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
sub-operation-service/src/assets/images/inputs/2.png
Normal file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
sub-operation-service/src/assets/images/inputs/3.png
Normal file
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
BIN
sub-operation-service/src/assets/images/inputs/4.png
Normal file
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
BIN
sub-operation-service/src/assets/images/inputs/5.png
Normal file
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
BIN
sub-operation-service/src/assets/images/inputs/6.png
Normal file
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
sub-operation-service/src/assets/images/inputs/bg_label.png
Normal file
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
sub-operation-service/src/assets/images/inputs/bg_title.png
Normal file
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
BIN
sub-operation-service/src/assets/images/inputs/bg_value.png
Normal file
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
BIN
sub-operation-service/src/assets/images/inputs/order.webp
Normal file
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
BIN
sub-operation-service/src/assets/images/inputs/order2x.webp
Normal file
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
BIN
sub-operation-service/src/assets/images/metal.png
Normal file
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 906 KiB After Width: | Height: | Size: 906 KiB |
Before Width: | Height: | Size: 350 KiB After Width: | Height: | Size: 350 KiB |
Before Width: | Height: | Size: 679 KiB After Width: | Height: | Size: 679 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/broccoliTop.png
Normal file
Before Width: | Height: | Size: 735 KiB After Width: | Height: | Size: 735 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/chiliBottom0.png
Normal file
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/chiliBottom1.png
Normal file
Before Width: | Height: | Size: 352 KiB After Width: | Height: | Size: 352 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/chiliBottom2.png
Normal file
Before Width: | Height: | Size: 393 KiB After Width: | Height: | Size: 393 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/chiliBottom3.png
Normal file
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/chiliTop.png
Normal file
Before Width: | Height: | Size: 760 KiB After Width: | Height: | Size: 760 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/choyBottom0.png
Normal file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/choyBottom1.png
Normal file
Before Width: | Height: | Size: 620 KiB After Width: | Height: | Size: 620 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/choyBottom2.png
Normal file
Before Width: | Height: | Size: 381 KiB After Width: | Height: | Size: 381 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/choyBottom3.png
Normal file
Before Width: | Height: | Size: 378 KiB After Width: | Height: | Size: 378 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/choyTop.png
Normal file
Before Width: | Height: | Size: 522 KiB After Width: | Height: | Size: 522 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 896 KiB After Width: | Height: | Size: 896 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/ganzheTop.png
Normal file
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/leafyBottom0.png
Normal file
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/leafyBottom1.png
Normal file
Before Width: | Height: | Size: 551 KiB After Width: | Height: | Size: 551 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/leafyBottom2.png
Normal file
Before Width: | Height: | Size: 506 KiB After Width: | Height: | Size: 506 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/leafyTop.png
Normal file
Before Width: | Height: | Size: 918 KiB After Width: | Height: | Size: 918 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/seedReport.png
Normal file
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/shihuBottom0.png
Normal file
Before Width: | Height: | Size: 644 KiB After Width: | Height: | Size: 644 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/shihuBottom1.png
Normal file
Before Width: | Height: | Size: 1016 KiB After Width: | Height: | Size: 1016 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/shihuBottom2.png
Normal file
Before Width: | Height: | Size: 580 KiB After Width: | Height: | Size: 580 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/shihuBottom3.png
Normal file
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/shihuTop.png
Normal file
Before Width: | Height: | Size: 195 KiB After Width: | Height: | Size: 195 KiB |
BIN
sub-operation-service/src/assets/images/mockPic/waterReport.png
Normal file
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
BIN
sub-operation-service/src/assets/images/plastics.png
Normal file
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu4-1.png
Normal file
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu4.png
Normal file
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu5-1.png
Normal file
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu5.png
Normal file
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu6-1.png
Normal file
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu6.png
Normal file
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu7-1.png
Normal file
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
BIN
sub-operation-service/src/assets/images/userCenter/menu7.png
Normal file
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
BIN
sub-operation-service/src/assets/images/vegetable.png
Normal file
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="chartRef" style="width: 100%; height: 170px"></div>
|
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, watchEffect } from 'vue';
|
import { ref, reactive, watchEffect } from 'vue';
|
||||||
@ -260,8 +260,8 @@ export default {
|
|||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: true,
|
show: true,
|
||||||
right: '25%',
|
left: '50%', // 将图例放在图表右侧
|
||||||
top: '25%',
|
top: 'center', // 垂直居中
|
||||||
orient: 'vertical',
|
orient: 'vertical',
|
||||||
icon: 'circle',
|
icon: 'circle',
|
||||||
itemHeight: 12,
|
itemHeight: 12,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div ref="chartRef" :style="{ height, width }"></div>
|
<div ref="chartRef" :style="{ height, width }"></div>
|
||||||
</template> -->
|
</template> -->
|
||||||
<template>
|
<template>
|
||||||
<div ref="chartRef" style="width: 100%; height: 260px"></div>
|
<div ref="chartRef" style="width: 100%; height: calc((100vh - 330px) / 3 - 40px)"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, watch, watchEffect } from 'vue';
|
import { ref, reactive, watch, watchEffect } from 'vue';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="chartRef" style="width: 100%; height: 170px"></div>
|
<div ref="chartRef" style="width: 100%; height: 100%"></div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -42,6 +42,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
|
show: false,
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="chartRef" style="width: 100%; height: 260px"></div>
|
<div ref="chartRef" style="width: 100%; height: 100%; min-height: 150px"></div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { ref, reactive, watch, watchEffect } from 'vue';
|
import { ref, reactive, watch, watchEffect, onMounted } from 'vue';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { useEcharts } from '@/hooks/useEcharts';
|
import { useEcharts } from '@/hooks/useEcharts';
|
||||||
|
|
||||||
@ -58,6 +58,10 @@ export default {
|
|||||||
props.chartData && initCharts();
|
props.chartData && initCharts();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
initCharts();
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.size,
|
() => props.size,
|
||||||
() => {
|
() => {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div class="layout-header">
|
<div class="layout-header">
|
||||||
<div class="layout-header-top">
|
<div class="layout-header-top">
|
||||||
<div class="layout-header-top-left">
|
<div class="layout-header-top-left">
|
||||||
<span class="welcome-msg">您好,欢迎来到农业产业服务平台</span>
|
<span class="welcome-msg">您好,欢迎来到农业产业运营平台</span>
|
||||||
<div class="left-link">
|
<div class="left-link">
|
||||||
<div class="iconfont icon-bigScreen"></div>
|
<div class="iconfont icon-bigScreen"></div>
|
||||||
<span>数据大屏</span>
|
<span>数据大屏</span>
|
||||||
@ -74,10 +74,10 @@ const router = useRouter();
|
|||||||
const keyword = ref('');
|
const keyword = ref('');
|
||||||
|
|
||||||
const meuns = ref([
|
const meuns = ref([
|
||||||
// {
|
{
|
||||||
// label: '综合看板',
|
label: '综合看板',
|
||||||
// path: '/sub-operation-service/dashboard',
|
path: '/sub-operation-service/dashboard',
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
label: '智慧种植',
|
label: '智慧种植',
|
||||||
path: '/sub-operation-service/smartFarm',
|
path: '/sub-operation-service/smartFarm',
|
||||||
|
@ -49,6 +49,12 @@ export const constantRoutes = [
|
|||||||
name: 'sureOrder',
|
name: 'sureOrder',
|
||||||
meta: { title: '结算' },
|
meta: { title: '结算' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/addressList',
|
||||||
|
component: () => import('@/views/userCenter/addressList.vue'),
|
||||||
|
name: 'addressList',
|
||||||
|
meta: { title: '我的地址' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-operation-service/orderSuccess',
|
path: '/sub-operation-service/orderSuccess',
|
||||||
component: () => import('@/views/userCenter/orderSuccess.vue'),
|
component: () => import('@/views/userCenter/orderSuccess.vue'),
|
||||||
@ -67,6 +73,12 @@ export const constantRoutes = [
|
|||||||
name: 'userOrders',
|
name: 'userOrders',
|
||||||
meta: { title: '我的订单' },
|
meta: { title: '我的订单' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/orderDetails',
|
||||||
|
component: () => import('@/views/userCenter/orderDetails.vue'),
|
||||||
|
name: 'orderDetails',
|
||||||
|
meta: { title: '订单详情' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-operation-service/userLands',
|
path: '/sub-operation-service/userLands',
|
||||||
component: () => import('@/views/userCenter/userLands.vue'),
|
component: () => import('@/views/userCenter/userLands.vue'),
|
||||||
@ -85,6 +97,12 @@ export const constantRoutes = [
|
|||||||
name: 'myFinance',
|
name: 'myFinance',
|
||||||
meta: { title: '我的金融' },
|
meta: { title: '我的金融' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/myBrand',
|
||||||
|
component: () => import('@/views/userCenter/myBrand.vue'),
|
||||||
|
name: 'myBrand',
|
||||||
|
meta: { title: '我的品牌' },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -92,7 +110,7 @@ export const constantRoutes = [
|
|||||||
path: '/sub-operation-service',
|
path: '/sub-operation-service',
|
||||||
name: 'layout',
|
name: 'layout',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/sub-operation-service/smartFarm',
|
redirect: '/sub-operation-service/dashboard',
|
||||||
meta: { title: '运营服务' },
|
meta: { title: '运营服务' },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -101,11 +119,20 @@ export const constantRoutes = [
|
|||||||
name: 'home',
|
name: 'home',
|
||||||
meta: { title: '首页' },
|
meta: { title: '首页' },
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-operation-service/dashboard',
|
path: '/sub-operation-service/dashboard',
|
||||||
component: () => import('@/views/dashboard/index.vue'),
|
component: Layout,
|
||||||
name: 'dashboard',
|
name: 'dashboard',
|
||||||
|
redirect: '/sub-operation-service/dashboard/home',
|
||||||
meta: { title: '综合看板' },
|
meta: { title: '综合看板' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/dashboard/home',
|
||||||
|
component: () => import('@/views/dashboard/breed/index.vue'),
|
||||||
|
name: 'dashboardHome',
|
||||||
|
meta: { title: '综合看板首页' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -230,6 +257,12 @@ export const constantRoutes = [
|
|||||||
name: 'packagingMain',
|
name: 'packagingMain',
|
||||||
meta: { title: '包装首页' },
|
meta: { title: '包装首页' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/packaging/details',
|
||||||
|
component: () => import('@/views/packaging/details.vue'),
|
||||||
|
name: 'detailsMain',
|
||||||
|
meta: { title: '详情页' },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -245,12 +278,24 @@ export const constantRoutes = [
|
|||||||
name: 'warehouseMain',
|
name: 'warehouseMain',
|
||||||
meta: { title: '仓储首页' },
|
meta: { title: '仓储首页' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/warehouse-detail',
|
||||||
|
component: () => import('@/views/warehouseLogistics/warehouse/detail.vue'),
|
||||||
|
name: 'warehouse-detail',
|
||||||
|
meta: { title: '仓储详情' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/sub-operation-service/logistics',
|
path: '/sub-operation-service/logistics',
|
||||||
component: () => import('@/views/warehouseLogistics/logistics/index.vue'),
|
component: () => import('@/views/warehouseLogistics/logistics/index.vue'),
|
||||||
name: 'logistics-list',
|
name: 'logistics-list',
|
||||||
meta: { title: '物流首页' },
|
meta: { title: '物流首页' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/sub-operation-service/logistics-detail',
|
||||||
|
component: () => import('@/views/warehouseLogistics/logistics/detail.vue'),
|
||||||
|
name: 'logistics-detail',
|
||||||
|
meta: { title: '物流详情' },
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
24
sub-operation-service/src/store/modules/userOrder.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { constantRoutes, notFoundRouter } from '@/router';
|
||||||
|
import { createAsyncRoutes, filterAsyncRoutes, filterKeepAlive } from '@/utils/router';
|
||||||
|
import { orderInfo } from '../../apis/user';
|
||||||
|
import { getTree } from '@/utils';
|
||||||
|
|
||||||
|
export const useGetUserOrder = defineStore('userOrder', {
|
||||||
|
state: () => ({
|
||||||
|
data: {},
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
//订单
|
||||||
|
getData(params) {
|
||||||
|
return Promise.resolve(
|
||||||
|
orderInfo(params).then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
useGetUserOrder().$state.data = res.data;
|
||||||
|
return useGetUserOrder().$state.data;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
getters: {},
|
||||||
|
});
|
@ -1,7 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<el-breadcrumb separator="·">
|
<el-breadcrumb separator="·">
|
||||||
<el-breadcrumb-item style="cursor: pointer" @click="backToList">使用申请</el-breadcrumb-item>
|
<el-breadcrumb-item style="cursor: pointer" @click="backToList"
|
||||||
|
><el-icon><ArrowLeftBold /></el-icon>使用申请</el-breadcrumb-item
|
||||||
|
>
|
||||||
<el-breadcrumb-item><a href="#">我要申请</a></el-breadcrumb-item>
|
<el-breadcrumb-item><a href="#">我要申请</a></el-breadcrumb-item>
|
||||||
</el-breadcrumb>
|
</el-breadcrumb>
|
||||||
|
|
||||||
@ -9,10 +11,13 @@
|
|||||||
|
|
||||||
<el-form label-width="120px" class="form">
|
<el-form label-width="120px" class="form">
|
||||||
<h1 style="margin: 20px 0 20px 50px">请选择溯源农产品申请</h1>
|
<h1 style="margin: 20px 0 20px 50px">请选择溯源农产品申请</h1>
|
||||||
<el-form-item label="检查批次">
|
<el-form-item label="溯源商品">
|
||||||
<el-select v-model="batch" placeholder="请选择农产品批次" :width="200">
|
<el-select v-model="batch" placeholder="请选择商品" :width="200">
|
||||||
<el-option label="批次A" value="A" />
|
<el-option v-for="(item, index) in goodsList" :key="index" :label="item.goodName" :value="item.id">
|
||||||
<el-option label="批次B" value="B" />
|
<el-tooltip :content="item.goodName" placement="top">
|
||||||
|
<span>{{ item.goodNames }}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@ -50,22 +55,33 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted, reactive } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { getAssetsFile } from '@/utils/index.js';
|
import { getAssetsFile } from '@/utils/index.js';
|
||||||
|
import { goodList, saveRecords } from '@/apis/brand.js';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const productId = route.params.id;
|
const productId = route.query.id;
|
||||||
const product = ref({ name: '加载中...', id: productId });
|
const product = ref({ name: '加载中...', id: productId });
|
||||||
|
|
||||||
|
const goodsList = reactive([]);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 模拟加载产品数据
|
// 模拟加载产品数据
|
||||||
product.value = {
|
product.value = {
|
||||||
id: productId,
|
id: productId,
|
||||||
name: productId == 1 ? '有机苹果' : '绿色蔬菜',
|
name: productId == 1 ? '有机苹果' : '绿色蔬菜',
|
||||||
};
|
};
|
||||||
|
goodList().then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
goodsList.splice(0, goodsList.length, ...res.data);
|
||||||
|
for (let i in goodsList) {
|
||||||
|
goodsList[i].goodNames = goodsList[i].goodName.length > 15 ? goodsList[i].goodName.substring(0, 15) + '...' : goodsList[i].goodName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const batch = ref('');
|
const batch = ref('');
|
||||||
@ -83,14 +99,23 @@ function uploadTraceCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
console.log('提交申请:', {
|
// console.log('提交申请:', {
|
||||||
product: product.value,
|
// product: productId,
|
||||||
batch: batch.value,
|
// batch: batch.value,
|
||||||
detectTime: detectTime.value,
|
// detectTime: detectTime.value,
|
||||||
station: station.value,
|
// station: station.value,
|
||||||
origin: origin.value,
|
// origin: origin.value,
|
||||||
});
|
// });
|
||||||
|
let obj = {
|
||||||
|
goodsId: batch.value,
|
||||||
|
brandId: productId,
|
||||||
|
};
|
||||||
|
saveRecords(obj).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
// console.log(res);
|
||||||
ElMessage.success('提交成功!');
|
ElMessage.success('提交成功!');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<el-col v-for="product in products" :key="product.id" :span="6">
|
<el-col v-for="product in products" :key="product.id" :span="6">
|
||||||
<el-card class="box-card" :body-style="{ padding: '8px', height: '100%' }">
|
<el-card class="box-card" :body-style="{ padding: '8px', height: '100%' }">
|
||||||
<div class="flex-column">
|
<div class="flex-column">
|
||||||
<img :src="getAssetsFile(product.imageUrl)" alt="商品图" class="img" />
|
<img :src="getAssetsFile(product.imgPath)" alt="商品图" class="img" />
|
||||||
<div class="flex-1 flex-around">
|
<div class="flex-1 flex-around">
|
||||||
<p>{{ product.name }}</p>
|
<p>{{ product.title }}</p>
|
||||||
<el-button type="success" class="button" @click="gotoApplication(product.id)">我要申请</el-button>
|
<el-button type="success" class="button" @click="gotoApplication(product.id)">我要申请</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { getApplyList } from '@/apis/brand';
|
import { getApplyList, brandList } from '@/apis/brand';
|
||||||
import { getAssetsFile } from '@/utils/index.js';
|
import { getAssetsFile } from '@/utils/index.js';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const products = ref([]);
|
const products = ref([]);
|
||||||
@ -29,18 +30,12 @@ const products = ref([]);
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
const applyData = [
|
const applyData = [
|
||||||
{ id: 1, name: '耿马绿色蔬菜', imageUrl: 'images/brand/11.png' },
|
{ id: 1, title: '耿马绿色蔬菜', imgPath: 'images/brand/11.png' },
|
||||||
{ id: 2, name: '云南高山茶', imageUrl: 'images/brand/12.png' },
|
{ id: 2, title: '耿马云斛石斛', imgPath: 'images/brand/12.png' },
|
||||||
{ id: 3, name: '新疆大枣', imageUrl: 'images/brand/13.png' },
|
{ id: 3, title: '耿马蒸酶茶', imgPath: 'images/brand/15.png' },
|
||||||
{ id: 4, name: '东北大米', imageUrl: 'images/brand/14.png' },
|
{ id: 4, title: '孟定蔬菜', imgPath: 'images/brand/14.png' },
|
||||||
{ id: 5, name: '山东苹果', imageUrl: 'images/brand/15.png' },
|
{ id: 5, title: '耿马芒抗金丝凤梨', imgPath: 'images/brand/16.png' },
|
||||||
{ id: 6, name: '四川泡菜', imageUrl: 'images/brand/16.png' },
|
// { id: 6, name: '四川泡菜', imgPath: 'images/brand/16.png' },
|
||||||
{ id: 7, name: '江苏阳澄湖大闸蟹', imageUrl: 'images/brand/11.png' },
|
|
||||||
{ id: 8, name: '海南椰子', imageUrl: 'images/brand/12.png' },
|
|
||||||
{ id: 9, name: '广东早茶', imageUrl: 'images/brand/13.png' },
|
|
||||||
{ id: 10, name: '北京烤鸭', imageUrl: 'images/brand/14.png' },
|
|
||||||
{ id: 11, name: '西藏青稞酒', imageUrl: 'images/brand/15.png' },
|
|
||||||
{ id: 12, name: '青海牦牛肉', imageUrl: 'images/brand/16.png' },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function gotoApplication(id) {
|
function gotoApplication(id) {
|
||||||
@ -52,9 +47,20 @@ function data() {
|
|||||||
products.value = applyData;
|
products.value = applyData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getApplyData() {
|
||||||
|
brandList().then((res) => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.code === 200) {
|
||||||
|
products.value = res.data.records;
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.errmsg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 组件挂载时获取数据
|
// 组件挂载时获取数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// getApplyList;
|
// getApplyData();
|
||||||
data();
|
data();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -37,35 +37,42 @@
|
|||||||
<!-- 产品列表 -->
|
<!-- 产品列表 -->
|
||||||
<el-card shadow="hover" style="border-radius: 16px" class="product-card">
|
<el-card shadow="hover" style="border-radius: 16px" class="product-card">
|
||||||
<!-- 状态筛选 -->
|
<!-- 状态筛选 -->
|
||||||
<el-tabs v-model="activeStatus" class="tabs-wrapper">
|
<el-tabs v-model="activeStatus" class="tabs-wrapper" @tab-change="changeStatus">
|
||||||
<el-tab-pane label="已授权" name="authorized" />
|
<el-tab-pane label="已授权" name="1" />
|
||||||
<el-tab-pane label="审批中" name="approving" />
|
<el-tab-pane label="审批中" name="2" />
|
||||||
<el-tab-pane label="已失效" name="expired" />
|
<el-tab-pane label="被驳回" name="3" />
|
||||||
|
<el-tab-pane label="已失效" name="4" />
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
<div class="product-list">
|
<div class="product-list">
|
||||||
<div v-for="(product, index) in filteredProducts" :key="product.id" class="product-item" :class="{ 'border-top': index > 0 }">
|
<div v-for="(product, index) in products" :key="product.id" class="product-item" :class="{ 'border-top': index > 0 }">
|
||||||
<div class="product-info">
|
<div class="product-info">
|
||||||
<img class="product-img" :src="product.img" alt="product" />
|
<img class="product-img" :src="product.goodsUrl" alt="product" />
|
||||||
<div class="product-text">
|
<div class="product-text">
|
||||||
<span class="product-name">{{ product.name }}</span>
|
<span class="product-name">{{ product.productName }}</span>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<label>检测批次:</label>
|
<label>检测批次:</label>
|
||||||
<span>{{ product.batch }}</span>
|
<span>2</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<label>授权期限:</label>
|
<label>授权期限:</label>
|
||||||
<span>{{ product.duration }}</span>
|
<span
|
||||||
|
>{{ product.timeNum
|
||||||
|
}}{{ product.timeNumUnit === 1 ? '天' : product.timeNumUnit === 2 ? '月' : product.timeNumUnit === 3 ? '年' : '' }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<label>到期时间:</label>
|
<label>到期时间:</label>
|
||||||
<span class="text-expire">{{ product.expireDate }}</span>
|
<span class="text-expire">{{ product.endTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="product-action">
|
<div class="product-action">
|
||||||
<el-tag :class="statusClass(activeStatus)" :type="statusTypeMap[product.status]">{{ product.statusLabel }}</el-tag>
|
<el-tag v-if="product.status == 1" size="large" class="text-success status-tag" type="success">已授权</el-tag>
|
||||||
|
<el-tag v-if="product.status == 2" size="large" class="text-warning status-tag" type="warning">审批中</el-tag>
|
||||||
|
<el-tag v-if="product.status == 3" size="large" class="text-danger status-tag" type="danger">被驳回</el-tag>
|
||||||
|
<el-tag v-if="product.status == 4" size="large" class="text-info status-tag" type="info">已失效</el-tag>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="product.status === 'authorized'"
|
v-if="product.status == 1"
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
:icon="Edit"
|
:icon="Edit"
|
||||||
@ -95,18 +102,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { getAssetsFile } from '@/utils/index.js';
|
import { getAssetsFile } from '@/utils/index.js';
|
||||||
import { getProducts } from '@/apis/brand';
|
import { authList, getProducts } from '@/apis/brand';
|
||||||
import { Edit } from '@element-plus/icons-vue';
|
import { Edit } from '@element-plus/icons-vue';
|
||||||
|
|
||||||
const activeStatus = ref('authorized');
|
const activeStatus = ref('1');
|
||||||
|
|
||||||
const statusTypeMap = {
|
|
||||||
authorized: 'success',
|
|
||||||
approving: 'warning',
|
|
||||||
expired: 'danger',
|
|
||||||
};
|
|
||||||
|
|
||||||
const products = ref([
|
const products = ref([
|
||||||
{
|
{
|
||||||
@ -171,13 +172,7 @@ const products = ref([
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const statusClass = (tab) => {
|
// const filteredProducts = computed(() => products.value.filter((p) => p.status === activeStatus.value));
|
||||||
if (tab === 'approving') return 'text-warning status-tag';
|
|
||||||
if (tab === 'expired') return 'text-danger status-tag';
|
|
||||||
return 'text-success status-tag';
|
|
||||||
};
|
|
||||||
|
|
||||||
const filteredProducts = computed(() => products.value.filter((p) => p.status === activeStatus.value));
|
|
||||||
const certificateDialogVisible = ref(false);
|
const certificateDialogVisible = ref(false);
|
||||||
const currentCertificateImg = ref('');
|
const currentCertificateImg = ref('');
|
||||||
|
|
||||||
@ -187,6 +182,28 @@ const handleCertificate = (product) => {
|
|||||||
currentCertificateImg.value = getAssetsFile('images/brand/sqzs.png'); // 你可以换成真实字段,如 product.certificate
|
currentCertificateImg.value = getAssetsFile('images/brand/sqzs.png'); // 你可以换成真实字段,如 product.certificate
|
||||||
certificateDialogVisible.value = true;
|
certificateDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeStatus = (tab) => {
|
||||||
|
getAuthList(tab);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAuthList = (status) => {
|
||||||
|
products.value = [];
|
||||||
|
authList({ status: status }).then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
products.value = res.data.records;
|
||||||
|
for (let i in products.value) {
|
||||||
|
if (products.value[i].endTime) {
|
||||||
|
products.value[i].endTime = products.value[i].endTime.split(' ')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getAuthList(1);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@ -348,9 +365,9 @@ const handleCertificate = (product) => {
|
|||||||
}
|
}
|
||||||
.detail-item {
|
.detail-item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 16px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
gap: 10px;
|
||||||
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
<template>
|
||||||
|
<div class="inventory-charts">
|
||||||
|
<custom-echart-line-line :chart-data="chartsData.valData" height="100%" :option="chartsData.option" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue';
|
||||||
|
const legendData = reactive(['分拣', '包装']);
|
||||||
|
let dataItem = reactive([100, 90, 200, 250, 240, 275, 120, 300, 320, 270, 290, 120]);
|
||||||
|
let colors = reactive({
|
||||||
|
分拣: '#3685fe',
|
||||||
|
包装: '#41b879',
|
||||||
|
});
|
||||||
|
let colorBg = reactive({
|
||||||
|
分拣: [
|
||||||
|
{ offset: 0, color: 'rgba(54,161,255,0.6)' },
|
||||||
|
{ offset: 1, color: 'rgba(25,104,255,0)' },
|
||||||
|
],
|
||||||
|
包装: [
|
||||||
|
{ offset: 0, color: 'rgba(0,255,0,0.6)' },
|
||||||
|
{ offset: 1, color: 'rgba(25,104,255,0)' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const currentMonth = ref(new Date().getMonth() + 1);
|
||||||
|
const yAxisData = computed(() => {
|
||||||
|
let list = [];
|
||||||
|
for (let i = 1; i < 13; i++) {
|
||||||
|
let mouth = i < 10 ? i : i;
|
||||||
|
list.push(mouth + '月');
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
let seriesItem = reactive({
|
||||||
|
type: 'line',
|
||||||
|
stack: 'Total',
|
||||||
|
symbol: 'none',
|
||||||
|
smooth: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let seriesData = computed(() => {
|
||||||
|
let list = [];
|
||||||
|
if (legendData.length && legendData.length > 0) {
|
||||||
|
legendData.forEach((m) => {
|
||||||
|
let val = {
|
||||||
|
...seriesItem,
|
||||||
|
name: m,
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: colorBg[m],
|
||||||
|
global: false, // 缺省为 false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: colors[m],
|
||||||
|
width: 1,
|
||||||
|
type: 'solid',
|
||||||
|
},
|
||||||
|
data: dataItem,
|
||||||
|
};
|
||||||
|
|
||||||
|
list.push(val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
const chartsData = reactive({
|
||||||
|
option: {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '15%',
|
||||||
|
bottom: '1%',
|
||||||
|
top: '3%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow',
|
||||||
|
},
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
confine: true, // 超出范围
|
||||||
|
backgroundColor: 'rgba(17,95,182,0.5)', //设置背景颜色
|
||||||
|
formatter: function (item) {
|
||||||
|
let params = [...item];
|
||||||
|
var res = params[0].name + '<br/>';
|
||||||
|
for (var i = 0, l = params.length; i < l; i++) {
|
||||||
|
res += params[i].value !== '-' ? params[i].marker + params[i].seriesName + ' : ' + params[i].value + ' <br/>' : '';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
left: '30%', // 距离左侧10%的位置
|
||||||
|
top: '0', // 垂直居中
|
||||||
|
itemWidth: 20, // 图例标记的宽度
|
||||||
|
itemHeight: 20, // 图例标记的高度
|
||||||
|
show: true,
|
||||||
|
data: Array.from(legendData),
|
||||||
|
right: '0', // 距离左侧10%的位置
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 10, // 图例文字的字体大小
|
||||||
|
color: '#fff', // 图例文字的颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: true,
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#94A7BD', //轴线和单位颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: yAxisData,
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: ' ',
|
||||||
|
nameTextStyle: {
|
||||||
|
fontSize: 14,
|
||||||
|
color: '#94A7BD',
|
||||||
|
padding: [0, 0, 0, -45],
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: '#94A7BD', //轴线和单位颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#182D46',
|
||||||
|
type: [2, 3],
|
||||||
|
dashOffset: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: seriesData.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.inventory-charts {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,403 @@
|
|||||||
|
<template>
|
||||||
|
<div class="benefit-charts">
|
||||||
|
<custom-echart-mixin :chart-data="handelData" :option="chartsData.option" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue';
|
||||||
|
let itemStyle = reactive({
|
||||||
|
itemStyle: { borderRadius: [8, 8, 0, 0] },
|
||||||
|
});
|
||||||
|
|
||||||
|
let legendList = reactive(['成本', '收入', '繁殖率', '配种成功率']);
|
||||||
|
|
||||||
|
var { data, optionConfig } = {
|
||||||
|
data: [
|
||||||
|
{ name: '已使用', value: 15, itemStyle: { color: '#0096f9' }, startRatio: 0, endRatio: 0.15 },
|
||||||
|
{ name: '未使用', value: 25, itemStyle: { color: '#00e8ce' }, startRatio: 0.15, endRatio: 0.4 },
|
||||||
|
],
|
||||||
|
optionConfig: {},
|
||||||
|
};
|
||||||
|
const getPie3D = (pieData, internalDiameterRatio) => {
|
||||||
|
let series = [];
|
||||||
|
let sumValue = 0;
|
||||||
|
let startValue = 0;
|
||||||
|
let endValue = 0;
|
||||||
|
let legendData = [];
|
||||||
|
let k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3;
|
||||||
|
|
||||||
|
// 为每一个饼图数据,生成一个 series-surface 配置
|
||||||
|
for (let i = 0; i < pieData.length; i++) {
|
||||||
|
sumValue += pieData[i].value;
|
||||||
|
|
||||||
|
let seriesItem = {
|
||||||
|
name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
|
||||||
|
type: 'surface',
|
||||||
|
parametric: true,
|
||||||
|
wireframe: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
pieData: pieData[i],
|
||||||
|
pieStatus: {
|
||||||
|
selected: false,
|
||||||
|
hovered: false,
|
||||||
|
k: k,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
// normal: {
|
||||||
|
// position: "inner",
|
||||||
|
// formatter: (params) => {
|
||||||
|
// return params;
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof pieData[i].itemStyle != 'undefined') {
|
||||||
|
let itemStyle = {};
|
||||||
|
|
||||||
|
typeof pieData[i].itemStyle.color != 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
|
||||||
|
typeof pieData[i].itemStyle.opacity != 'undefined' ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : null;
|
||||||
|
|
||||||
|
seriesItem.itemStyle = itemStyle;
|
||||||
|
}
|
||||||
|
series.push(seriesItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
||||||
|
// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
||||||
|
for (let i = 0; i < series.length; i++) {
|
||||||
|
endValue = startValue + series[i].pieData.value;
|
||||||
|
// console.log(series[i]);
|
||||||
|
series[i].pieData.startRatio = startValue / sumValue;
|
||||||
|
series[i].pieData.endRatio = endValue / sumValue;
|
||||||
|
series[i].parametricEquation = getParametricEquation(
|
||||||
|
series[i].pieData.startRatio,
|
||||||
|
series[i].pieData.endRatio,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
k,
|
||||||
|
series[i].pieData.value
|
||||||
|
);
|
||||||
|
|
||||||
|
startValue = endValue;
|
||||||
|
|
||||||
|
legendData.push(series[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备待返回的配置项,把准备好的 legendData、series 传入。
|
||||||
|
let option = {
|
||||||
|
tooltip: {
|
||||||
|
// backgroundColor: '#053A8D',
|
||||||
|
formatter: (params) => {
|
||||||
|
if (params.seriesName !== 'mouseoutSeries') {
|
||||||
|
return `${
|
||||||
|
params.seriesName
|
||||||
|
}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
|
||||||
|
params.color
|
||||||
|
};"></span>${option.series[params.seriesIndex].pieData.value}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pie2dConfig: {
|
||||||
|
center: ['50%', '40%'],
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'outside',
|
||||||
|
formatter: (params) => {
|
||||||
|
const total = 221.8 + 70.01; // 或动态计算
|
||||||
|
const percent = ((params.value / total) * 100).toFixed(0);
|
||||||
|
return `{name|${params.name}}\n{value|${params.value} 万吨\n(${percent}%)}`;
|
||||||
|
},
|
||||||
|
rich: {
|
||||||
|
name: {
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#ffffff',
|
||||||
|
lineHeight: 20,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#79F5AF',
|
||||||
|
lineHeight: 18,
|
||||||
|
align: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: true,
|
||||||
|
length: 40,
|
||||||
|
length2: 40,
|
||||||
|
lineStyle: { color: '#fff', width: 2 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
graphic: {
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
left: '50%',
|
||||||
|
top: '30%',
|
||||||
|
style: {
|
||||||
|
text: '40.1%',
|
||||||
|
fill: '#FFF',
|
||||||
|
fontSize: 18,
|
||||||
|
padding: [4, 8],
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
left: '20%',
|
||||||
|
top: '60%',
|
||||||
|
style: {
|
||||||
|
text: '59.9%',
|
||||||
|
fill: '#FFF',
|
||||||
|
fontSize: 16,
|
||||||
|
padding: [4, 8],
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
labelLine: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'horizontal', // 设置为水平排列
|
||||||
|
top: 0,
|
||||||
|
data: legendData,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
icon: 'roundRect',
|
||||||
|
formatter: function (name) {
|
||||||
|
let item = data.filter((item) => item.name == name)[0];
|
||||||
|
return `${item.name}`;
|
||||||
|
},
|
||||||
|
// top: '30%', //居右显示
|
||||||
|
},
|
||||||
|
xAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
yAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
zAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
grid3D: {
|
||||||
|
show: false,
|
||||||
|
boxHeight: 4,
|
||||||
|
top: '0%',
|
||||||
|
left: '-2%',
|
||||||
|
// environment: "#021041",
|
||||||
|
viewControl: {
|
||||||
|
distance: 6000,
|
||||||
|
alpha: 60,
|
||||||
|
beta: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: series,
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
||||||
|
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, height) => {
|
||||||
|
// 计算
|
||||||
|
let midRatio = (startRatio + endRatio) / 2;
|
||||||
|
|
||||||
|
let startRadian = startRatio * Math.PI * 2;
|
||||||
|
let endRadian = endRatio * Math.PI * 2;
|
||||||
|
let midRadian = midRatio * Math.PI * 2;
|
||||||
|
|
||||||
|
// 如果只有一个扇形,则不实现选中效果。
|
||||||
|
if (startRatio === 0 && endRatio === 1) {
|
||||||
|
isSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
||||||
|
k = typeof k !== 'undefined' ? k : 1 / 3;
|
||||||
|
|
||||||
|
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
||||||
|
let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
||||||
|
let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
||||||
|
|
||||||
|
// 计算高亮效果的放大比例(未高亮,则比例为 1)
|
||||||
|
let hoverRate = isHovered ? 1.05 : 1;
|
||||||
|
|
||||||
|
// 返回曲面参数方程
|
||||||
|
return {
|
||||||
|
u: {
|
||||||
|
min: -Math.PI,
|
||||||
|
max: Math.PI * 3,
|
||||||
|
step: Math.PI / 32,
|
||||||
|
},
|
||||||
|
|
||||||
|
v: {
|
||||||
|
min: 0,
|
||||||
|
max: Math.PI * 2,
|
||||||
|
step: Math.PI / 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
x: function (u, v) {
|
||||||
|
if (u < startRadian) {
|
||||||
|
return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
if (u > endRadian) {
|
||||||
|
return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
},
|
||||||
|
|
||||||
|
y: function (u, v) {
|
||||||
|
if (u < startRadian) {
|
||||||
|
return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
if (u > endRadian) {
|
||||||
|
return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
},
|
||||||
|
|
||||||
|
z: function (u, v) {
|
||||||
|
if (u < -Math.PI * 0.5) {
|
||||||
|
return Math.sin(u);
|
||||||
|
}
|
||||||
|
if (u > Math.PI * 2.5) {
|
||||||
|
return Math.sin(u);
|
||||||
|
}
|
||||||
|
return Math.sin(v) > 0 ? 1 * height : -1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const chartsData = reactive({
|
||||||
|
option: {
|
||||||
|
// color: ['#3685fe', '#8dcbe9', '#ffd500', '#631f9f'],
|
||||||
|
// title: {
|
||||||
|
// text: ' ',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#333',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// legend: {
|
||||||
|
// show: true,
|
||||||
|
// data: legendList,
|
||||||
|
// left: '0', // 距离左侧10%的位置
|
||||||
|
// top: '0', // 垂直居中
|
||||||
|
// itemWidth: 15, // 图例标记的宽度
|
||||||
|
// itemHeight: 8, // 图例标记的高度
|
||||||
|
// textStyle: {
|
||||||
|
// fontSize: 10, // 图例文字的字体大小
|
||||||
|
// color: '#fff', // 图例文字的颜色
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// barStyle: {
|
||||||
|
// barWidth: 10,
|
||||||
|
// },
|
||||||
|
// dataZoom: [
|
||||||
|
// // {
|
||||||
|
// // type: 'slider', // 滑动条型数据区域缩放组件
|
||||||
|
// // startValue: 0, // 数据窗口起始值的索引
|
||||||
|
// // endValue: 2, // 数据窗口结束值的索引
|
||||||
|
// // },
|
||||||
|
// // {
|
||||||
|
// // type: 'inside', // 支持鼠标滚轮和触控板缩放和平移
|
||||||
|
// // startValue: 0,
|
||||||
|
// // endValue: 2,
|
||||||
|
// // },
|
||||||
|
// ],
|
||||||
|
// yAxis: [
|
||||||
|
// {
|
||||||
|
// type: 'value',
|
||||||
|
// name: ' ',
|
||||||
|
// axisLabel: {
|
||||||
|
// formatter: '{value}',
|
||||||
|
// },
|
||||||
|
// splitLine: {
|
||||||
|
// show: true, // 显示分割线
|
||||||
|
// lineStyle: {
|
||||||
|
// type: 'dashed', // 设置为虚线
|
||||||
|
// width: 0.5, // 分割线宽度
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// itemStyle: { fontSize: 8 },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// grid: {
|
||||||
|
// x: '10%',
|
||||||
|
// x2: '10%',
|
||||||
|
// y: '20%',
|
||||||
|
// y2: '20%',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
valData: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
chartsData.option = getPie3D(data, 0);
|
||||||
|
|
||||||
|
const randomVal = (num) => {
|
||||||
|
let list = [];
|
||||||
|
for (let i = 0; i < legendList.length; i++) {
|
||||||
|
let addNum = [10, 8, 2, 5];
|
||||||
|
let val = {
|
||||||
|
name: num + '月',
|
||||||
|
value: Number(Math.random() * 100 + addNum[i]).toFixed(2),
|
||||||
|
seriesType: i < legendList.length - 2 ? 'bar' : 'line',
|
||||||
|
type: legendList[i],
|
||||||
|
stack: num + '月',
|
||||||
|
};
|
||||||
|
if (val.seriesType == 'line') {
|
||||||
|
val.smooth = 30;
|
||||||
|
val.symbol = 'none';
|
||||||
|
}
|
||||||
|
let lastVal = {
|
||||||
|
...val,
|
||||||
|
...itemStyle,
|
||||||
|
};
|
||||||
|
list[i] = i < legendList.length - 3 ? val : lastVal;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
let handelData = computed(() => {
|
||||||
|
let list = [];
|
||||||
|
let maxMouth = 12;
|
||||||
|
for (let i = 0; i < maxMouth; i++) {
|
||||||
|
let val = randomVal(i + 1);
|
||||||
|
list = [...list, ...val];
|
||||||
|
}
|
||||||
|
|
||||||
|
list.map((m, indexm) => {
|
||||||
|
return { ...m, value: Number(Number(m.value) + Math.random() + indexm).toFixed(0) };
|
||||||
|
});
|
||||||
|
// console.info('handelData', list);
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.benefit-charts {
|
||||||
|
height: 130%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,397 @@
|
|||||||
|
<template>
|
||||||
|
<div class="benefit-charts">
|
||||||
|
<custom-echart-mixin :chart-data="handelData" :option="chartsData.option" height="100%" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue';
|
||||||
|
let itemStyle = reactive({
|
||||||
|
itemStyle: { borderRadius: [8, 8, 0, 0] },
|
||||||
|
});
|
||||||
|
|
||||||
|
let legendList = reactive(['成本', '收入', '繁殖率', '配种成功率']);
|
||||||
|
|
||||||
|
var { data, optionConfig } = {
|
||||||
|
data: [
|
||||||
|
{ name: '豆菜', value: 15, itemStyle: { color: '#938df6' }, startRatio: 0, endRatio: 0.15 },
|
||||||
|
{ name: '茄科', value: 25, itemStyle: { color: '#0ce4d1' }, startRatio: 0.15, endRatio: 0.4 },
|
||||||
|
{ name: '根菜', value: 5, itemStyle: { color: '#2196f3' }, startRatio: 0.15, endRatio: 0.4 },
|
||||||
|
],
|
||||||
|
optionConfig: {},
|
||||||
|
};
|
||||||
|
const getPie3D = (pieData, internalDiameterRatio) => {
|
||||||
|
let series = [];
|
||||||
|
let sumValue = 0;
|
||||||
|
let startValue = 0;
|
||||||
|
let endValue = 0;
|
||||||
|
let legendData = [];
|
||||||
|
let k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3;
|
||||||
|
|
||||||
|
// 为每一个饼图数据,生成一个 series-surface 配置
|
||||||
|
for (let i = 0; i < pieData.length; i++) {
|
||||||
|
sumValue += pieData[i].value;
|
||||||
|
|
||||||
|
let seriesItem = {
|
||||||
|
name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
|
||||||
|
type: 'surface',
|
||||||
|
parametric: true,
|
||||||
|
wireframe: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
pieData: pieData[i],
|
||||||
|
pieStatus: {
|
||||||
|
selected: false,
|
||||||
|
hovered: false,
|
||||||
|
k: k,
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
// normal: {
|
||||||
|
// position: "inner",
|
||||||
|
// formatter: (params) => {
|
||||||
|
// return params;
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
opacity: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof pieData[i].itemStyle != 'undefined') {
|
||||||
|
let itemStyle = {};
|
||||||
|
|
||||||
|
typeof pieData[i].itemStyle.color != 'undefined' ? (itemStyle.color = pieData[i].itemStyle.color) : null;
|
||||||
|
typeof pieData[i].itemStyle.opacity != 'undefined' ? (itemStyle.opacity = pieData[i].itemStyle.opacity) : null;
|
||||||
|
|
||||||
|
seriesItem.itemStyle = itemStyle;
|
||||||
|
}
|
||||||
|
series.push(seriesItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
|
||||||
|
// 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
|
||||||
|
for (let i = 0; i < series.length; i++) {
|
||||||
|
endValue = startValue + series[i].pieData.value;
|
||||||
|
// console.log(series[i]);
|
||||||
|
series[i].pieData.startRatio = startValue / sumValue;
|
||||||
|
series[i].pieData.endRatio = endValue / sumValue;
|
||||||
|
series[i].parametricEquation = getParametricEquation(
|
||||||
|
series[i].pieData.startRatio,
|
||||||
|
series[i].pieData.endRatio,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
k,
|
||||||
|
series[i].pieData.value
|
||||||
|
);
|
||||||
|
|
||||||
|
startValue = endValue;
|
||||||
|
|
||||||
|
legendData.push(series[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备待返回的配置项,把准备好的 legendData、series 传入。
|
||||||
|
let option = {
|
||||||
|
tooltip: {
|
||||||
|
backgroundColor: '#053A8D',
|
||||||
|
formatter: (params) => {
|
||||||
|
if (params.seriesName !== 'mouseoutSeries') {
|
||||||
|
return `${
|
||||||
|
params.seriesName
|
||||||
|
}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
|
||||||
|
params.color
|
||||||
|
};"></span>${option.series[params.seriesIndex].pieData.value}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
graphic: {
|
||||||
|
elements: [
|
||||||
|
// {
|
||||||
|
// type: 'polyline',
|
||||||
|
// shape: {
|
||||||
|
// points: [
|
||||||
|
// [100, 150], // 起点
|
||||||
|
// [150, 100], // 水平右移
|
||||||
|
// [10, 200], // 垂直下移
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// style: { stroke: '#FF0000', lineWidth: 2 },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'line',
|
||||||
|
// shape: { x1: 80, y1: 150, x2: 0, y2: 200 },
|
||||||
|
// style: { stroke: '#fff', lineWidth: 2 },
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
left: '65%',
|
||||||
|
top: '30%',
|
||||||
|
style: {
|
||||||
|
text: '24500',
|
||||||
|
fill: '#FFF',
|
||||||
|
fontSize: 18,
|
||||||
|
padding: [4, 8],
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
left: '60%',
|
||||||
|
top: '55%',
|
||||||
|
style: {
|
||||||
|
text: '32500',
|
||||||
|
fill: '#FFF',
|
||||||
|
fontSize: 16,
|
||||||
|
padding: [4, 8],
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
left: '15%',
|
||||||
|
top: '50%',
|
||||||
|
style: {
|
||||||
|
text: '31100',
|
||||||
|
fill: '#FFF',
|
||||||
|
fontSize: 16,
|
||||||
|
padding: [4, 8],
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'horizontal', // 设置为水平排列
|
||||||
|
left: 'left', // 水平居中
|
||||||
|
top: 0,
|
||||||
|
data: legendData,
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: 15,
|
||||||
|
},
|
||||||
|
itemWidth: 10,
|
||||||
|
itemHeight: 10,
|
||||||
|
icon: 'roundRect',
|
||||||
|
formatter: function (name) {
|
||||||
|
let item = data.filter((item) => item.name == name)[0];
|
||||||
|
return `${item.name}`;
|
||||||
|
},
|
||||||
|
// top: '30%', //居右显示
|
||||||
|
},
|
||||||
|
xAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
yAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
zAxis3D: {
|
||||||
|
min: -1.3,
|
||||||
|
max: 1.3,
|
||||||
|
},
|
||||||
|
grid3D: {
|
||||||
|
show: false,
|
||||||
|
boxHeight: 4,
|
||||||
|
top: '0%',
|
||||||
|
left: '-2%',
|
||||||
|
// environment: "#021041",
|
||||||
|
viewControl: {
|
||||||
|
distance: 6000,
|
||||||
|
alpha: 60,
|
||||||
|
beta: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
series: series,
|
||||||
|
};
|
||||||
|
return option;
|
||||||
|
};
|
||||||
|
// 生成扇形的曲面参数方程,用于 series-surface.parametricEquation
|
||||||
|
const getParametricEquation = (startRatio, endRatio, isSelected, isHovered, k, height) => {
|
||||||
|
// 计算
|
||||||
|
let midRatio = (startRatio + endRatio) / 2;
|
||||||
|
|
||||||
|
let startRadian = startRatio * Math.PI * 2;
|
||||||
|
let endRadian = endRatio * Math.PI * 2;
|
||||||
|
let midRadian = midRatio * Math.PI * 2;
|
||||||
|
|
||||||
|
// 如果只有一个扇形,则不实现选中效果。
|
||||||
|
if (startRatio === 0 && endRatio === 1) {
|
||||||
|
isSelected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
|
||||||
|
k = typeof k !== 'undefined' ? k : 1 / 3;
|
||||||
|
|
||||||
|
// 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
|
||||||
|
let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
|
||||||
|
let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
|
||||||
|
|
||||||
|
// 计算高亮效果的放大比例(未高亮,则比例为 1)
|
||||||
|
let hoverRate = isHovered ? 1.05 : 1;
|
||||||
|
|
||||||
|
// 返回曲面参数方程
|
||||||
|
return {
|
||||||
|
u: {
|
||||||
|
min: -Math.PI,
|
||||||
|
max: Math.PI * 3,
|
||||||
|
step: Math.PI / 32,
|
||||||
|
},
|
||||||
|
|
||||||
|
v: {
|
||||||
|
min: 0,
|
||||||
|
max: Math.PI * 2,
|
||||||
|
step: Math.PI / 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
x: function (u, v) {
|
||||||
|
if (u < startRadian) {
|
||||||
|
return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
if (u > endRadian) {
|
||||||
|
return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
},
|
||||||
|
|
||||||
|
y: function (u, v) {
|
||||||
|
if (u < startRadian) {
|
||||||
|
return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
if (u > endRadian) {
|
||||||
|
return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
}
|
||||||
|
return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
|
||||||
|
},
|
||||||
|
|
||||||
|
z: function (u, v) {
|
||||||
|
if (u < -Math.PI * 0.5) {
|
||||||
|
return Math.sin(u);
|
||||||
|
}
|
||||||
|
if (u > Math.PI * 2.5) {
|
||||||
|
return Math.sin(u);
|
||||||
|
}
|
||||||
|
return Math.sin(v) > 0 ? 1 * height : -1;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const chartsData = reactive({
|
||||||
|
option: {
|
||||||
|
// color: ['#3685fe', '#8dcbe9', '#ffd500', '#631f9f'],
|
||||||
|
// title: {
|
||||||
|
// text: ' ',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#333',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// legend: {
|
||||||
|
// show: true,
|
||||||
|
// data: legendList,
|
||||||
|
// left: '0', // 距离左侧10%的位置
|
||||||
|
// top: '0', // 垂直居中
|
||||||
|
// itemWidth: 15, // 图例标记的宽度
|
||||||
|
// itemHeight: 8, // 图例标记的高度
|
||||||
|
// textStyle: {
|
||||||
|
// fontSize: 10, // 图例文字的字体大小
|
||||||
|
// color: '#fff', // 图例文字的颜色
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// barStyle: {
|
||||||
|
// barWidth: 10,
|
||||||
|
// },
|
||||||
|
// dataZoom: [
|
||||||
|
// // {
|
||||||
|
// // type: 'slider', // 滑动条型数据区域缩放组件
|
||||||
|
// // startValue: 0, // 数据窗口起始值的索引
|
||||||
|
// // endValue: 2, // 数据窗口结束值的索引
|
||||||
|
// // },
|
||||||
|
// // {
|
||||||
|
// // type: 'inside', // 支持鼠标滚轮和触控板缩放和平移
|
||||||
|
// // startValue: 0,
|
||||||
|
// // endValue: 2,
|
||||||
|
// // },
|
||||||
|
// ],
|
||||||
|
// yAxis: [
|
||||||
|
// {
|
||||||
|
// type: 'value',
|
||||||
|
// name: ' ',
|
||||||
|
// axisLabel: {
|
||||||
|
// formatter: '{value}',
|
||||||
|
// },
|
||||||
|
// splitLine: {
|
||||||
|
// show: true, // 显示分割线
|
||||||
|
// lineStyle: {
|
||||||
|
// type: 'dashed', // 设置为虚线
|
||||||
|
// width: 0.5, // 分割线宽度
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// itemStyle: { fontSize: 8 },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// grid: {
|
||||||
|
// x: '10%',
|
||||||
|
// x2: '10%',
|
||||||
|
// y: '20%',
|
||||||
|
// y2: '20%',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
valData: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
chartsData.option = getPie3D(data, 0);
|
||||||
|
|
||||||
|
const randomVal = (num) => {
|
||||||
|
let list = [];
|
||||||
|
for (let i = 0; i < legendList.length; i++) {
|
||||||
|
let addNum = [10, 8, 2, 5];
|
||||||
|
let val = {
|
||||||
|
name: num + '月',
|
||||||
|
value: Number(Math.random() * 100 + addNum[i]).toFixed(2),
|
||||||
|
seriesType: i < legendList.length - 2 ? 'bar' : 'line',
|
||||||
|
type: legendList[i],
|
||||||
|
stack: num + '月',
|
||||||
|
};
|
||||||
|
if (val.seriesType == 'line') {
|
||||||
|
val.smooth = 30;
|
||||||
|
val.symbol = 'none';
|
||||||
|
}
|
||||||
|
let lastVal = {
|
||||||
|
...val,
|
||||||
|
...itemStyle,
|
||||||
|
};
|
||||||
|
list[i] = i < legendList.length - 3 ? val : lastVal;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
let handelData = computed(() => {
|
||||||
|
let list = [];
|
||||||
|
let maxMouth = 12;
|
||||||
|
for (let i = 0; i < maxMouth; i++) {
|
||||||
|
let val = randomVal(i + 1);
|
||||||
|
list = [...list, ...val];
|
||||||
|
}
|
||||||
|
|
||||||
|
list.map((m, indexm) => {
|
||||||
|
return { ...m, value: Number(Number(m.value) + Math.random() + indexm).toFixed(0) };
|
||||||
|
});
|
||||||
|
// console.info('handelData', list);
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.benefit-charts {
|
||||||
|
height: 130%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,231 @@
|
|||||||
|
<template>
|
||||||
|
<div class="business">
|
||||||
|
<div style="display: flex; flex-direction: column; justify-content: flex-start; width: 60%">
|
||||||
|
<div class="business-left">
|
||||||
|
<custom-echart-water-droplet width="100%" height="100%" :option="state.option" />
|
||||||
|
</div>
|
||||||
|
<div class="business-title" style="z-index: 99; color: #fff">通过率</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="business-right">
|
||||||
|
<div class="business-title">提交申请数量</div>
|
||||||
|
<ul class="business-info">
|
||||||
|
<li class="success">
|
||||||
|
<span>253家</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="business-right">
|
||||||
|
<div class="business-title">审核通过数量</div>
|
||||||
|
<ul class="business-info">
|
||||||
|
<li class="success">
|
||||||
|
<span>101家</span>
|
||||||
|
</li>
|
||||||
|
<!-- <li class="warning">
|
||||||
|
<b>临期</b>
|
||||||
|
<span>5家</span>
|
||||||
|
</li>
|
||||||
|
<li class="danger">
|
||||||
|
<b>已过期</b>
|
||||||
|
<span>0家</span>
|
||||||
|
</li> -->
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from 'vue';
|
||||||
|
import { isEmpty } from '@/utils';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
option: {
|
||||||
|
backgroundColor: 'transparent', //背景色
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
type: 'liquidFill',
|
||||||
|
radius: '80%',
|
||||||
|
center: ['50%', '50%'],
|
||||||
|
backgroundStyle: {
|
||||||
|
color: 'transparent',
|
||||||
|
},
|
||||||
|
data: [],
|
||||||
|
amplitude: 12, //水波振幅
|
||||||
|
label: {
|
||||||
|
position: ['50%', '50%'],
|
||||||
|
// formatter: 0.3998 * 100 + '%', //显示文本,
|
||||||
|
textStyle: {
|
||||||
|
fontSize: '20px', //文本字号,
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outline: {
|
||||||
|
borderDistance: 2,
|
||||||
|
itemStyle: {
|
||||||
|
borderWidth: 2,
|
||||||
|
borderColor: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 1,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: 'rgba(71, 202, 219, 0.5)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.6,
|
||||||
|
color: 'rgba(45, 209, 185, 0.5)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: 'rgba(13, 204, 163, 0.5)',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
globalCoord: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear', // 线性渐变
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: 'rgba(13, 204, 163, 0.6)' },
|
||||||
|
{ offset: 1, color: 'rgba(71, 202, 219, 1)' },
|
||||||
|
],
|
||||||
|
global: false, // 默认为 false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
(val) => {
|
||||||
|
if (!isEmpty(val)) {
|
||||||
|
state.option.series[0].data = [0, val.percent];
|
||||||
|
state.option.series[0].label.formatter = val.percent * 100 + '%';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.business-right {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.business-left {
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
.business {
|
||||||
|
width: 100%;
|
||||||
|
height: calc((100vh - 330px) / 3 - 50px);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&-title {
|
||||||
|
width: 160px;
|
||||||
|
margin: 0 auto;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 26px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
text-align: center;
|
||||||
|
color: #ffffff;
|
||||||
|
text-shadow: 2px 0px 10px 0px #01eeff;
|
||||||
|
background: url('@/assets/images/business/bg_title.png');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
text-shadow:
|
||||||
|
0 0 10px #01eeff,
|
||||||
|
0 0 20px #01eeff,
|
||||||
|
0 0 30px #01eeff,
|
||||||
|
0 0 40px #01eeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-left,
|
||||||
|
&-right {
|
||||||
|
@include flex-column();
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-info {
|
||||||
|
width: 100%;
|
||||||
|
@include flex-column();
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
li {
|
||||||
|
@include flex-column();
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #fff;
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
b {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
display: inline-block;
|
||||||
|
content: '';
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.success {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
span {
|
||||||
|
color: #01faf9;
|
||||||
|
}
|
||||||
|
b {
|
||||||
|
&::before {
|
||||||
|
background-color: #01faf9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.warning {
|
||||||
|
span {
|
||||||
|
color: #fef906;
|
||||||
|
}
|
||||||
|
b {
|
||||||
|
&::before {
|
||||||
|
background-color: #fef906;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.danger {
|
||||||
|
span {
|
||||||
|
color: #fc0003;
|
||||||
|
}
|
||||||
|
b {
|
||||||
|
&::before {
|
||||||
|
background-color: #fc0003;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,207 @@
|
|||||||
|
<template>
|
||||||
|
<centerMap
|
||||||
|
:dialog-title="'经营主体'"
|
||||||
|
:marker-data="markerData"
|
||||||
|
:bg-image="'images/vsualized/mapopup1.png'"
|
||||||
|
:dialog-width="240"
|
||||||
|
@mapclick="doMapclick"
|
||||||
|
>
|
||||||
|
<template #header>
|
||||||
|
<div class="buiness-map-pop-header">
|
||||||
|
<div class="title">{{ currentRegion && currentRegion.name ? currentRegion.name : '经营主体' }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #dialogContent>
|
||||||
|
<div class="buiness-map-pop-content">
|
||||||
|
<div class="addr">
|
||||||
|
<el-icon :size="'18px'" :color="'#fff'">
|
||||||
|
<LocationFilled />
|
||||||
|
</el-icon>
|
||||||
|
{{ testInfo.addr || ' --' }}
|
||||||
|
</div>
|
||||||
|
<div class="tips-warp">
|
||||||
|
<div class="label">负责人:</div>
|
||||||
|
<div class="val">{{ testInfo.user || '--' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="tips-warp">
|
||||||
|
<div class="label">联系方式:</div>
|
||||||
|
<div class="val">{{ testInfo.tel || '--' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="tips-warp">
|
||||||
|
<div class="label">注册资本:</div>
|
||||||
|
<div class="val">{{ testInfo.capital || '--' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="tips-warp">
|
||||||
|
<div class="label">成立时间:</div>
|
||||||
|
<div class="val">{{ testInfo.time || '--' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="tips-warp">
|
||||||
|
<div class="label">信用等级:</div>
|
||||||
|
<div class="val">{{ testInfo.credit || '--' }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="img-list">
|
||||||
|
<div class="img-item">
|
||||||
|
<el-image
|
||||||
|
style="width: 80px; height: 60px; cursor: pointer"
|
||||||
|
:preview-src-list="
|
||||||
|
testInfo.imglist.map((m) => {
|
||||||
|
return getAssetsFile(m);
|
||||||
|
})
|
||||||
|
"
|
||||||
|
:src="getAssetsFile(testInfo.imglist[0])"
|
||||||
|
fit="cover"
|
||||||
|
lazy
|
||||||
|
/>
|
||||||
|
<div class="img-name">营业执照</div>
|
||||||
|
</div>
|
||||||
|
<div class="img-item">
|
||||||
|
<el-image
|
||||||
|
style="width: 80px; height: 60px; cursor: pointer"
|
||||||
|
:preview-src-list="
|
||||||
|
testInfo.imglist.map((m) => {
|
||||||
|
return getAssetsFile(m);
|
||||||
|
})
|
||||||
|
"
|
||||||
|
:src="getAssetsFile(testInfo.imglist[1])"
|
||||||
|
fit="cover"
|
||||||
|
lazy
|
||||||
|
/>
|
||||||
|
<div class="img-name">经营许可证</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="img-item">
|
||||||
|
<el-image
|
||||||
|
style="width: 80px; height: 60px; cursor: pointer"
|
||||||
|
:preview-src-list="
|
||||||
|
testInfo.imglist.map((m) => {
|
||||||
|
return getAssetsFile(m);
|
||||||
|
})
|
||||||
|
"
|
||||||
|
:src="getAssetsFile(testInfo.imglist[2])"
|
||||||
|
fit="cover"
|
||||||
|
lazy
|
||||||
|
/>
|
||||||
|
<div class="img-name">其他证件</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</centerMap>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { isEmpty, getAssetsFile } from '@/utils';
|
||||||
|
|
||||||
|
const list = reactive([
|
||||||
|
{ title: '年总产值', value: 3.49, color: '#01FEFD', unit: '亿元' },
|
||||||
|
{ title: '年人均收入', value: 6.98, color: '#FEF906', unit: '万元' },
|
||||||
|
]);
|
||||||
|
let testInfo = reactive({});
|
||||||
|
let currentRegion = ref(null);
|
||||||
|
const doMapclick = (data) => {
|
||||||
|
currentRegion.value = data;
|
||||||
|
if (data.name == '永星生产加工企业') {
|
||||||
|
testInfo = {
|
||||||
|
addr: '云南省临沧市耿马傣族佤族自治县孟定镇101号',
|
||||||
|
user: '张强',
|
||||||
|
tel: '15331683325',
|
||||||
|
capital: '500万',
|
||||||
|
time: '2018年12月1日',
|
||||||
|
credit: 'AA',
|
||||||
|
imglist: ['images/business/b1-1.png', 'images/business/b1-2.png', 'images/business/b1-3.png'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (data.name == '欣欣生产加工企业') {
|
||||||
|
testInfo = {
|
||||||
|
addr: '云南省临沧市耿马傣族佤族自治耿马镇102号',
|
||||||
|
user: '李欣',
|
||||||
|
tel: '13713575206',
|
||||||
|
capital: '600万',
|
||||||
|
time: '2020年10月1日',
|
||||||
|
credit: 'AA',
|
||||||
|
imglist: ['images/business/b2-1.png', 'images/business/b1-2.png', 'images/business/b1-2.png'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let markerData = reactive([
|
||||||
|
// 示例数据点,实际应用中应替换为真实的数据
|
||||||
|
{
|
||||||
|
name: '永星生产加工企业',
|
||||||
|
value: [99.081993, 23.524045, 150], // 经度, 纬度, 数值
|
||||||
|
symbol: 'image://' + getAssetsFile('images/vsualized/marker.png'),
|
||||||
|
itemStyle: {
|
||||||
|
color: '#4bffb4', //
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '欣欣生产加工企业',
|
||||||
|
value: [99.402267, 23.538889, 150], // 经度, 纬度, 数值
|
||||||
|
symbol: 'image://' + getAssetsFile('images/vsualized/marker.png'),
|
||||||
|
itemStyle: {
|
||||||
|
color: '#4bffb4', // 勐永镇的颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.buiness-map-pop-header {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 3px;
|
||||||
|
.title,
|
||||||
|
.value {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
color: $color-white;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.buiness-map-pop-content {
|
||||||
|
width: 100%;
|
||||||
|
.addr {
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
color: #fff;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.tips-warp {
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
text-align: left;
|
||||||
|
margin: 6px 0;
|
||||||
|
.label {
|
||||||
|
color: #fef906;
|
||||||
|
}
|
||||||
|
.val {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.img-list {
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 10;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
.img-item {
|
||||||
|
width: calc((100% - 10px) / 2);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
.el-image {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
.img-name {
|
||||||
|
color: #fff;
|
||||||
|
padding: 6px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,161 @@
|
|||||||
|
<template>
|
||||||
|
<div class="demo device-charts" style="height: 90%">
|
||||||
|
<div class="list-item-header item-warp" :style="{ flex: listKeys.length }">
|
||||||
|
<template v-for="(h, indexh) in listKeys" :key="indexh">
|
||||||
|
<div class="item-td" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">{{ listKeysHeader[h] }}</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<vue3ScrollSeamless class="scroll-wrap" :class-options="classOptions" :data-list="datalist">
|
||||||
|
<div v-for="(item, index) in datalist" :key="index" class="list-item">
|
||||||
|
<div class="list-item-content">
|
||||||
|
<div class="list-item-boday item-warp" :style="{ flex: listKeys.length }">
|
||||||
|
<template v-for="(b, indexb) in listKeys" :key="indexb">
|
||||||
|
<div class="item-td" :class="item.status == 1 ? 'td-title' : 'td-warn'" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">
|
||||||
|
<span v-if="b == 'num'">
|
||||||
|
{{ item[b] }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="b == 'duration'" class="duration">
|
||||||
|
<span class="val">{{ item[b] + 'h' }}</span>
|
||||||
|
<div class="pro">
|
||||||
|
<customProgress height="5px" :percent="item.percent" inactive-bg="#081931"></customProgress>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
{{ item[b] == 0 ? '待机' : '运行' }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</vue3ScrollSeamless>
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted, computed, reactive } from 'vue';
|
||||||
|
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||||
|
import customProgress from '@/components/customProgress.vue';
|
||||||
|
const props = defineProps({
|
||||||
|
// items: {
|
||||||
|
// type: Array,
|
||||||
|
// default: () => [],
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
|
||||||
|
let list = reactive([
|
||||||
|
{ num: '投喂机', duration: '3.7', status: 1 },
|
||||||
|
{ num: '喂水机', duration: '10.0', status: 1 },
|
||||||
|
{ num: '投喂机', duration: '6.4', status: 1 },
|
||||||
|
{ num: '喂水机', duration: '3.9', status: 1 },
|
||||||
|
{ num: '投喂机', duration: '3.6', status: 0 },
|
||||||
|
{ num: '喂水机', duration: '4.5', status: 1 },
|
||||||
|
{ num: '投喂机', duration: '5.6', status: 1 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const listKeys = reactive(['num', 'status', 'duration']);
|
||||||
|
const listKeysHeader = reactive({
|
||||||
|
num: '设备编号',
|
||||||
|
status: '设备状态',
|
||||||
|
duration: '设备今日运行时长',
|
||||||
|
});
|
||||||
|
|
||||||
|
let datalist = computed(() => {
|
||||||
|
return list.map((m) => {
|
||||||
|
return {
|
||||||
|
...m,
|
||||||
|
percent: Number((Number(parseInt(m.duration) / max.value) * 100).toFixed(0)),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let max = computed(() => {
|
||||||
|
let valueList = new Set(list.map((item) => item.duration));
|
||||||
|
let sortValue = [...valueList].sort((a, b) => b - a) || [];
|
||||||
|
// console.info('valueList', sortValue);
|
||||||
|
return sortValue.length ? sortValue[0] : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const classOptions = {
|
||||||
|
singleHeight: 48,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.device-charts {
|
||||||
|
margin-top: 8px;
|
||||||
|
.scroll-wrap {
|
||||||
|
height: 80%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 4px auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.list-item-header {
|
||||||
|
background: #144482;
|
||||||
|
font-size: 10px;
|
||||||
|
width: 100%;
|
||||||
|
.item-td {
|
||||||
|
padding: 8px 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-item-boday {
|
||||||
|
background: transparent;
|
||||||
|
width: 100%;
|
||||||
|
.item-td {
|
||||||
|
padding: 4px 6px;
|
||||||
|
&.td-title {
|
||||||
|
color: #6beff9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.td-warn {
|
||||||
|
color: red !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-warp {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
.item-td {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.duration {
|
||||||
|
width: 100%;
|
||||||
|
.val,
|
||||||
|
.pro {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.val {
|
||||||
|
width: 50px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
.pro {
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-item {
|
||||||
|
// border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
|
||||||
|
line-height: 18px;
|
||||||
|
|
||||||
|
.list-item-content {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo {
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
// margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,196 @@
|
|||||||
|
<template>
|
||||||
|
<customEchartHyalineCake :chart-data="dataList" :option="option" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
|
||||||
|
/* --------------- 左中饼图 --------------- */
|
||||||
|
// #region
|
||||||
|
const dataList = ref([
|
||||||
|
{
|
||||||
|
name: '豆菜类作物 25万亩',
|
||||||
|
value: 60.8,
|
||||||
|
money: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '根菜类作物 20万亩',
|
||||||
|
value: 44.4,
|
||||||
|
money: 88,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '叶菜类作物 10万亩',
|
||||||
|
value: 24.3,
|
||||||
|
money: 92,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '茄科类作物 20万亩',
|
||||||
|
value: 32.7,
|
||||||
|
money: 56,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '其他蔬菜作物 20万亩',
|
||||||
|
value: 32.9,
|
||||||
|
money: 18,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const option = reactive({
|
||||||
|
k: 0.3,
|
||||||
|
opacity: 1,
|
||||||
|
itemGap: 0,
|
||||||
|
autoItemHeight: 2,
|
||||||
|
grid3D: {
|
||||||
|
show: false,
|
||||||
|
boxHeight: 4, //厚度
|
||||||
|
top: '0', //距离顶部的距离
|
||||||
|
left: '-20%',
|
||||||
|
viewControl: {
|
||||||
|
//3d效果可以放大、旋转等,请自己去查看官方配置
|
||||||
|
alpha: 30, //角度(这个很重要 调节角度的)
|
||||||
|
distance: 200, //调整视角到主体的距离,类似调整zoom(这是整体大小)
|
||||||
|
rotateSensitivity: 0, //设置旋转灵敏度,为0无法旋转
|
||||||
|
zoomSensitivity: 0, //设置缩放灵敏度,为0无法缩放
|
||||||
|
panSensitivity: 0, //设置平移灵敏度,0无法平移
|
||||||
|
autoRotate: false, //自动旋转
|
||||||
|
autoRotateAfterStill: 2, //在鼠标静止操作后恢复自动旋转的时间间隔,在开启 autoRotate 后有效
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// graphic: {
|
||||||
|
// elements: [
|
||||||
|
// // {
|
||||||
|
// // type: 'polyline',
|
||||||
|
// // shape: {
|
||||||
|
// // points: [
|
||||||
|
// // [100, 150], // 起点
|
||||||
|
// // [150, 100], // 水平右移
|
||||||
|
// // [10, 200], // 垂直下移
|
||||||
|
// // ],
|
||||||
|
// // },
|
||||||
|
// // style: { stroke: '#FF0000', lineWidth: 2 },
|
||||||
|
// // },
|
||||||
|
// // {
|
||||||
|
// // type: 'line',
|
||||||
|
// // shape: { x1: 80, y1: 150, x2: 0, y2: 200 },
|
||||||
|
// // style: { stroke: '#fff', lineWidth: 2 },
|
||||||
|
// // },
|
||||||
|
// {
|
||||||
|
// type: 'text',
|
||||||
|
// left: 0,
|
||||||
|
// top: 150,
|
||||||
|
// style: {
|
||||||
|
// text: '茄科类作物 20万亩',
|
||||||
|
// fill: '#FFF',
|
||||||
|
// fontSize: 14,
|
||||||
|
// padding: [4, 8],
|
||||||
|
// borderRadius: 4,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'text',
|
||||||
|
// left: 120,
|
||||||
|
// top: 200,
|
||||||
|
// style: {
|
||||||
|
// text: '其他蔬菜作物 20万亩',
|
||||||
|
// fill: '#FFF',
|
||||||
|
// fontSize: 14,
|
||||||
|
// padding: [4, 8],
|
||||||
|
// borderRadius: 4,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'text',
|
||||||
|
// left: 200,
|
||||||
|
// top: 100,
|
||||||
|
// style: {
|
||||||
|
// text: '豆菜类作物 25万亩',
|
||||||
|
// fill: '#FFF',
|
||||||
|
// fontSize: 14,
|
||||||
|
// padding: [4, 8],
|
||||||
|
// borderRadius: 4,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'text',
|
||||||
|
// left: 20,
|
||||||
|
// top: 60,
|
||||||
|
// style: {
|
||||||
|
// text: '根菜类作物 20万亩',
|
||||||
|
// fill: '#FFF',
|
||||||
|
// fontSize: 14,
|
||||||
|
// padding: [4, 8],
|
||||||
|
// borderRadius: 4,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// type: 'text',
|
||||||
|
// left: 0,
|
||||||
|
// top: 100,
|
||||||
|
// style: {
|
||||||
|
// text: '叶菜类作物 10万亩',
|
||||||
|
// fill: '#FFF',
|
||||||
|
// fontSize: 14,
|
||||||
|
// padding: [4, 8],
|
||||||
|
// borderRadius: 4,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// // {
|
||||||
|
// // type: 'text',
|
||||||
|
// // left: 210,
|
||||||
|
// // top: 210,
|
||||||
|
// // style: {
|
||||||
|
// // text: '3.00',
|
||||||
|
// // fill: '#FFF',
|
||||||
|
// // fontSize: 14,
|
||||||
|
// // backgroundColor: 'rgba(0,0,0,0.7)',
|
||||||
|
// // padding: [4, 8],
|
||||||
|
// // borderRadius: 4,
|
||||||
|
// // },
|
||||||
|
// // },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// series: [
|
||||||
|
// // 透明的 2D 饼图(仅用于生成标签折线)
|
||||||
|
// {
|
||||||
|
// type: 'pie',
|
||||||
|
// radius: ['30%', '70%'],
|
||||||
|
// center: ['40%', '50%'],
|
||||||
|
// startAngle: -40, // 调整角度与 3D 图形对齐
|
||||||
|
// clockwise: false,
|
||||||
|
// label: {
|
||||||
|
// show: true,
|
||||||
|
// position: 'outside',
|
||||||
|
// formatter: (params) => {
|
||||||
|
// console.log(params);
|
||||||
|
// return `{a|${params.data.name}}\n{b|${params.data.money}万元}`;
|
||||||
|
// },
|
||||||
|
// rich: {
|
||||||
|
// a: { color: '#ffffff' },
|
||||||
|
// b: { color: '#79F5AF' },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// labelLine: {
|
||||||
|
// show: true,
|
||||||
|
// length: 10,
|
||||||
|
// length2: 15,
|
||||||
|
// lineStyle: {
|
||||||
|
// color: '#ffffff',
|
||||||
|
// width: 1,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// data: dataList,
|
||||||
|
// itemStyle: {
|
||||||
|
// opacity: 1, // 隐藏扇区,仅保留标签和折线
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
});
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
/* --------------- methods --------------- */
|
||||||
|
// #region
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
@ -0,0 +1,174 @@
|
|||||||
|
<template>
|
||||||
|
<div class="plant-environment-warp">
|
||||||
|
<div class="data-item-row">
|
||||||
|
<div
|
||||||
|
v-for="(n, index) in datalist"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
'background-image': 'url(' + getAssetsFile('images/plant/bg3.png') + ')',
|
||||||
|
width: 'calc((100% - 30px) /' + datalist.length + ')',
|
||||||
|
}"
|
||||||
|
class="data-item"
|
||||||
|
>
|
||||||
|
<div class="data-warp">
|
||||||
|
<div class="data-pos">
|
||||||
|
<div class="data-pos-center">
|
||||||
|
<div class="pos-center">
|
||||||
|
<span class="label">{{ n.label }}</span>
|
||||||
|
<div class="value">
|
||||||
|
<span>{{ n.value }}</span>
|
||||||
|
<span class="unit">{{ n.unit }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="small-bg">
|
||||||
|
<img :src="getAssetsFile('images/plant/bg6.png')" />
|
||||||
|
<img :src="getAssetsFile('images/plant/' + n.icon)" class="img-icon" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { isEmpty, getAssetsFile } from '@/utils';
|
||||||
|
import { ref, reactive, onMounted, watch } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useApp } from '@/hooks';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const props = defineProps({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: '统计分析',
|
||||||
|
},
|
||||||
|
postion: {
|
||||||
|
type: String,
|
||||||
|
default: 'left',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let topTitle = ref('');
|
||||||
|
let pos = ref('');
|
||||||
|
|
||||||
|
const datalist = reactive([
|
||||||
|
{ label: '空气温度', value: 28.6, unit: '℃', icon: 'icon4.png' },
|
||||||
|
{ label: '空气湿度', value: 30, unit: '%', icon: 'icon3.png' },
|
||||||
|
{ label: '光照强度', value: 1000, unit: 'lux', icon: 'icon1.png' },
|
||||||
|
{ label: '降水量', value: 100, unit: 'mm', icon: 'icon2.png' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (datalist.length) {
|
||||||
|
datalist.forEach((m, index) => {
|
||||||
|
let num = 0;
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
num = 20;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
num = 30;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
num = 1000;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
num = 100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
num = 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m.value = (Math.random() + num).toFixed(2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => (props.title, props.postion),
|
||||||
|
() => {
|
||||||
|
topTitle.value = props.title;
|
||||||
|
pos.value = props.postion;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.plant-environment-warp {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
.data-item-row {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.data-item {
|
||||||
|
height: 100%;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.data-warp {
|
||||||
|
padding: 8px 0;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 1;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
.small-bg,
|
||||||
|
.data-pos {
|
||||||
|
display: inline-flex;
|
||||||
|
vertical-align: middle;
|
||||||
|
.data-pos-center {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
.pos-center {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.small-bg {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
position: relative;
|
||||||
|
margin-top: 10%;
|
||||||
|
.img-icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 38%;
|
||||||
|
height: 38%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.data-pos {
|
||||||
|
width: calc(100% - 54px);
|
||||||
|
.label,
|
||||||
|
.value {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
color: #6beff9;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
.unit {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<div class="growth-indexes-charts">
|
||||||
|
<custom-echart-mixin :chart-data="handelData" :option="chartsData.option" height="100%" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue';
|
||||||
|
let itemStyle = reactive({
|
||||||
|
itemStyle: { borderRadius: [8, 8, 0, 0] },
|
||||||
|
});
|
||||||
|
|
||||||
|
let legendList = reactive(['猪', '牛', '羊', '鸡', '其他']);
|
||||||
|
const chartsData = reactive({
|
||||||
|
option: {
|
||||||
|
title: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '2%',
|
||||||
|
right: '2%',
|
||||||
|
bottom: '3%',
|
||||||
|
top: '18%',
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['货款', '投保'],
|
||||||
|
left: '35%', // 距离左侧10%的位置
|
||||||
|
top: '0', // 垂直居中
|
||||||
|
itemWidth: 20, // 图例标记的宽度
|
||||||
|
itemHeight: 20, // 图例标记的高度
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: '15',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
calculable: true,
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
boundaryGap: [0, 0.01],
|
||||||
|
axisLabel: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
name: '',
|
||||||
|
data: ['其他', '仓储', '生产加工', '种植'],
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 15,
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '货款',
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: '10px',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#35d0c0',
|
||||||
|
barBorderRadius: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
// 关键配置
|
||||||
|
show: true,
|
||||||
|
position: 'outside', // 位置:top / bottom / inside / outside
|
||||||
|
formatter: '{c}亿元',
|
||||||
|
color: '#fff', // 全局字体颜色
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
data: [10, 15, 8.5, 5, 5, 16],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '投保',
|
||||||
|
type: 'bar',
|
||||||
|
barWidth: '10px',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#fef906',
|
||||||
|
barBorderRadius: 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
// 关键配置
|
||||||
|
show: true,
|
||||||
|
position: 'outside', // 位置:top / bottom / inside / outside
|
||||||
|
formatter: '{c}亿元',
|
||||||
|
color: '#fff', // 全局字体颜色
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
data: [6, 6.5, 6, 3, 2, 10],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// color: ['#3685fe', '#41b879', '#ffd500', '#e57373'],
|
||||||
|
// title: {
|
||||||
|
// text: ' ',
|
||||||
|
// textStyle: {
|
||||||
|
// color: '#333',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// legend: {
|
||||||
|
// show: true,
|
||||||
|
// data: legendList,
|
||||||
|
// left: '0', // 距离左侧10%的位置
|
||||||
|
// top: '0', // 垂直居中
|
||||||
|
// itemWidth: 15, // 图例标记的宽度
|
||||||
|
// itemHeight: 8, // 图例标记的高度
|
||||||
|
// textStyle: {
|
||||||
|
// fontSize: 10, // 图例文字的字体大小
|
||||||
|
// color: '#fff', // 图例文字的颜色
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// barStyle: {
|
||||||
|
// barWidth: 10,
|
||||||
|
// },
|
||||||
|
// dataZoom: [
|
||||||
|
// // {
|
||||||
|
// // type: 'slider', // 滑动条型数据区域缩放组件
|
||||||
|
// // startValue: 0, // 数据窗口起始值的索引
|
||||||
|
// // endValue: 2, // 数据窗口结束值的索引
|
||||||
|
// // },
|
||||||
|
// // {
|
||||||
|
// // type: 'inside', // 支持鼠标滚轮和触控板缩放和平移
|
||||||
|
// // startValue: 0,
|
||||||
|
// // endValue: 2,
|
||||||
|
// // },
|
||||||
|
// ],
|
||||||
|
// yAxis: [
|
||||||
|
// {
|
||||||
|
// type: 'value',
|
||||||
|
// name: ' ',
|
||||||
|
// axisLabel: {
|
||||||
|
// formatter: '{value}',
|
||||||
|
// },
|
||||||
|
// splitLine: {
|
||||||
|
// show: true, // 显示分割线
|
||||||
|
// lineStyle: {
|
||||||
|
// type: 'dashed', // 设置为虚线
|
||||||
|
// width: 0.5, // 分割线宽度
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// itemStyle: { fontSize: 8 },
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// grid: {
|
||||||
|
// x: '10%',
|
||||||
|
// x2: '10%',
|
||||||
|
// y: '20%',
|
||||||
|
// y2: '20%',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
valData: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
const randomVal = (num) => {
|
||||||
|
let list = [];
|
||||||
|
for (let i = 0; i < legendList.length; i++) {
|
||||||
|
let addNum = [10, 8, 2, 5];
|
||||||
|
let val = {
|
||||||
|
name: num + '月',
|
||||||
|
value: Number(Math.random() * 100 + addNum[i]).toFixed(2),
|
||||||
|
seriesType: 'bar',
|
||||||
|
type: legendList[i],
|
||||||
|
stack: num + '月',
|
||||||
|
};
|
||||||
|
let lastVal = {
|
||||||
|
...val,
|
||||||
|
...itemStyle,
|
||||||
|
};
|
||||||
|
list[i] = i < legendList.length - 1 ? val : lastVal;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
};
|
||||||
|
let handelData = computed(() => {
|
||||||
|
let list = [];
|
||||||
|
let maxMouth = 12;
|
||||||
|
for (let i = 0; i < maxMouth; i++) {
|
||||||
|
let val = randomVal(i + 1);
|
||||||
|
list = [...list, ...val];
|
||||||
|
}
|
||||||
|
|
||||||
|
list.map((m, indexm) => {
|
||||||
|
return { ...m, value: Number(Number(m.value) + Math.random() + indexm).toFixed(0) };
|
||||||
|
});
|
||||||
|
// console.info('handelData', list);
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.growth-indexes-charts {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<div class="demo health-status-charts" style="height: 90%">
|
||||||
|
<div class="list-item-header item-warp" :style="{ flex: listKeys.length }">
|
||||||
|
<template v-for="(h, indexh) in listKeys" :key="indexh">
|
||||||
|
<div class="item-td" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">{{ listKeysHeader[h] }}</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<vue3ScrollSeamless class="scroll-wrap" :class-options="classOptions" :data-list="list">
|
||||||
|
<div v-for="(item, index) in list" :key="index" class="list-item">
|
||||||
|
<div class="list-item-content">
|
||||||
|
<div class="list-item-boday item-warp" :style="{ flex: listKeys.length }">
|
||||||
|
<template v-for="(b, indexb) in listKeys" :key="indexb">
|
||||||
|
<div class="item-td" :class="item.status == 1 ? 'td-title' : 'td-warn'" :style="{ width: 'calc(100% / ' + listKeys.length + ')' }">
|
||||||
|
<span v-if="b != 'status'">
|
||||||
|
{{ item[b] }}
|
||||||
|
</span>
|
||||||
|
<el-icon v-else>
|
||||||
|
<Bell></Bell>
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</vue3ScrollSeamless>
|
||||||
|
</div>
|
||||||
|
<!-- </div> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted, computed, reactive } from 'vue';
|
||||||
|
import { vue3ScrollSeamless } from 'vue3-scroll-seamless';
|
||||||
|
const props = defineProps({
|
||||||
|
// items: {
|
||||||
|
// type: Array,
|
||||||
|
// default: () => [],
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
|
||||||
|
let list = reactive([
|
||||||
|
{ diseaseType: '瘟疫', incidenceRate: '23%', coverage: '84%', status: 1 },
|
||||||
|
{ diseaseType: '蓝耳病', incidenceRate: '19%', coverage: '88%', status: 1 },
|
||||||
|
{ diseaseType: '口蹄疫', incidenceRate: '45%', coverage: '68%', status: 1 },
|
||||||
|
{ diseaseType: '链球病菌', incidenceRate: '35%', coverage: '88%', status: 1 },
|
||||||
|
{ diseaseType: '炎症', incidenceRate: '8%', coverage: '98%', status: 1 },
|
||||||
|
{ diseaseType: '寄生虫', incidenceRate: '11%', coverage: '99%', status: 1 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const listKeys = reactive(['diseaseType', 'incidenceRate', 'coverage', 'status']);
|
||||||
|
const listKeysHeader = reactive({
|
||||||
|
diseaseType: '疾病种类',
|
||||||
|
incidenceRate: '发病率',
|
||||||
|
coverage: '疫苗接种率',
|
||||||
|
status: '预警',
|
||||||
|
});
|
||||||
|
|
||||||
|
const classOptions = {
|
||||||
|
singleHeight: 48,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.health-status-charts {
|
||||||
|
margin-top: 8px;
|
||||||
|
.scroll-wrap {
|
||||||
|
height: 80%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 4px auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.list-item-header {
|
||||||
|
background: #144482;
|
||||||
|
font-size: 10px;
|
||||||
|
width: 100%;
|
||||||
|
.item-td {
|
||||||
|
padding: 8px 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-item-boday {
|
||||||
|
background: transparent;
|
||||||
|
width: 100%;
|
||||||
|
.item-td {
|
||||||
|
padding: 4px 6px;
|
||||||
|
&.td-title {
|
||||||
|
color: #6beff9 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.td-warn {
|
||||||
|
color: red !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.item-warp {
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
.item-td {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-item {
|
||||||
|
// border-bottom: 1px dashed rgba(255, 255, 255, 0.2);
|
||||||
|
line-height: 18px;
|
||||||
|
|
||||||
|
.list-item-content {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-around;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo {
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
// margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|