feat:采收与赋码管理
This commit is contained in:
parent
c9829c6a5c
commit
182b97b336
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-02-23 21:12:37
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-07 14:38:05
|
||||
* @LastEditTime: 2025-02-10 14:47:12
|
||||
*/
|
||||
import lodash from 'lodash';
|
||||
import dayjs from 'dayjs';
|
||||
@ -291,42 +291,56 @@ export const obj2Param = (json) => {
|
||||
* @returns
|
||||
*/
|
||||
export const getAssetsFile = (url) => {
|
||||
return new URL(`../assets/images/${url}`, import.meta.url);
|
||||
};
|
||||
/**
|
||||
* @Title: a链接方式文件下载
|
||||
* @param {void} content:
|
||||
* @param {void} fileName:
|
||||
* @return {void}
|
||||
*/
|
||||
export const downloadLink = (url, fileName) => {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = url;
|
||||
elink.target = '_blank';
|
||||
elink.click();
|
||||
elink.remove();
|
||||
return new URL(`../assets/${url}`, import.meta.url);
|
||||
};
|
||||
/**
|
||||
* @Title: 下载文件
|
||||
* @param {void} content:
|
||||
* @param {void} url:
|
||||
* @param {void} fileName:
|
||||
* @param {void} fileType:
|
||||
* @return {void}
|
||||
*/
|
||||
export const downloadFile = (content, fileName) => {
|
||||
const blob = new Blob([content]);
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
export const downloadFile = async (url, fileName, fileType) => {
|
||||
let blob = null;
|
||||
try {
|
||||
switch (fileType) {
|
||||
case 'image': {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'Anonymous';
|
||||
img.src = url;
|
||||
await new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
blob = await new Promise((resolve) => {
|
||||
canvas.toBlob(resolve, 'image/jpeg');
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'blob': {
|
||||
blob = new Blob([url]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = blob ? URL.createObjectURL(blob) : url;
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
blob && URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('下载出错:', error);
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
@ -6,15 +6,14 @@ import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||
import compression from 'vite-plugin-compression';
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||
// import { viteMockServe } from 'vite-plugin-mock';
|
||||
import AutoImport from 'unplugin-auto-import/vite';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import postcssImport from 'postcss-import';
|
||||
import autoprefixer from 'autoprefixer';
|
||||
// import postCssPxToRem from 'postcss-pxtorem';
|
||||
import { resolve } from 'path';
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
console.log('vite.config.js', command, mode, loadEnv(mode, process.cwd()));
|
||||
const {
|
||||
VITE_PORT,
|
||||
VITE_APP_NAME,
|
||||
@ -77,12 +76,6 @@ export default defineConfig(({ command, mode }) => {
|
||||
autoprefixer({
|
||||
overrideBrowserslist: ['> 1%', 'last 2 versions'],
|
||||
}),
|
||||
// postCssPxToRem({
|
||||
// rootValue: 192,
|
||||
// selectorBlackList: [],
|
||||
// propList: ['*'],
|
||||
// exclude: /node_modules/i,
|
||||
// }),
|
||||
],
|
||||
},
|
||||
},
|
||||
@ -101,7 +94,7 @@ export default defineConfig(({ command, mode }) => {
|
||||
include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
|
||||
}),
|
||||
Components({
|
||||
dirs: ['../global/components', 'src/components'],
|
||||
dirs: ['src/components'],
|
||||
extensions: ['vue', 'js', 'jsx', 'ts', 'tsx'],
|
||||
resolvers: [],
|
||||
}),
|
||||
@ -114,12 +107,6 @@ export default defineConfig(({ command, mode }) => {
|
||||
iconDirs: [resolve(process.cwd(), 'src/assets/svgs')],
|
||||
symbolId: 'icon-[name]',
|
||||
}),
|
||||
// viteMockServe({
|
||||
// mockPath: 'src/mock',
|
||||
// watchFiles: true,
|
||||
// localEnabled: command === 'dev',
|
||||
// prodEnabled: false,
|
||||
// }),
|
||||
],
|
||||
};
|
||||
if (mode === 'production') {
|
||||
|
@ -3,10 +3,10 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-02-23 21:12:37
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-01-25 17:05:12
|
||||
* @LastEditTime: 2025-02-10 14:45:53
|
||||
*/
|
||||
import lodash from 'lodash';
|
||||
import moment from 'moment';
|
||||
import dayjs from 'dayjs';
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
/**
|
||||
@ -90,7 +90,7 @@ export const setDefaultOption = (options, prop, defaultVal) => {
|
||||
return options[prop] === undefined ? defaultVal : options.prop;
|
||||
};
|
||||
/**
|
||||
* 设置字典值
|
||||
* @Title 设置字典值
|
||||
* @param {*} columns
|
||||
* @param {*} key
|
||||
* @param {*} data
|
||||
@ -107,7 +107,7 @@ export const setDicData = (columns, key, data = []) => {
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 求字段lable
|
||||
* @Title 求字段lable
|
||||
* @param {*} tree
|
||||
* @returns
|
||||
*/
|
||||
@ -124,7 +124,35 @@ export const setDicLabel = (dicData, value) => {
|
||||
return label;
|
||||
};
|
||||
/**
|
||||
* 加密
|
||||
* @Title 数组交集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const intersectionArray = (arr1 = [], arr2 = []) => {
|
||||
return arr1.filter((item) => arr2.includes(item));
|
||||
};
|
||||
/**
|
||||
* @Title 数组并集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const unionArray = (arr1 = [], arr2 = []) => {
|
||||
return Array.from(new Set([...arr1, ...arr2]));
|
||||
};
|
||||
/**
|
||||
* @Title 数组差集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const differenceArray = (arr1 = [], arr2 = []) => {
|
||||
const s = new Set(arr2);
|
||||
return arr1.filter((x) => !s.has(x));
|
||||
};
|
||||
/**
|
||||
* @Title 加密
|
||||
* @param {*} n
|
||||
* @returns
|
||||
*/
|
||||
@ -146,7 +174,7 @@ export const encode = (n, flag = false) => {
|
||||
return n;
|
||||
};
|
||||
/**
|
||||
* 解密
|
||||
* @Title 解密
|
||||
* @param {*} e
|
||||
* @returns
|
||||
*/
|
||||
@ -190,6 +218,22 @@ export const imageToBase64 = (file) => {
|
||||
export const bufferToBase64 = (buffer) => {
|
||||
return 'data:image/jpeg;base64,' + window.btoa(new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
};
|
||||
/**
|
||||
* @Title blob转json
|
||||
* @param {*} file
|
||||
* @returns
|
||||
*/
|
||||
export const blobToJSON = (blob) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(blob, 'utf-8');
|
||||
reader.onload = () => {
|
||||
const res = !isEmpty(reader.result) ? JSON.parse(reader.result) : reader.result;
|
||||
resolve(res);
|
||||
};
|
||||
reader.onerror = reject;
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @Title 将array转化为树
|
||||
* @param tree
|
||||
@ -227,42 +271,76 @@ export const getUrlQuery = (name) => {
|
||||
const usp = new URLSearchParams(search);
|
||||
return usp.get(name);
|
||||
};
|
||||
/**
|
||||
* @Title 将Object参数转换为字符串
|
||||
* @param {*} json
|
||||
* @returns
|
||||
*/
|
||||
export const obj2Param = (json) => {
|
||||
if (!json) return '';
|
||||
return Object.keys(json)
|
||||
.map((key) => {
|
||||
if (isEmpty(json[key])) return '';
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
|
||||
})
|
||||
.join('&');
|
||||
};
|
||||
/**
|
||||
* @Title 获取静态资源文件
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
export const getAssetsFile = (url) => {
|
||||
return new URL(`../assets/images/${url}`, import.meta.url);
|
||||
return new URL(`../assets/${url}`, import.meta.url);
|
||||
};
|
||||
/**
|
||||
* @Title 替换图片url字段值
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
export const setUploadField = (url) => {
|
||||
if (isEmpty(url) || url.includes('http')) return null;
|
||||
return url;
|
||||
};
|
||||
/**
|
||||
* @Title: a链接方式文件下载
|
||||
* @param {void} content:
|
||||
* @Title: 下载文件
|
||||
* @param {void} url:
|
||||
* @param {void} fileName:
|
||||
* @param {void} fileType:
|
||||
* @return {void}
|
||||
*/
|
||||
export const dowloadLink = (content, fileName) => {
|
||||
const blob = new Blob([content]);
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
export const downloadFile = async (url, fileName, fileType) => {
|
||||
let blob = null;
|
||||
try {
|
||||
switch (fileType) {
|
||||
case 'image': {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'Anonymous';
|
||||
img.src = url;
|
||||
await new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
blob = await new Promise((resolve) => {
|
||||
canvas.toBlob(resolve, 'image/jpeg');
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'blob': {
|
||||
blob = new Blob([url]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = blob ? URL.createObjectURL(blob) : url;
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
blob && URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('下载出错:', error);
|
||||
}
|
||||
};
|
||||
/**
|
||||
@ -275,20 +353,106 @@ export const sleep = (duration = 0) =>
|
||||
setTimeout(resolve, duration);
|
||||
});
|
||||
/**
|
||||
* 日期格式化
|
||||
* @Title 创建id
|
||||
* @param {*} prefix
|
||||
* @returns
|
||||
*/
|
||||
export const createId = (prefix) => {
|
||||
const val = Date.now() + Math.ceil(Math.random() * 99999);
|
||||
return isEmpty(prefix) ? val : prefix + '-' + val;
|
||||
};
|
||||
/**
|
||||
* @Title 生成数据
|
||||
* @param {*} duration
|
||||
* @returns
|
||||
*/
|
||||
export const mockData = (item = {}, len = 1) => {
|
||||
const list = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
let temp = { ...item, id: createId() };
|
||||
list.push(temp);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
/**
|
||||
* @Title 日期格式化
|
||||
* @param {*} date
|
||||
* @param {*} format
|
||||
* @returns
|
||||
*/
|
||||
export const dateFormat = (datetime, type = 'yyyy-MM-dd') => {
|
||||
return moment(datetime).format(type);
|
||||
export const dateFormat = (datetime, formater = 'YYYY-MM-DD hh:mm:ss') => {
|
||||
if (datetime instanceof Date || datetime) {
|
||||
return dayjs(datetime).format(formater);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 上日/周/月/年
|
||||
* @Title 字符串转日期
|
||||
* @param {*} str
|
||||
* @returns
|
||||
*/
|
||||
export const lastDate = (last = 0, date = 'month', type = 'yyyy-MM-dd') => {
|
||||
if (date === 'day') {
|
||||
return moment().subtract(last, 'day').endOf('day').format(type);
|
||||
}
|
||||
return moment().subtract(last, date).format(type);
|
||||
export const toDate = (str) => {
|
||||
return !isEmpty(str) ? dayjs(str) : dayjs();
|
||||
};
|
||||
/**
|
||||
* @Title 字符串转日期
|
||||
* @param {*} str
|
||||
* @returns
|
||||
*/
|
||||
export const getDate = (num, type, formater = 'YYYY-MM-DD', start = true) => {
|
||||
const date = dayjs().subtract(num, type);
|
||||
return start ? date.startOf(type).format(formater) : date.endOf(type).format(formater);
|
||||
};
|
||||
/**
|
||||
* @Title: 获取时间差
|
||||
* @param start
|
||||
* @param end
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
export const getDiffTime = (start, end, type) => {
|
||||
const startTime = dayjs(start);
|
||||
const endTime = dayjs(end);
|
||||
const duration = endTime.diff(startTime);
|
||||
let diff = 0;
|
||||
switch (type) {
|
||||
case 'DD': {
|
||||
diff = duration / (1000 * 60 * 60 * 24);
|
||||
break;
|
||||
}
|
||||
case 'HH': {
|
||||
diff = duration / (1000 * 60 * 60);
|
||||
break;
|
||||
}
|
||||
case 'mm': {
|
||||
diff = duration / (1000 * 60);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Math.round(diff);
|
||||
};
|
||||
/**
|
||||
* @Title: 开始日期
|
||||
* @param last
|
||||
* @param type
|
||||
* @param formater
|
||||
* @returns
|
||||
*/
|
||||
export const startDate = (num, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
|
||||
if (num === 'now') return dayjs().format(formater);
|
||||
if (typeof num === 'string') return dayjs(num).startOf(type).format(formater);
|
||||
return num === 0 ? dayjs().startOf(type).format(formater) : dayjs().subtract(num, type).startOf(type).format(formater);
|
||||
};
|
||||
/**
|
||||
* @Title: 结束日期
|
||||
* @param num
|
||||
* @param type
|
||||
* @param formater
|
||||
* @returns
|
||||
*/
|
||||
export const endDate = (num = 0, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
|
||||
if (num === 'now') return dayjs().format(formater);
|
||||
if (typeof num === 'string') return dayjs(num).endOf(type).format(formater);
|
||||
return num === 0 ? dayjs().endOf(type).format(formater) : dayjs().subtract(num, type).endOf(type).format(formater);
|
||||
};
|
||||
|
@ -2,10 +2,10 @@
|
||||
VITE_PORT = 9528
|
||||
VITE_MODE = 'DEV'
|
||||
VITE_APP_NAME = 'sub-government-affairs-service'
|
||||
VITE_APP_BASE_API = '/traceApis'
|
||||
VITE_APP_BASE_API = '/apis'
|
||||
VITE_APP_BASE_URL = 'http://192.168.18.99:8080'
|
||||
VITE_APP_UPLOAD_API = '/uploadApis'
|
||||
VITE_APP_UPLOAD_URL = 'http://192.168.18.99:9300'
|
||||
VITE_APP_DICDATA_API = '/dicDataApis'
|
||||
VITE_APP_DICDATA_URL = 'http://192.168.18.99:99/stage-api'
|
||||
VITE_APP_SYSTEM_API = '/systemApis'
|
||||
VITE_APP_SYSTEM_URL = 'http://192.168.18.99:99/stage-api'
|
||||
|
||||
|
@ -3,7 +3,7 @@ import request from '@/utils/axios';
|
||||
/**
|
||||
* @Title: 列表
|
||||
*/
|
||||
export function GetEntityList(params) {
|
||||
export function GetEntityList(params = {}) {
|
||||
return request('/trace/code/farmMange/page', {
|
||||
method: 'GET',
|
||||
params,
|
||||
@ -13,7 +13,7 @@ export function GetEntityList(params) {
|
||||
/**
|
||||
* @Title: 新增
|
||||
*/
|
||||
export function AddEntity(data) {
|
||||
export function AddEntity(data = {}) {
|
||||
return request('/trace/code/farmMange/save', {
|
||||
method: 'POST',
|
||||
data,
|
||||
@ -23,7 +23,7 @@ export function AddEntity(data) {
|
||||
/**
|
||||
* @Title: 修改
|
||||
*/
|
||||
export function UpdateEntity(data) {
|
||||
export function UpdateEntity(data = {}) {
|
||||
return request('/trace/code/farmMange/edit', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
@ -33,7 +33,7 @@ export function UpdateEntity(data) {
|
||||
/**
|
||||
* @Title: 删除
|
||||
*/
|
||||
export function DeleteEntity(params) {
|
||||
export function DeleteEntity(params = {}) {
|
||||
return request('/trace/code/farmMange/delete', {
|
||||
method: 'DELETE',
|
||||
params,
|
||||
@ -43,7 +43,7 @@ export function DeleteEntity(params) {
|
||||
/**
|
||||
* @Title: 导入
|
||||
*/
|
||||
export function ImportEntity(data) {
|
||||
export function ImportEntity(data = {}) {
|
||||
return request('/trace/code/farmMange/import', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
@ -54,7 +54,7 @@ export function ImportEntity(data) {
|
||||
/**
|
||||
* @Title: 导出
|
||||
*/
|
||||
export function ExportEntity(params) {
|
||||
export function ExportEntity(params = {}) {
|
||||
return request('/trace/code/farmMange/export', {
|
||||
method: 'GET',
|
||||
params,
|
||||
@ -63,11 +63,10 @@ export function ExportEntity(params) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @Title: 地址列表
|
||||
* @Title: 详情
|
||||
*/
|
||||
export function GetAreaList(params) {
|
||||
return request('/trace/code/farmMange/areas', {
|
||||
export function GetEntity(params = {}) {
|
||||
return request(`/trace/code/farmMange/qualityCheck/${params?.id}`, {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
41
sub-government-affairs-service/src/apis/quality.js
Normal file
41
sub-government-affairs-service/src/apis/quality.js
Normal file
@ -0,0 +1,41 @@
|
||||
import request from '@/utils/axios';
|
||||
|
||||
/**
|
||||
* @Title: 列表
|
||||
*/
|
||||
export function GetEntityList(params) {
|
||||
return request('/trace/code/qualityManage/page', {
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @Title: 新增
|
||||
*/
|
||||
export function AddEntity(data) {
|
||||
return request('/trace/code/qualityManage/save', {
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @Title: 修改
|
||||
*/
|
||||
export function UpdateEntity(data) {
|
||||
return request('/trace/code/qualityManage/edit', {
|
||||
method: 'PUT',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @Title: 删除
|
||||
*/
|
||||
export function DeleteEntity(params) {
|
||||
return request('/trace/code/qualityManage/delete', {
|
||||
method: 'DELETE',
|
||||
params,
|
||||
});
|
||||
}
|
@ -17,6 +17,7 @@ export const CRUD_OPTIONS = {
|
||||
align: 'center',
|
||||
headerAlign: 'center',
|
||||
gridBtn: false,
|
||||
columnBtn: false,
|
||||
addBtn: true,
|
||||
viewBtn: false,
|
||||
editBtn: false,
|
||||
@ -26,4 +27,5 @@ export const CRUD_OPTIONS = {
|
||||
column: [],
|
||||
menuWidth: 100,
|
||||
actions: [],
|
||||
dialogDrag: true,
|
||||
};
|
||||
|
@ -3,9 +3,10 @@ import { constantRoutes, notFoundRouter } from '@/router';
|
||||
import { createAsyncRoutes, filterAsyncRoutes, filterKeepAlive } from '@/utils/router';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { getTree } from '@/utils';
|
||||
import { GenKey } from '@/config';
|
||||
|
||||
export const usePermissionStore = defineStore({
|
||||
id: 'permissionStore',
|
||||
id: GenKey('permissionStore'),
|
||||
state: () => ({
|
||||
// 路由
|
||||
routes: [],
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { GenKey } from '@/config';
|
||||
import router from '@/router';
|
||||
|
||||
export const useTagsViewStore = defineStore({
|
||||
id: 'tagsViewStore',
|
||||
id: GenKey('tagsViewStore'),
|
||||
state: () => ({
|
||||
activeTabsValue: '/home',
|
||||
visitedViews: [],
|
||||
|
@ -3,10 +3,10 @@ import { GenKey } from '@/config';
|
||||
import { isEmpty, encode, decode } from '@/utils';
|
||||
|
||||
export const useUserStore = defineStore({
|
||||
id: GenKey('USER_STATE'),
|
||||
id: GenKey('userStore'),
|
||||
state: () => ({
|
||||
token:
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6IjA0ZjNmZTE5LTc5ZWYtNGMxNy1iNWQ4LTE5YjA0MTkyNTZiMyIsInVzZXJuYW1lIjoiYWRtaW4ifQ.nGVLjwzO7K6MO9DbKKhfmwsoinDig5tsGWGEb3jcOtUQHcyJhTTvvuq3zAxNHSFRm9Nly_MSEcRV6oVcz3gT_w',
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VyX2tleSI6IjU0ZGVjMzk4LTRhZmQtNDUyOS1hYjFkLTExZGZlZjU5NjJhOSIsInVzZXJuYW1lIjoiYWRtaW4ifQ._bHoqldw4oL_MqZxrHv81ShD3Z0GJYSdWietR1mHAfKluNi3SSs1PRZNrq1v-WTQyXgz1QgsBimPB48iqP7o6Q',
|
||||
userInfo: {},
|
||||
currentOrg: null,
|
||||
orgList: [],
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-02-23 21:12:37
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-07 15:21:48
|
||||
* @LastEditTime: 2025-02-10 14:42:53
|
||||
*/
|
||||
import lodash from 'lodash';
|
||||
import dayjs from 'dayjs';
|
||||
@ -293,40 +293,54 @@ export const obj2Param = (json) => {
|
||||
export const getAssetsFile = (url) => {
|
||||
return new URL(`../assets/${url}`, import.meta.url);
|
||||
};
|
||||
/**
|
||||
* @Title: a链接方式文件下载
|
||||
* @param {void} content:
|
||||
* @param {void} fileName:
|
||||
* @return {void}
|
||||
*/
|
||||
export const downloadLink = (url, fileName) => {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = url;
|
||||
elink.target = '_blank';
|
||||
elink.click();
|
||||
elink.remove();
|
||||
};
|
||||
/**
|
||||
* @Title: 下载文件
|
||||
* @param {void} content:
|
||||
* @param {void} url:
|
||||
* @param {void} fileName:
|
||||
* @param {void} fileType:
|
||||
* @return {void}
|
||||
*/
|
||||
export const downloadFile = (content, fileName) => {
|
||||
const blob = new Blob([content]);
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
export const downloadFile = async (url, fileName, fileType) => {
|
||||
let blob = null;
|
||||
try {
|
||||
switch (fileType) {
|
||||
case 'image': {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'Anonymous';
|
||||
img.src = url;
|
||||
await new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
blob = await new Promise((resolve) => {
|
||||
canvas.toBlob(resolve, 'image/jpeg');
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'blob': {
|
||||
blob = new Blob([url]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = blob ? URL.createObjectURL(blob) : url;
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
blob && URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('下载出错:', error);
|
||||
}
|
||||
};
|
||||
/**
|
||||
|
@ -8,12 +8,12 @@
|
||||
:table-loading="state.loading"
|
||||
:data="state.data"
|
||||
:option="state.options"
|
||||
@size-change="sizeChange"
|
||||
@current-change="currentChange"
|
||||
@refresh-change="refreshChange"
|
||||
@search-reset="searchChange"
|
||||
@search-change="searchChange"
|
||||
@selection-change="selectionChange"
|
||||
@current-change="currentChange"
|
||||
@size-change="sizeChange"
|
||||
@row-save="rowSave"
|
||||
@row-update="rowUpdate"
|
||||
@row-del="rowDel"
|
||||
@ -24,13 +24,6 @@
|
||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||
</template>
|
||||
|
||||
<template #qualityReportUrl="{ row }">
|
||||
<el-button v-if="row.qualityReportUrl" type="primary" text @click="downloadLink(row.qualityReportUrl, `${row.productName}-质检报告.pdf`)">
|
||||
下载
|
||||
</el-button>
|
||||
<span v-else>暂无</span>
|
||||
</template>
|
||||
|
||||
<template #productUrl-form="{ column }">
|
||||
<el-upload class="custom-form__uploader" action="#" :show-file-list="false" accept="image/*" :limit="1" :http-request="rowUploadPicture">
|
||||
<img v-if="state.form.base64" :src="state.form.base64" class="custom-form__uploader__img" />
|
||||
@ -38,6 +31,10 @@
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<template #customInfo-form="{ column }">
|
||||
<custom-info :row="state.currentRow" />
|
||||
</template>
|
||||
|
||||
<template #menu="scope">
|
||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||
</template>
|
||||
@ -49,22 +46,28 @@
|
||||
@on-download="onDownloadExcel"
|
||||
@on-confirm="onUploadExcel"
|
||||
/>
|
||||
|
||||
<custom-quality-add ref="qualityAddRef" :row="state.currentRow" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { isEmpty, imageToBase64, getAssetsFile, downloadLink, downloadFile } from '@/utils';
|
||||
import { isEmpty, imageToBase64, getAssetsFile, downloadFile } from '@/utils';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { CommonUpload } from '@/apis';
|
||||
import { GetEntityList, GetAreaList, AddEntity, UpdateEntity, DeleteEntity, ImportEntity, ExportEntity } from '@/apis/coding';
|
||||
import { compact } from 'lodash';
|
||||
import { GetEntityList, AddEntity, UpdateEntity, DeleteEntity, ImportEntity, ExportEntity } from '@/apis/coding';
|
||||
import CustomInfo from './info.vue';
|
||||
import CustomQualityAdd from '../quality/form.vue';
|
||||
|
||||
const { VITE_APP_DICDATA_API, VITE_APP_BASE_API } = import.meta.env;
|
||||
const { VITE_APP_SYSTEM_API } = import.meta.env;
|
||||
const app = useApp();
|
||||
const UserStore = useUserStore();
|
||||
const crudRef = ref(null);
|
||||
const importExcelRef = ref(null);
|
||||
const qualityAddRef = ref(null);
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
query: {
|
||||
@ -89,11 +92,6 @@ const state = reactive({
|
||||
prop: 'harvestBatch',
|
||||
width: 200,
|
||||
display: false,
|
||||
// rules: {
|
||||
// required: true,
|
||||
// message: '请输入',
|
||||
// trigger: 'blur',
|
||||
// },
|
||||
},
|
||||
{
|
||||
label: '产品名称',
|
||||
@ -115,7 +113,7 @@ const state = reactive({
|
||||
label: 'dictLabel',
|
||||
value: 'dictValue',
|
||||
},
|
||||
dicUrl: `${VITE_APP_DICDATA_API}/system/dict/data/list?pageNum=1&pageSize=20&dictType=sys_product_type`,
|
||||
dicUrl: `${VITE_APP_SYSTEM_API}/system/dict/data/list?pageNum=1&pageSize=20&dictType=sys_product_type`,
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
@ -144,7 +142,7 @@ const state = reactive({
|
||||
label: 'dictLabel',
|
||||
value: 'dictValue',
|
||||
},
|
||||
dicUrl: `${VITE_APP_DICDATA_API}/system/dict/data/list?pageNum=1&pageSize=20&dictType=sys_unit_type`,
|
||||
dicUrl: `${VITE_APP_SYSTEM_API}/system/dict/data/list?pageNum=1&pageSize=20&dictType=sys_unit_type`,
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
@ -168,17 +166,17 @@ const state = reactive({
|
||||
return row.qualityGuaranteePeriod + '天';
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '质检结果',
|
||||
prop: 'qualityResult',
|
||||
display: false,
|
||||
},
|
||||
{
|
||||
label: '质检报告',
|
||||
prop: 'qualityReportUrl',
|
||||
display: false,
|
||||
slot: true,
|
||||
},
|
||||
// {
|
||||
// label: '质检结果',
|
||||
// prop: 'qualityResult',
|
||||
// display: false,
|
||||
// },
|
||||
// {
|
||||
// label: '质检报告',
|
||||
// prop: 'qualityReportUrl',
|
||||
// display: false,
|
||||
// slot: true,
|
||||
// },
|
||||
{
|
||||
label: '采收日期',
|
||||
prop: 'datetime',
|
||||
@ -235,27 +233,27 @@ const state = reactive({
|
||||
{
|
||||
label: '原产地',
|
||||
prop: 'originAddress',
|
||||
type: 'cascader',
|
||||
search: true,
|
||||
display: false,
|
||||
overHidden: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
label: '原产地',
|
||||
prop: 'cities',
|
||||
type: 'cascader',
|
||||
// search: true,
|
||||
hide: true,
|
||||
props: {
|
||||
// expandTrigger: 'click',
|
||||
label: 'areaName',
|
||||
value: 'areaCode',
|
||||
children: 'areaChildVOS',
|
||||
lazy: true,
|
||||
lazyLoad: async (node, resolve) => {
|
||||
console.log(361, node);
|
||||
const { data } = await GetAreaList({ areaCode: node.value });
|
||||
resolve(data ?? []);
|
||||
},
|
||||
},
|
||||
dicUrl: `${VITE_APP_BASE_API}/trace/code/farmMange/areas`,
|
||||
dicUrl: `${VITE_APP_SYSTEM_API}/system/area/region?areaCode=530000`,
|
||||
dicHeaders: {
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
dicFormatter: (res) => res?.data ?? [],
|
||||
dicFormatter: (res) => res.data ?? [],
|
||||
// change: (o) => setCityChange(o),
|
||||
rules: {
|
||||
required: true,
|
||||
message: '请选择',
|
||||
@ -311,6 +309,15 @@ const state = reactive({
|
||||
width: 200,
|
||||
display: false,
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
labelWidth: 0,
|
||||
prop: 'customInfo',
|
||||
addDisplay: false,
|
||||
editDisplay: false,
|
||||
viewDisplay: true,
|
||||
span: 24,
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
@ -329,6 +336,11 @@ const state = reactive({
|
||||
icon: 'delete',
|
||||
event: ({ row }) => rowDel(row),
|
||||
},
|
||||
{
|
||||
name: '新增质检',
|
||||
icon: 'plus',
|
||||
event: ({ row }) => rowAdd(row),
|
||||
},
|
||||
],
|
||||
},
|
||||
pageData: {
|
||||
@ -337,8 +349,10 @@ const state = reactive({
|
||||
pageSize: 10,
|
||||
},
|
||||
data: [],
|
||||
currentRow: {},
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = async () => {
|
||||
state.loading = true;
|
||||
GetEntityList(state.query)
|
||||
@ -355,14 +369,13 @@ const loadData = async () => {
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
state.data = [];
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
// GetAreaList();
|
||||
|
||||
loadData();
|
||||
|
||||
// 页数
|
||||
@ -403,6 +416,7 @@ const selectionChange = (rows) => {
|
||||
// 查看
|
||||
const rowView = (row) => {
|
||||
row.base64 = row.productUrl;
|
||||
state.currentRow = row;
|
||||
crudRef.value.rowView(row);
|
||||
};
|
||||
|
||||
@ -419,9 +433,33 @@ const rowUploadPicture = async ({ file }) => {
|
||||
}
|
||||
};
|
||||
|
||||
const setCity = (row) => {
|
||||
if (!isEmpty(row.cities)) {
|
||||
row.province = row?.cities[0] ?? null;
|
||||
row.city = row?.cities[1] ?? null;
|
||||
row.county = row?.cities[2] ?? null;
|
||||
row.village = row?.cities[3] ?? null;
|
||||
}
|
||||
};
|
||||
|
||||
// const setCityChange = ({ value, dic }) => {
|
||||
// debugger;
|
||||
// const labels = [];
|
||||
// let currentOptions = dic;
|
||||
// value.forEach((val) => {
|
||||
// const option = dic.find((item) => item.areaCode === val);
|
||||
// if (option) {
|
||||
// labels.push(option.label);
|
||||
// currentOptions = option.children || [];
|
||||
// }
|
||||
// });
|
||||
// state.form.originAddress = labels.join(' / ');
|
||||
// };
|
||||
|
||||
// 新增
|
||||
const rowSave = (row, done, loading) => {
|
||||
delete row.base64;
|
||||
setCity(row);
|
||||
AddEntity(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
@ -441,10 +479,12 @@ const rowSave = (row, done, loading) => {
|
||||
// 编辑
|
||||
const rowEdit = (row) => {
|
||||
row.base64 = row.productUrl;
|
||||
row.cities = compact([row.province, row.city, row.county ?? '', row.village ?? '']);
|
||||
crudRef.value.rowEdit(row);
|
||||
};
|
||||
const rowUpdate = (row, index, done, loading) => {
|
||||
delete row.base64;
|
||||
setCity(row);
|
||||
UpdateEntity(row)
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
@ -490,6 +530,12 @@ const rowDel = (row, index, done) => {
|
||||
onDel([row]);
|
||||
};
|
||||
|
||||
// 质检
|
||||
const rowAdd = (row) => {
|
||||
state.currentRow = row;
|
||||
qualityAddRef?.value && qualityAddRef.value.show();
|
||||
};
|
||||
|
||||
// 导入
|
||||
const onUpload = () => {
|
||||
importExcelRef?.value && importExcelRef.value.show();
|
||||
@ -512,7 +558,7 @@ const onUploadExcel = (formData) => {
|
||||
};
|
||||
|
||||
const onDownloadExcel = (url) => {
|
||||
downloadLink(url, `采收赋码-导入模板.xlsx`);
|
||||
downloadFile(url, `采收赋码-导入模板.xlsx`, 'blob');
|
||||
};
|
||||
|
||||
// 导出
|
||||
@ -526,7 +572,7 @@ const onExport = () => {
|
||||
ExportEntity(state.query)
|
||||
.then((res) => {
|
||||
if (res.status === 200) {
|
||||
downloadFile(res.data, `${fileName}.xlsx`);
|
||||
downloadFile(res.data, `${fileName}.xlsx`, 'blob');
|
||||
app.$message.success('导出成功!');
|
||||
}
|
||||
})
|
||||
|
@ -0,0 +1,175 @@
|
||||
<template>
|
||||
<div class="custom-info">
|
||||
<avue-crud ref="crudRef" :table-loading="state.loading" :data="state.list" :option="state.options">
|
||||
<template #header>
|
||||
<h5 class="custom-form__title">质检记录</h5>
|
||||
</template>
|
||||
<template #qualityReportUrl="{ row: item }">
|
||||
<el-button
|
||||
v-if="item.qualityReportUrl"
|
||||
type="primary"
|
||||
text
|
||||
@click="downloadFile(item.qualityReportUrl, `${item.productName}-质检报告.png`, 'image')"
|
||||
>
|
||||
下载
|
||||
</el-button>
|
||||
<span v-else>暂无</span>
|
||||
</template>
|
||||
</avue-crud>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import { useApp } from '@/hooks';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import { downloadFile } from '@/utils';
|
||||
import { GetEntity } from '@/apis/coding';
|
||||
|
||||
const props = defineProps({
|
||||
row: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const app = useApp();
|
||||
const crudRef = ref(null);
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
// query: {
|
||||
// current: 1,
|
||||
// size: 10,
|
||||
// },
|
||||
options: {
|
||||
...CRUD_OPTIONS,
|
||||
index: false,
|
||||
addBtn: false,
|
||||
refreshBtn: false,
|
||||
selection: false,
|
||||
menu: false,
|
||||
column: [
|
||||
{
|
||||
label: '溯源码',
|
||||
prop: 'id',
|
||||
width: 200,
|
||||
fixed: true,
|
||||
},
|
||||
{
|
||||
label: '采收批次',
|
||||
prop: 'harvestBatch',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
label: '产品名称',
|
||||
prop: 'productName',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
label: '质检结果',
|
||||
prop: 'qualityResultType',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{
|
||||
label: '合格',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '不合格',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '质检类型',
|
||||
prop: 'qualityType',
|
||||
type: 'select',
|
||||
dicData: [
|
||||
{
|
||||
label: '检测机构',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '自检',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '质检机构',
|
||||
prop: 'department',
|
||||
width: 200,
|
||||
overHidden: true,
|
||||
},
|
||||
{
|
||||
label: '质检项目',
|
||||
prop: 'qualityProject',
|
||||
},
|
||||
{
|
||||
label: '质检报告',
|
||||
prop: 'qualityReportUrl',
|
||||
slot: true,
|
||||
},
|
||||
{
|
||||
label: '检测说明',
|
||||
prop: 'qualityDescribe',
|
||||
type: 'textarea',
|
||||
overHidden: true,
|
||||
resize: 'none',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
label: '质检人',
|
||||
prop: 'qualityPerson',
|
||||
},
|
||||
{
|
||||
label: '质检时间',
|
||||
prop: 'qualityTime',
|
||||
width: 200,
|
||||
},
|
||||
],
|
||||
},
|
||||
// pageData: {
|
||||
// total: 0,
|
||||
// currentPage: 1,
|
||||
// pageSize: 10,
|
||||
// },
|
||||
data: {},
|
||||
list: [],
|
||||
});
|
||||
|
||||
// 加载
|
||||
const loadData = () => {
|
||||
state.loading = true;
|
||||
GetEntity({ id: props.row.id })
|
||||
.then((res) => {
|
||||
if (res.code === 200) {
|
||||
state.data = res.data;
|
||||
state.list = res.data?.productInfo ?? [];
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
app.$message.error(err.msg);
|
||||
})
|
||||
.finally(() => {
|
||||
state.loading = false;
|
||||
});
|
||||
};
|
||||
|
||||
watch(
|
||||
() => props.row,
|
||||
(val) => {
|
||||
val?.id && loadData();
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.custom-info {
|
||||
:deep(.avue-crud__header) {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-09-18 21:24:29
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-07 10:01:57
|
||||
* @LastEditTime: 2025-02-08 17:26:25
|
||||
*/
|
||||
|
||||
import { defineConfig, loadEnv } from 'vite';
|
||||
@ -23,7 +23,6 @@ import { resolve } from 'path';
|
||||
const useDevMode = true;
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
console.log('vite.config.js', command, mode, loadEnv(mode, process.cwd()));
|
||||
const {
|
||||
VITE_PORT,
|
||||
VITE_APP_NAME,
|
||||
@ -31,8 +30,8 @@ export default defineConfig(({ command, mode }) => {
|
||||
VITE_APP_BASE_URL,
|
||||
VITE_APP_UPLOAD_API,
|
||||
VITE_APP_UPLOAD_URL,
|
||||
VITE_APP_DICDATA_API,
|
||||
VITE_APP_DICDATA_URL,
|
||||
VITE_APP_SYSTEM_API,
|
||||
VITE_APP_SYSTEM_URL,
|
||||
} = loadEnv(mode, process.cwd());
|
||||
const config = {
|
||||
base: './',
|
||||
@ -53,17 +52,17 @@ export default defineConfig(({ command, mode }) => {
|
||||
[VITE_APP_BASE_API]: {
|
||||
target: VITE_APP_BASE_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/traceApis/, ''),
|
||||
rewrite: (path) => path.replace(/^\/apis/, ''),
|
||||
},
|
||||
[VITE_APP_UPLOAD_API]: {
|
||||
target: VITE_APP_UPLOAD_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/uploadApis/, ''),
|
||||
},
|
||||
[VITE_APP_DICDATA_API]: {
|
||||
target: VITE_APP_DICDATA_URL,
|
||||
[VITE_APP_SYSTEM_API]: {
|
||||
target: VITE_APP_SYSTEM_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/dicDataApis/, ''),
|
||||
rewrite: (path) => path.replace(/^\/systemApis/, ''),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -3,10 +3,10 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2022-02-23 21:12:37
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-01-25 17:03:51
|
||||
* @LastEditTime: 2025-02-10 14:45:39
|
||||
*/
|
||||
import lodash from 'lodash';
|
||||
import moment from 'moment';
|
||||
import dayjs from 'dayjs';
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
/**
|
||||
@ -90,7 +90,7 @@ export const setDefaultOption = (options, prop, defaultVal) => {
|
||||
return options[prop] === undefined ? defaultVal : options.prop;
|
||||
};
|
||||
/**
|
||||
* 设置字典值
|
||||
* @Title 设置字典值
|
||||
* @param {*} columns
|
||||
* @param {*} key
|
||||
* @param {*} data
|
||||
@ -107,7 +107,7 @@ export const setDicData = (columns, key, data = []) => {
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 求字段lable
|
||||
* @Title 求字段lable
|
||||
* @param {*} tree
|
||||
* @returns
|
||||
*/
|
||||
@ -124,7 +124,35 @@ export const setDicLabel = (dicData, value) => {
|
||||
return label;
|
||||
};
|
||||
/**
|
||||
* 加密
|
||||
* @Title 数组交集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const intersectionArray = (arr1 = [], arr2 = []) => {
|
||||
return arr1.filter((item) => arr2.includes(item));
|
||||
};
|
||||
/**
|
||||
* @Title 数组并集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const unionArray = (arr1 = [], arr2 = []) => {
|
||||
return Array.from(new Set([...arr1, ...arr2]));
|
||||
};
|
||||
/**
|
||||
* @Title 数组差集
|
||||
* @param {*} arr1
|
||||
* @param {*} arr2
|
||||
* @returns
|
||||
*/
|
||||
export const differenceArray = (arr1 = [], arr2 = []) => {
|
||||
const s = new Set(arr2);
|
||||
return arr1.filter((x) => !s.has(x));
|
||||
};
|
||||
/**
|
||||
* @Title 加密
|
||||
* @param {*} n
|
||||
* @returns
|
||||
*/
|
||||
@ -146,7 +174,7 @@ export const encode = (n, flag = false) => {
|
||||
return n;
|
||||
};
|
||||
/**
|
||||
* 解密
|
||||
* @Title 解密
|
||||
* @param {*} e
|
||||
* @returns
|
||||
*/
|
||||
@ -190,6 +218,22 @@ export const imageToBase64 = (file) => {
|
||||
export const bufferToBase64 = (buffer) => {
|
||||
return 'data:image/jpeg;base64,' + window.btoa(new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), ''));
|
||||
};
|
||||
/**
|
||||
* @Title blob转json
|
||||
* @param {*} file
|
||||
* @returns
|
||||
*/
|
||||
export const blobToJSON = (blob) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.readAsText(blob, 'utf-8');
|
||||
reader.onload = () => {
|
||||
const res = !isEmpty(reader.result) ? JSON.parse(reader.result) : reader.result;
|
||||
resolve(res);
|
||||
};
|
||||
reader.onerror = reject;
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @Title 将array转化为树
|
||||
* @param tree
|
||||
@ -227,42 +271,76 @@ export const getUrlQuery = (name) => {
|
||||
const usp = new URLSearchParams(search);
|
||||
return usp.get(name);
|
||||
};
|
||||
/**
|
||||
* @Title 将Object参数转换为字符串
|
||||
* @param {*} json
|
||||
* @returns
|
||||
*/
|
||||
export const obj2Param = (json) => {
|
||||
if (!json) return '';
|
||||
return Object.keys(json)
|
||||
.map((key) => {
|
||||
if (isEmpty(json[key])) return '';
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
|
||||
})
|
||||
.join('&');
|
||||
};
|
||||
/**
|
||||
* @Title 获取静态资源文件
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
export const getAssetsFile = (url) => {
|
||||
return new URL(`../assets/images/${url}`, import.meta.url);
|
||||
return new URL(`../assets/${url}`, import.meta.url);
|
||||
};
|
||||
/**
|
||||
* @Title 替换图片url字段值
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
export const setUploadField = (url) => {
|
||||
if (isEmpty(url) || url.includes('http')) return null;
|
||||
return url;
|
||||
};
|
||||
/**
|
||||
* @Title: a链接方式文件下载
|
||||
* @param {void} content:
|
||||
* @Title: 下载文件
|
||||
* @param {void} url:
|
||||
* @param {void} fileName:
|
||||
* @param {void} fileType:
|
||||
* @return {void}
|
||||
*/
|
||||
export const dowloadLink = (content, fileName) => {
|
||||
const blob = new Blob([content]);
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = URL.createObjectURL(blob);
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
export const downloadFile = async (url, fileName, fileType) => {
|
||||
let blob = null;
|
||||
try {
|
||||
switch (fileType) {
|
||||
case 'image': {
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'Anonymous';
|
||||
img.src = url;
|
||||
await new Promise((resolve, reject) => {
|
||||
img.onload = resolve;
|
||||
img.onerror = reject;
|
||||
});
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
const ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
blob = await new Promise((resolve) => {
|
||||
canvas.toBlob(resolve, 'image/jpeg');
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'blob': {
|
||||
blob = new Blob([url]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ('download' in document.createElement('a')) {
|
||||
const elink = document.createElement('a');
|
||||
elink.download = fileName;
|
||||
elink.style.display = 'none';
|
||||
elink.href = blob ? URL.createObjectURL(blob) : url;
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
blob && URL.revokeObjectURL(elink.href);
|
||||
document.body.removeChild(elink);
|
||||
} else {
|
||||
navigator.msSaveBlob(blob, fileName);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('下载出错:', error);
|
||||
}
|
||||
};
|
||||
/**
|
||||
@ -275,20 +353,106 @@ export const sleep = (duration = 0) =>
|
||||
setTimeout(resolve, duration);
|
||||
});
|
||||
/**
|
||||
* 日期格式化
|
||||
* @Title 创建id
|
||||
* @param {*} prefix
|
||||
* @returns
|
||||
*/
|
||||
export const createId = (prefix) => {
|
||||
const val = Date.now() + Math.ceil(Math.random() * 99999);
|
||||
return isEmpty(prefix) ? val : prefix + '-' + val;
|
||||
};
|
||||
/**
|
||||
* @Title 生成数据
|
||||
* @param {*} duration
|
||||
* @returns
|
||||
*/
|
||||
export const mockData = (item = {}, len = 1) => {
|
||||
const list = [];
|
||||
for (let i = 0; i < len; i++) {
|
||||
let temp = { ...item, id: createId() };
|
||||
list.push(temp);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
/**
|
||||
* @Title 日期格式化
|
||||
* @param {*} date
|
||||
* @param {*} format
|
||||
* @returns
|
||||
*/
|
||||
export const dateFormat = (datetime, type = 'yyyy-MM-dd') => {
|
||||
return moment(datetime).format(type);
|
||||
export const dateFormat = (datetime, formater = 'YYYY-MM-DD hh:mm:ss') => {
|
||||
if (datetime instanceof Date || datetime) {
|
||||
return dayjs(datetime).format(formater);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 上日/周/月/年
|
||||
* @Title 字符串转日期
|
||||
* @param {*} str
|
||||
* @returns
|
||||
*/
|
||||
export const lastDate = (last = 0, date = 'month', type = 'yyyy-MM-dd') => {
|
||||
if (date === 'day') {
|
||||
return moment().subtract(last, 'day').endOf('day').format(type);
|
||||
}
|
||||
return moment().subtract(last, date).format(type);
|
||||
export const toDate = (str) => {
|
||||
return !isEmpty(str) ? dayjs(str) : dayjs();
|
||||
};
|
||||
/**
|
||||
* @Title 字符串转日期
|
||||
* @param {*} str
|
||||
* @returns
|
||||
*/
|
||||
export const getDate = (num, type, formater = 'YYYY-MM-DD', start = true) => {
|
||||
const date = dayjs().subtract(num, type);
|
||||
return start ? date.startOf(type).format(formater) : date.endOf(type).format(formater);
|
||||
};
|
||||
/**
|
||||
* @Title: 获取时间差
|
||||
* @param start
|
||||
* @param end
|
||||
* @param type
|
||||
* @returns
|
||||
*/
|
||||
export const getDiffTime = (start, end, type) => {
|
||||
const startTime = dayjs(start);
|
||||
const endTime = dayjs(end);
|
||||
const duration = endTime.diff(startTime);
|
||||
let diff = 0;
|
||||
switch (type) {
|
||||
case 'DD': {
|
||||
diff = duration / (1000 * 60 * 60 * 24);
|
||||
break;
|
||||
}
|
||||
case 'HH': {
|
||||
diff = duration / (1000 * 60 * 60);
|
||||
break;
|
||||
}
|
||||
case 'mm': {
|
||||
diff = duration / (1000 * 60);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Math.round(diff);
|
||||
};
|
||||
/**
|
||||
* @Title: 开始日期
|
||||
* @param last
|
||||
* @param type
|
||||
* @param formater
|
||||
* @returns
|
||||
*/
|
||||
export const startDate = (num, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
|
||||
if (num === 'now') return dayjs().format(formater);
|
||||
if (typeof num === 'string') return dayjs(num).startOf(type).format(formater);
|
||||
return num === 0 ? dayjs().startOf(type).format(formater) : dayjs().subtract(num, type).startOf(type).format(formater);
|
||||
};
|
||||
/**
|
||||
* @Title: 结束日期
|
||||
* @param num
|
||||
* @param type
|
||||
* @param formater
|
||||
* @returns
|
||||
*/
|
||||
export const endDate = (num = 0, type = 'month', formater = 'YYYY-MM-DD HH:mm:ss') => {
|
||||
if (num === 'now') return dayjs().format(formater);
|
||||
if (typeof num === 'string') return dayjs(num).endOf(type).format(formater);
|
||||
return num === 0 ? dayjs().endOf(type).format(formater) : dayjs().subtract(num, type).endOf(type).format(formater);
|
||||
};
|
||||
|
@ -23,7 +23,6 @@ import { resolve } from 'path';
|
||||
const useDevMode = true;
|
||||
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
console.log('vite.config.js', command, mode, loadEnv(mode, process.cwd()));
|
||||
const { VITE_PORT, VITE_APP_NAME, VITE_APP_BASE_API, VITE_APP_BASE_URL, VITE_APP_UPLOAD_API, VITE_APP_UPLOAD_URL } = loadEnv(mode, process.cwd());
|
||||
const config = {
|
||||
base: './',
|
||||
|
Loading…
x
Reference in New Issue
Block a user