Merge branch 'main' into shen

pull/1/head
Dragon 1 year ago
commit a80a2f4055

@ -1,3 +1,32 @@
diff --git a/node_modules/naive-ui/es/form/src/FormItem.mjs b/node_modules/naive-ui/es/form/src/FormItem.mjs
index 3aacec9..a63ab54 100644
--- a/node_modules/naive-ui/es/form/src/FormItem.mjs
+++ b/node_modules/naive-ui/es/form/src/FormItem.mjs
@@ -73,8 +73,8 @@ function wrapValidator(validator, async) {
try {
const validateResult = validator(...args);
if (!async && (typeof validateResult === 'boolean' || validateResult instanceof Error || Array.isArray(validateResult)) || (
- // Error[]
- validateResult === null || validateResult === void 0 ? void 0 : validateResult.then)) {
+ // Error[]
+ validateResult === null || validateResult === void 0 ? void 0 : validateResult.then)) {
return validateResult;
} else if (validateResult === undefined) {
return true;
@@ -479,8 +479,11 @@ export default defineComponent({
class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--warning`
}, feedbackNodes) : mergedValidationStatus === 'error' ? h("div", {
key: "controlled-error",
- class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--error`
- }, feedbackNodes) : mergedValidationStatus === 'success' ? h("div", {
+ class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--error flex`
+ }, [h('img', {
+ style: { width: '1rem', height: '1rem' },
+ src: 'http://47.93.59.251/api/upload/ocr/1711419313955_c.png'
+ }), feedbackNodes]) : mergedValidationStatus === 'success' ? h("div", {
key: "controlled-success",
class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--success`
}, feedbackNodes) : h("div", {
diff --git a/node_modules/naive-ui/es/pagination/src/Pagination.mjs b/node_modules/naive-ui/es/pagination/src/Pagination.mjs diff --git a/node_modules/naive-ui/es/pagination/src/Pagination.mjs b/node_modules/naive-ui/es/pagination/src/Pagination.mjs
index 5bd975b..e1c6ebc 100644 index 5bd975b..e1c6ebc 100644
--- a/node_modules/naive-ui/es/pagination/src/Pagination.mjs --- a/node_modules/naive-ui/es/pagination/src/Pagination.mjs
@ -11,3 +40,124 @@ index 5bd975b..e1c6ebc 100644
default: default:
return null; return null;
} }
diff --git a/node_modules/naive-ui/lib/form/src/FormItem.js b/node_modules/naive-ui/lib/form/src/FormItem.js
index 4f47aad..6dae078 100644
--- a/node_modules/naive-ui/lib/form/src/FormItem.js
+++ b/node_modules/naive-ui/lib/form/src/FormItem.js
@@ -24,7 +24,8 @@ const styles_1 = require("../styles");
const utils_1 = require("./utils");
const context_1 = require("./context");
const form_item_cssr_1 = __importDefault(require("./styles/form-item.cssr"));
-exports.formItemProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), { label: String, labelWidth: [Number, String], labelStyle: [String, Object], labelAlign: String, labelPlacement: String, path: String, first: Boolean, rulePath: String, required: Boolean, showRequireMark: {
+exports.formItemProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props), {
+ label: String, labelWidth: [Number, String], labelStyle: [String, Object], labelAlign: String, labelPlacement: String, path: String, first: Boolean, rulePath: String, required: Boolean, showRequireMark: {
type: Boolean,
default: undefined
}, requireMarkPlacement: String, showFeedback: {
@@ -33,7 +34,8 @@ exports.formItemProps = Object.assign(Object.assign({}, _mixins_1.useTheme.props
}, rule: [Object, Array], size: String, ignorePathChange: Boolean, validationStatus: String, feedback: String, showLabel: {
type: Boolean,
default: undefined
- }, labelProps: Object });
+ }, labelProps: Object
+});
exports.formItemPropKeys = (0, _utils_1.keysOf)(exports.formItemProps);
// wrap sync validator
function wrapValidator(validator, async) {
@@ -175,22 +177,22 @@ exports.default = (0, vue_1.defineComponent)({
}))
.filter(shouldRuleBeApplied)
.map((rule, i) => {
- const shallowClonedRule = Object.assign({}, rule);
- if (shallowClonedRule.validator) {
- shallowClonedRule.validator = wrapValidator(shallowClonedRule.validator, false);
- }
- if (shallowClonedRule.asyncValidator) {
- shallowClonedRule.asyncValidator = wrapValidator(shallowClonedRule.asyncValidator, true);
- }
- if (shallowClonedRule.renderMessage) {
- const rendererKey = `__renderMessage__${i}`;
- originalMessageRendersMessage[rendererKey] =
- shallowClonedRule.message;
- shallowClonedRule.message = rendererKey;
- messageRenderers[rendererKey] = shallowClonedRule.renderMessage;
- }
- return shallowClonedRule;
- });
+ const shallowClonedRule = Object.assign({}, rule);
+ if (shallowClonedRule.validator) {
+ shallowClonedRule.validator = wrapValidator(shallowClonedRule.validator, false);
+ }
+ if (shallowClonedRule.asyncValidator) {
+ shallowClonedRule.asyncValidator = wrapValidator(shallowClonedRule.asyncValidator, true);
+ }
+ if (shallowClonedRule.renderMessage) {
+ const rendererKey = `__renderMessage__${i}`;
+ originalMessageRendersMessage[rendererKey] =
+ shallowClonedRule.message;
+ shallowClonedRule.message = rendererKey;
+ messageRenderers[rendererKey] = shallowClonedRule.renderMessage;
+ }
+ return shallowClonedRule;
+ });
const activeErrorRules = activeRules.filter((r) => r.level !== 'warning');
const activeWarningRules = activeRules.filter((r) => r.level === 'warning');
const mergedPath = path !== null && path !== void 0 ? path : '__n_no_path__';
@@ -353,31 +355,37 @@ exports.default = (0, vue_1.defineComponent)({
const textNode = ((0, vue_1.h)("span", { class: `${mergedClsPrefix}-form-item-label__text` }, labelText));
const markNode = renderedShowRequireMark ? ((0, vue_1.h)("span", { class: `${mergedClsPrefix}-form-item-label__asterisk` }, mergedRequireMarkPlacement !== 'left' ? '\u00A0*' : '*\u00A0')) : (mergedRequireMarkPlacement === 'right-hanging' && ((0, vue_1.h)("span", { class: `${mergedClsPrefix}-form-item-label__asterisk-placeholder` }, '\u00A0*')));
const { labelProps } = this;
- return ((0, vue_1.h)("label", Object.assign({}, labelProps, { class: [
+ return ((0, vue_1.h)("label", Object.assign({}, labelProps, {
+ class: [
labelProps === null || labelProps === void 0 ? void 0 : labelProps.class,
`${mergedClsPrefix}-form-item-label`,
`${mergedClsPrefix}-form-item-label--${mergedRequireMarkPlacement}-mark`,
this.reverseColSpace &&
- `${mergedClsPrefix}-form-item-label--reverse-columns-space`
- ], style: this.mergedLabelStyle, ref: "labelElementRef" }), mergedRequireMarkPlacement === 'left'
+ `${mergedClsPrefix}-form-item-label--reverse-columns-space`
+ ], style: this.mergedLabelStyle, ref: "labelElementRef"
+ }), mergedRequireMarkPlacement === 'left'
? [markNode, textNode]
: [textNode, markNode]));
};
- return ((0, vue_1.h)("div", { class: [
+ return ((0, vue_1.h)("div", {
+ class: [
`${mergedClsPrefix}-form-item`,
this.themeClass,
`${mergedClsPrefix}-form-item--${this.mergedSize}-size`,
`${mergedClsPrefix}-form-item--${this.mergedLabelPlacement}-labelled`,
this.isAutoLabelWidth &&
- `${mergedClsPrefix}-form-item--auto-label-width`,
+ `${mergedClsPrefix}-form-item--auto-label-width`,
!mergedShowLabel && `${mergedClsPrefix}-form-item--no-label`
- ], style: this.cssVars },
+ ], style: this.cssVars
+ },
mergedShowLabel && renderLabel(),
- (0, vue_1.h)("div", { class: [
+ (0, vue_1.h)("div", {
+ class: [
`${mergedClsPrefix}-form-item-blank`,
this.mergedValidationStatus &&
- `${mergedClsPrefix}-form-item-blank--${this.mergedValidationStatus}`
- ] }, $slots),
+ `${mergedClsPrefix}-form-item-blank--${this.mergedValidationStatus}`
+ ]
+ }, $slots),
this.mergedShowFeedback ? ((0, vue_1.h)("div", { key: this.feedbackId, class: `${mergedClsPrefix}-form-item-feedback-wrapper` },
(0, vue_1.h)(vue_1.Transition, { name: "fade-down-transition", mode: "out-in" }, {
default: () => {
@@ -386,7 +394,9 @@ exports.default = (0, vue_1.defineComponent)({
var _a;
const { feedback } = this;
const feedbackNodes = children || feedback ? ((0, vue_1.h)("div", { key: "__feedback__", class: `${mergedClsPrefix}-form-item-feedback__line` }, children || feedback)) : this.renderExplains.length ? ((_a = this.renderExplains) === null || _a === void 0 ? void 0 : _a.map(({ key, render }) => ((0, vue_1.h)("div", { key: key, class: `${mergedClsPrefix}-form-item-feedback__line` }, render())))) : null;
- return feedbackNodes ? (mergedValidationStatus === 'warning' ? ((0, vue_1.h)("div", { key: "controlled-warning", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--warning` }, feedbackNodes)) : mergedValidationStatus === 'error' ? ((0, vue_1.h)("div", { key: "controlled-error", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--error` }, feedbackNodes)) : mergedValidationStatus === 'success' ? ((0, vue_1.h)("div", { key: "controlled-success", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--success` }, feedbackNodes)) : ((0, vue_1.h)("div", { key: "controlled-default", class: `${mergedClsPrefix}-form-item-feedback` }, feedbackNodes))) : null;
+ return feedbackNodes ? (mergedValidationStatus === 'warning' ? ((0, vue_1.h)("div", { key: "controlled-warning", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--warning` }, feedbackNodes)) : mergedValidationStatus === 'error' ? ((0, vue_1.h)("div", { key: "controlled-error", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--error flex` }, [h('img', {
+ style: { width: '1rem', height: '1rem' },src: 'http://47.93.59.251/api/upload/ocr/1711419313955_c.png'
+ }), feedbackNodes])) : mergedValidationStatus === 'success' ? ((0, vue_1.h)("div", { key: "controlled-success", class: `${mergedClsPrefix}-form-item-feedback ${mergedClsPrefix}-form-item-feedback--success` }, feedbackNodes)) : ((0, vue_1.h)("div", { key: "controlled-default", class: `${mergedClsPrefix}-form-item-feedback` }, feedbackNodes))) : null;
});
}
}))) : null));

@ -1,8 +1,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { dateZhCN, zhCN } from "naive-ui"; import { dateZhCN, zhCN } from "naive-ui";
import { computed, onMounted, nextTick } from "vue"; import { computed, onMounted, nextTick,inject } from "vue";
import { AppProvider } from "@/components/Application"; import { AppProvider } from "@/components/Application";
import { lighten } from "@/utils/index"; import { lighten } from "@/utils/index";
import mouseTrapBind from '@/hooks/event/mouseTrapBind'
const mousetrap = inject('mousetrap') as any
onMounted(()=>{
mouseTrapBind(mousetrap);
})
const getThemeOverrides = computed(() => { const getThemeOverrides = computed(() => {
const theme = "#1980FF"; const theme = "#1980FF";

@ -153,6 +153,20 @@ export async function oneClickCheck(params: Partial<CheckParam> = { search_histo
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA }, headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
}) })
} }
/**
*
* @param note
* @returns
*/
export async function removeCheckDuplicate(checkDuplicateNo) {
return http.request({
url: `/ocr/checkDuplicate/removeCheckDuplicate`,
method: 'get',
params: { checkDuplicateNo },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
}
/** /**
* *
* @param * @param

@ -1,5 +1,5 @@
import { http } from '@/utils/http/axios' import { http } from '@/utils/http/axios'
import type { PageParam, PictureSortParam, SetTFParam } from '/#/api' import type { PageParam, PictureSortParam, SetTFParam, SimilarityPictureSortParam } from '/#/api'
import { ContentTypeEnum } from '@/enums/httpEnum' import { ContentTypeEnum } from '@/enums/httpEnum'
@ -9,7 +9,25 @@ import { ContentTypeEnum } from '@/enums/httpEnum'
*/ */
export async function getPackageList(params: PageParam, packagename: string) { export async function getPackageList(params: PageParam, packagename: string) {
const res = await http.request({ const res = await http.request({
url: `/ocr/ocrPackagetask/list`, url: `/ocr/ocrTaskPackage/getPackageList`,
method: 'get',
params: { ...params, packagename },
})
const { data: { records, pages } } = res
return {
pageCount: pages,
data: records,
}
}
/**
* -
* @returns
*/
export async function getPackagePicture(params: PageParam, packagename: string) {
const res = await http.request({
url: `/ocr/ocrPicture/getPackagePicture`,
method: 'get', method: 'get',
params: { ...params, packagename }, params: { ...params, packagename },
}) })
@ -44,16 +62,14 @@ export async function getPackageTaskList(packageid: string, params: PageParam) {
} }
/** /**
* () * -
* @param id id * @param checkDuplicateId id
* @param packageid id
* @returns * @returns
*/ */
export async function getTaskDetailInfo(taskId: string, packageid: string) { export async function getTaskDetailInfo(checkDuplicateId: string) {
const pid = packageid || 0
const res = await http.request({ const res = await http.request({
url: `/backstage/jifen/ocrtaskchildpicture/getdata/${taskId}/${pid}`, url: `/ocr/ocrPicture/getPackagePicture?checkDuplicateId=${checkDuplicateId}`,
method: 'get', method: 'get',
}) })
@ -67,11 +83,10 @@ export async function getTaskDetailInfo(taskId: string, packageid: string) {
* @param params * @param params
* @returns * @returns
*/ */
export async function getTaskDetailPictureList(packageid: string, taskchildpictureid: string, params: PageParam & PictureSortParam) { export async function getTaskDetailPictureList(params: PageParam & PictureSortParam & SimilarityPictureSortParam) {
const pid = packageid || 0
const res = await http.request({ const res = await http.request({
url: `/backstage/jifen/ocrtaskchildpicture/listbypictureid/${pid}/${taskchildpictureid}`, url: `/backstage/jifen/ocrtaskchildpicture/getPictureSimilarityList`,
method: 'get', method: 'get',
params, params,
}) })
@ -79,20 +94,22 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
const { data: { records, pages, total } } = res const { data: { records, pages, total } } = res
// 精简一下数据 // 精简一下数据
const list = records.map((item) => { const list = records.map((item,index) => {
return { return {
id: item.id, id: item.id,
taskId: item.taskId, taskId: item.taskId,
taskname: item.fromtaskname, taskname: item.fromtaskname,
assignee: item.assignee, assignee: item.assignee,
pictureid: item.pictureid, pictureid: item.pictureid,
imgurl: item.ocrPicture.imgurl, imgurl: item.imgUrl,
thumburl: item.ocrPicture.serverThumbnailUrl || item.ocrPicture.imgurl, thumburl: item.ocrPicture?.serverThumbnailUrl || item.ocrPicture?.imgurl,
iztrueorfalse: item.iztrueorfalse, iztrueorfalse: item.iztrueorfalse,
states: item.states, states: item.states,
history: hasHistory(item.ocpictureid, item.picturecompare), history: item.ocpictureid && item.picturecompare && hasHistory(item.ocpictureid, item.picturecompare),
} }
}) })
return { return {
pageCount: pages, pageCount: pages,
data: list, data: list,

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>关闭</title>
<defs>
<rect id="path-1" x="0" y="0" width="64" height="64"></rect>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="PrevailCloud-Design-图标集" transform="translate(-2512.000000, -4463.000000)">
<g id="关闭" transform="translate(2512.000000, 4463.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g id="编组-39" mask="url(#mask-2)">
<g transform="translate(8.000000, 8.000000)">
<rect id="矩形" fill="none" x="0" y="0" width="48" height="48"></rect>
<path d="M6.69150312,3.16140864 L23.9995365,20.4685365 L41.3084969,3.16140864 C41.6628011,2.80710441 42.2203082,2.77985024 42.6058744,3.07964613 L42.6984668,3.16140864 L44.8385914,5.30153325 C45.2224209,5.68536283 45.2224209,6.30767353 44.8385914,6.69150312 L44.8385914,6.69150312 L27.5295365,23.9995365 L44.8385914,41.3084969 C45.2224209,41.6923265 45.2224209,42.3146372 44.8385914,42.6984668 L42.6984668,44.8385914 C42.3146372,45.2224209 41.6923265,45.2224209 41.3084969,44.8385914 L23.9995365,27.5295365 L6.69150312,44.8385914 C6.33719889,45.1928956 5.77969181,45.2201498 5.3941256,44.9203539 L5.30153325,44.8385914 L3.16140864,42.6984668 C2.77757906,42.3146372 2.77757906,41.6923265 3.16140864,41.3084969 L3.16140864,41.3084969 L20.4685365,23.9995365 L3.16140864,6.69150312 C2.77757906,6.30767353 2.77757906,5.68536283 3.16140864,5.30153325 L5.30153325,3.16140864 C5.68536283,2.77757906 6.30767353,2.77757906 6.69150312,3.16140864 Z" id="形状结合" fill="#666666" fill-rule="evenodd"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>展开</title>
<defs>
<rect id="path-1" x="0" y="0" width="64" height="64"></rect>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="PrevailCloud-Design-图标集" transform="translate(-2512.000000, -2179.000000)">
<g id="展开-2" transform="translate(2512.000000, 2179.000000)">
<g id="展开" transform="translate(32.000000, 32.000000) scale(-1, 1) rotate(-270.000000) translate(-32.000000, -32.000000) ">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g id="编组" mask="url(#mask-2)" fill="#666666">
<g transform="translate(32.398318, 32.358039) scale(-1, 1) translate(-32.398318, -32.358039) translate(18.781652, 8.065215)" id="形状结合">
<path d="M7.27477106e-13,24.1889844 C0.0208813961,23.5597929 0.271458149,22.9368064 0.75173026,22.4565343 L0.75173026,22.4565343 L1.10421929,22.1040453 C1.1915415,22.0167231 1.28358153,21.9369941 1.3795189,21.8648584 L22.8677171,0.376576996 C23.3698198,-0.125525665 24.183889,-0.125525665 24.6859917,0.376576996 L26.8567553,2.54734061 C27.358858,3.04944327 27.358858,3.86351253 26.8567553,4.36561519 L6.929,24.293 L26.8567553,44.2200322 C27.3253845,44.6886613 27.3566264,45.429048 26.9504812,45.9339115 L26.8567553,46.0383067 L24.6859917,48.2090704 C24.183889,48.711173 23.3698198,48.711173 22.8677171,48.2090704 L22.8677171,48.2090704 L1.37441953,26.7169448 C1.28031918,26.6458236 1.18999323,26.567376 1.10421929,26.4816021 L0.75173026,26.129113 C0.271458149,25.6488409 0.0208813961,25.0258544 -1.7706149e-13,24.3966629 Z" transform="translate(13.616666, 24.292824) scale(1, -1) translate(-13.616666, -24.292824) "></path>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="64px" height="64px" viewBox="0 0 64 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>刷新</title>
<defs>
<rect id="path-1" x="0" y="0" width="64" height="64"></rect>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="PrevailCloud-Design-图标集" transform="translate(-664.000000, -4776.000000)">
<g id="刷新" transform="translate(664.000000, 4776.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g id="编组" mask="url(#mask-2)" fill="#666666">
<g transform="translate(6.995021, 6.975001)" id="形状结合">
<path d="M49.0099572,25.0249986 C49.5622419,25.0249986 50.0099572,25.4727138 50.0099572,26.0249986 L50.0099572,26.0259985 L49.9999581,26.2615845 C49.3553776,39.5080844 38.4112759,50.0499972 25.0049786,50.0499972 C16.58645,50.0499972 9.13882756,45.8930539 4.60277334,39.5198292 L1.67101425,41.8104464 C1.58334606,41.8789403 1.47533829,41.9162394 1.36408594,41.9164402 C1.08794402,41.9169386 0.863682725,41.6934854 0.863184328,41.4173435 L0.863184328,41.4173435 L0.844095019,30.8407325 C0.844020336,30.7993536 0.849082518,30.7581254 0.859165449,30.7179937 C0.92645382,30.4501749 1.19811182,30.2876129 1.46593058,30.3549013 L1.46593058,30.3549013 L11.7237529,32.9321374 C11.831652,32.9592466 11.927428,33.0215672 11.9959219,33.1092354 C12.1659321,33.3268385 12.1273504,33.6410613 11.9097473,33.8110715 L11.9097473,33.8110715 L8.56747628,36.4214918 C12.1791746,41.6209567 18.1945483,45.0249986 25.0049786,45.0249986 C35.7054956,45.0249986 44.4432922,36.6215932 44.9789547,26.0541959 L44.979571,26.0259985 L44.9811223,26.0259985 L44.9811223,26.0249986 C44.9811223,25.4727138 45.4288375,25.0249986 45.9811223,25.0249986 L49.0099572,25.0249986 Z M25.0049786,0 C33.321686,0 40.6908312,4.05699588 45.2413203,10.2998936 L47.905662,8.06524095 C47.9908864,7.99372921 48.0975266,7.95268339 48.2087042,7.94860007 C48.4846605,7.93846476 48.7165836,8.15395526 48.7267189,8.42991158 L48.7267189,8.42991158 L49.114915,18.9994134 C49.1164337,19.0407645 49.1128135,19.0821442 49.1041373,19.1226034 C49.0462366,19.3926073 48.7804175,19.564551 48.5104135,19.5066503 L48.5104135,19.5066503 L38.1688957,17.2889771 C38.0601163,17.26565 37.9622237,17.2067099 37.8907119,17.1214855 C37.713211,16.9099482 37.740803,16.5945704 37.9523403,16.4170695 L37.9523403,16.4170695 L41.3811509,13.5407149 C37.7629138,8.39075675 31.7770037,5.0249986 25.0049786,5.0249986 C14.2950415,5.0249986 5.55128214,13.4432061 5.02960686,24.0237149 C5.0297706,24.5377427 4.6437421,24.9604992 4.14640425,25.0182704 L4.02978319,25.0249986 L1,25.0249986 C0.487164161,25.0249986 0.0644928393,24.6389584 0.00672773133,24.1416197 L0,24.0249986 L0,24.0239987 C0.525328666,10.6668647 11.5194638,0 25.0049786,0 Z"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 208 KiB

@ -0,0 +1,11 @@
const commonKeyDown = (keyCode: number) => {
document.dispatchEvent(new KeyboardEvent('keydown', { keyCode }));
}
const c = () => {
commonKeyDown(27)
}
const initBind = (mousetrap) => {
mousetrap.bind('c', c)
}
export default initBind;

@ -134,10 +134,10 @@ const options = computed(() => {
.container { .container {
.header{ .header{
.user-name{ .user-name{
font-size: 21px; font-size: 16px;
} }
.depart-name{ .depart-name{
font-size: 16px; font-size: 12px;
} }
} }
} }

@ -32,7 +32,7 @@ const routes: Array<RouteRecordRaw> = [
path: 'message', path: 'message',
name: 'message-main', name: 'message-main',
meta: { meta: {
title: 'message', title: '消息通知',
}, },
component: () => import('@/views/message/index.vue'), component: () => import('@/views/message/index.vue'),
}, },

@ -1,8 +1,8 @@
import { defineStore } from 'pinia'
import type { OrderState, PackageListItem } from '/#/workorder'
import { useMessage } from 'naive-ui'
import { getPackageList } from '@/api/work/work' import { getPackageList } from '@/api/work/work'
import { store } from '@/store' import { store } from '@/store'
import { useMessage } from 'naive-ui'
import { defineStore } from 'pinia'
import type { OrderState, PackageListItem } from '/#/workorder'
export const useWorkOrderStore = defineStore({ export const useWorkOrderStore = defineStore({
id: 'work-order', id: 'work-order',
@ -11,6 +11,7 @@ export const useWorkOrderStore = defineStore({
activeId: '', activeId: '',
packageList: [], packageList: [],
immersion: false, immersion: false,
name: ''
}), }),
getters: { getters: {
getActiveId: (state: OrderState) => state.activeId, getActiveId: (state: OrderState) => state.activeId,
@ -24,7 +25,7 @@ export const useWorkOrderStore = defineStore({
setActive(index: number, orderId?: string) { setActive(index: number, orderId?: string) {
this.currentIndex = index this.currentIndex = index
const order = this.packageList[index] const order = this.packageList[index]
this.activeId = orderId || order?.id this.activeId = orderId || order?.checkDuplicateId
}, },
forward() { forward() {
const len = this.packageList.length const len = this.packageList.length
@ -45,7 +46,6 @@ export const useWorkOrderStore = defineStore({
}, },
async fetchOrderList(pagination, keyword) { async fetchOrderList(pagination, keyword) {
const res = await getPackageList(pagination, keyword) const res = await getPackageList(pagination, keyword)
if (res.data&&res.data.length > 0) { if (res.data&&res.data.length > 0) {
this.packageList.push(...res.data) this.packageList.push(...res.data)
if (!this.activeId) if (!this.activeId)

@ -41,7 +41,7 @@ export function checkStatus(status: number, msg: string): void {
$message.error('网络未实现') $message.error('网络未实现')
break break
case 502: case 502:
$message.error('网络错误') $message.error('网络错误,请重试')
break break
case 503: case 503:
$message.error('服务不可用,服务器暂时过载或维护!') $message.error('服务不可用,服务器暂时过载或维护!')

@ -25,7 +25,7 @@ const offList = ref<any[]>([]);
const onList = ref<any[]>([]); const onList = ref<any[]>([]);
const allCount = computed(() => { const allCount = computed(() => {
return `全部筛选(共${offList.value.length - 1}个)`; return `全部筛选(共${offList.value.length}个)`;
}); });
const selectCount = computed(() => { const selectCount = computed(() => {
@ -389,6 +389,7 @@ const rightInputHandler = debounce((keyword) => {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
font-size: 14px;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -446,9 +447,13 @@ const rightInputHandler = debounce((keyword) => {
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
::v-deep(.n-card > .n-card-header .n-card-header__main){ ::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important; font-weight: lighter !important;
font-size: 14px;
} }
::v-deep(.n-scrollbar){ ::v-deep(.n-scrollbar){
border-top: none !important; border-top: none !important;
} }
::v-deep(.n-button--info-type){
background: #507AFD !important;
}
</style> </style>

@ -64,7 +64,6 @@ onMounted(async () => {
} }
offList.value.push(item); offList.value.push(item);
}); });
}); });
const allCount = computed(() => { const allCount = computed(() => {
@ -344,7 +343,7 @@ function removeHandler(id: string, type: "fix" | "unfix") {
<SvgIcon size="14px" name="magnifying-1" /> <SvgIcon size="14px" name="magnifying-1" />
</template> </template>
</n-input> </n-input>
<div class="draggable-ul"> <div class="draggable-ul left-wrap">
<div class="draggable-li"> <div class="draggable-li">
<n-checkbox <n-checkbox
v-model:checked="checkAll" v-model:checked="checkAll"
@ -403,15 +402,12 @@ function removeHandler(id: string, type: "fix" | "unfix") {
:class="{ fix: item.fix }" :class="{ fix: item.fix }"
class="cursor-move draggable-item" class="cursor-move draggable-item"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" v-if="!item.fix"
size="16px" size="16px"
style=" style="display: block; margin-left: auto; cursor: pointer"
display: block;
margin-left: auto;
cursor: pointer;
"
name="clear" name="clear"
@click="removeHandler(item.id, 'fix')" @click="removeHandler(item.id, 'fix')"
/> />
@ -430,15 +426,12 @@ function removeHandler(id: string, type: "fix" | "unfix") {
:class="{ fix: item.fix }" :class="{ fix: item.fix }"
class="cursor-move draggable-item" class="cursor-move draggable-item"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" v-if="!item.fix"
size="16px" size="16px"
style=" style="display: block; margin-left: auto; cursor: pointer"
display: block;
margin-left: auto;
cursor: pointer;
"
name="clear" name="clear"
@click="removeHandler(item.id, 'unfix')" @click="removeHandler(item.id, 'unfix')"
/> />
@ -467,6 +460,8 @@ function removeHandler(id: string, type: "fix" | "unfix") {
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 32px;
&-title { &-title {
font-weight: bold; font-weight: bold;
@ -474,7 +469,6 @@ function removeHandler(id: string, type: "fix" | "unfix") {
} }
&-bar { &-bar {
background-color: #e8e8e8;
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
@ -487,6 +481,8 @@ function removeHandler(id: string, type: "fix" | "unfix") {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
color: #333333;
font-size: 14px;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -507,8 +503,11 @@ function removeHandler(id: string, type: "fix" | "unfix") {
.cardstyle { .cardstyle {
width: 820px; width: 820px;
--n-padding-bottom: 20px; // --n-padding-bottom: 20px;
--n-padding-left: 24px; --n-padding-left: 24px;
--n-padding-right: 24px;
--n-padding-top: 20px;
// padding: 20px 24px 0 24px !important
} }
.textbtnStyle { .textbtnStyle {
@ -540,10 +539,11 @@ function removeHandler(id: string, type: "fix" | "unfix") {
} }
.draggable-item { .draggable-item {
padding: 10px 16px; padding: 11px 16px;
color: #333; color: #333;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #e8e8e8;
} }
.disable-check { .disable-check {
@ -551,9 +551,7 @@ function removeHandler(id: string, type: "fix" | "unfix") {
} }
} }
::v-deep( ::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {
.n-card.n-card--content-segmented > .n-card__content:not(:first-child)
) {
border: 0px; border: 0px;
} }
@ -562,9 +560,19 @@ function removeHandler(id: string, type: "fix" | "unfix") {
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
::v-deep(.n-card > .n-card-header .n-card-header__main) { ::v-deep(.n-card > .n-card-header .n-card-header__main) {
font-weight: bolder !important; font-weight: lighter !important;
font-size: 14px;
} }
::v-deep(.n-scrollbar) { ::v-deep(.n-scrollbar) {
border-top: none !important; border-top: none !important;
} }
::v-deep(.n-button--info-type) {
background: #507afd !important;
}
.left-wrap{
border: 1px solid #cbd3de;
}
// ::v-deep(.n-card__content){
// padding: 20px 24px 0 24px !important;
// }
</style> </style>

@ -84,6 +84,7 @@ const columns: DataTableColumns<RowData> = [
]; ];
const loading = ref(true); const loading = ref(true);
const total = ref(0);
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
pageCount: 1, pageCount: 1,
@ -108,6 +109,7 @@ const pagination = reactive({
}, },
], ],
showQuickJumper: true, showQuickJumper: true,
prefix:()=>`${total.value} 条数据`
}); });
const tableData = ref<Array<RowData>>([]); const tableData = ref<Array<RowData>>([]);
const keyword = ref(""); const keyword = ref("");
@ -118,6 +120,7 @@ async function query(page: number, pageSize: number) {
}; };
const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 1); const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 1);
const { data, pageCount } = result; const { data, pageCount } = result;
total.value = data.total;
tableData.value = data; tableData.value = data;
pagination.page = page; pagination.page = page;
pagination.pageCount = pageCount; pagination.pageCount = pageCount;
@ -204,7 +207,6 @@ async function handlePageSizeChange(currentPageSize) {
await query(page, currentPageSize); await query(page, currentPageSize);
} }
function handleClick() { function handleClick() {
emit("showNewFilter"); emit("showNewFilter");
show.value = false; show.value = false;
@ -335,7 +337,6 @@ const inputHandler = debounce((word) => {
@update:page="handlePageChange" @update:page="handlePageChange"
@update-page-size="handlePageSizeChange" @update-page-size="handlePageSizeChange"
@update:checked-row-keys="handleCheck" @update:checked-row-keys="handleCheck"
/> />
</div> </div>
</div> </div>

@ -1,197 +1,200 @@
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, unref } from 'vue' import { reactive, ref, unref } from "vue";
import * as XLSX from 'xlsx' import * as XLSX from "xlsx";
import { arrayEquals } from '@/utils/index' import { arrayEquals } from "@/utils/index";
import { generateUuid } from '@/utils/uuid' import { generateUuid } from "@/utils/uuid";
const props = defineProps<{ const props = defineProps<{
onSuccess: Function onSuccess: Function;
headerConfig: string[] headerConfig: string[];
}>() }>();
interface ExcelData { interface ExcelData {
header: string[] | null header: string[] | null;
content: any[] | null content: any[] | null;
} }
interface ParseResults { interface ParseResults {
fileName: string fileName: string;
results: any[] results: any[];
uuid: string uuid: string;
} }
const cardStyle = { const cardStyle = {
'width': '620px', width: "620px",
'--n-padding-bottom': '10px', "--n-padding-bottom": "10px",
'--n-padding-left': '0px', "--n-padding-left": "0px",
} };
const inputRef = ref(null) const inputRef = ref(null);
let loading = false let loading = false;
const excelData: ExcelData = { header: null, content: null } const excelData: ExcelData = { header: null, content: null };
const excelDatas: ParseResults[] = reactive([]) const excelDatas: ParseResults[] = reactive([]);
function generateData(content) { function generateData(content) {
excelData.header = props.headerConfig excelData.header = props.headerConfig;
excelData.content = content excelData.content = content;
props.onSuccess && props.onSuccess(excelData) props.onSuccess && props.onSuccess(excelData);
} }
function handleDrop(e) { function handleDrop(e) {
e.stopPropagation() e.stopPropagation();
e.preventDefault() e.preventDefault();
if (loading) if (loading) return;
return const files = e.dataTransfer.files;
const files = e.dataTransfer.files const rawFiles = Array.from(files);
const rawFiles = Array.from(files)
// eslint-disable-next-line dot-notation // eslint-disable-next-line dot-notation
const $message = window['$message'] const $message = window["$message"];
if (!isExcel(rawFiles)) { if (!isExcel(rawFiles)) {
$message.error('Only supports upload .xlsx, .xls, .csv suffix files') $message.error("Only supports upload .xlsx, .xls, .csv suffix files");
return false return false;
} }
uploadFiles(rawFiles) uploadFiles(rawFiles);
e.stopPropagation() e.stopPropagation();
e.preventDefault() e.preventDefault();
} }
async function uploadFiles(files) { async function uploadFiles(files) {
const inputEl: HTMLInputElement | null = unref(inputRef) const inputEl: HTMLInputElement | null = unref(inputRef);
inputEl!.value = '' inputEl!.value = "";
loading = true loading = true;
for (const file of files) { for (const file of files) {
const fileData = await readFileData(file) const fileData = await readFileData(file);
const message = validate(fileData) const message = validate(fileData);
// TODO // TODO
if (message === undefined || true) { if (message === undefined || true) {
const uuid = generateUuid() const uuid = generateUuid();
excelDatas.push({ excelDatas.push({
fileName: file.name, fileName: file.name,
results: (fileData as any).results, results: (fileData as any).results,
uuid, uuid,
}) });
} }
} }
loading = false loading = false;
} }
function commitData() { function commitData() {
const mergeResults: any[] = [] const mergeResults: any[] = [];
if (excelDatas.length === 0) if (excelDatas.length === 0) return;
return
excelDatas.forEach((item) => { excelDatas.forEach((item) => {
mergeResults.push(...item.results) mergeResults.push(...item.results);
}) });
generateData(mergeResults) generateData(mergeResults);
} }
function validate(fileData) { function validate(fileData) {
const { header } = fileData const { header } = fileData;
// //
const equal = arrayEquals(header, props.headerConfig) const equal = arrayEquals(header, props.headerConfig);
if (!equal) if (!equal) return "表头不匹配";
return '表头不匹配'
// TODO // TODO
} }
function readFileData(file) { function readFileData(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const reader = new FileReader() const reader = new FileReader();
reader.onload = (e) => { reader.onload = (e) => {
const data = e.target!.result const data = e.target!.result;
const workbook = XLSX.read(data, { type: 'array' }) const workbook = XLSX.read(data, { type: "array" });
const firstSheetName = workbook.SheetNames[0] const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName] const worksheet = workbook.Sheets[firstSheetName];
const header = getHeaderRow(worksheet) const header = getHeaderRow(worksheet);
const results = XLSX.utils.sheet_to_json(worksheet) const results = XLSX.utils.sheet_to_json(worksheet);
resolve({ header, results }) resolve({ header, results });
} };
reader.readAsArrayBuffer(file) reader.readAsArrayBuffer(file);
}) });
} }
function handleDragover(e) { function handleDragover(e) {
e.stopPropagation() e.stopPropagation();
e.preventDefault() e.preventDefault();
e.dataTransfer.dropEffect = 'copy' e.dataTransfer.dropEffect = "copy";
} }
function handleUpload() { function handleUpload() {
(inputRef.value as any).click() (inputRef.value as any).click();
} }
function handleClick(e) { function handleClick(e) {
const files = e.target.files const files = e.target.files;
const rawFiles = Array.from(files) const rawFiles = Array.from(files);
uploadFiles(rawFiles) uploadFiles(rawFiles);
} }
function getHeaderRow(sheet) { function getHeaderRow(sheet) {
const headers: string[] = [] const headers: string[] = [];
const range = XLSX.utils.decode_range(sheet['!ref']) const range = XLSX.utils.decode_range(sheet["!ref"]);
let C let C;
const R = range.s.r const R = range.s.r;
/* start in the first row */ /* start in the first row */
for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ for (C = range.s.c; C <= range.e.c; ++C) {
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] /* walk every column in the range */
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })];
/* find the cell in the first row */ /* find the cell in the first row */
let hdr = `UNKNOWN ${C}` // <-- replace with your desired default let hdr = `UNKNOWN ${C}`; // <-- replace with your desired default
if (cell && cell.t) if (cell && cell.t) hdr = XLSX.utils.format_cell(cell);
hdr = XLSX.utils.format_cell(cell) headers.push(hdr);
headers.push(hdr)
} }
return headers return headers;
} }
function isExcel(files) { function isExcel(files) {
return files.every((file) => { return files.every((file) => {
return /\.(xlsx|xls|csv)$/.test(file.name) return /\.(xlsx|xls|csv)$/.test(file.name);
}) });
} }
const show = ref(false) const show = ref(false);
function showModal() { function showModal() {
show.value = true show.value = true;
} }
function closeModal() { function closeModal() {
show.value = false show.value = false;
} }
async function handleSumbit(e: MouseEvent) { async function handleSumbit(e: MouseEvent) {
e.preventDefault() e.preventDefault();
commitData() commitData();
closeModal() closeModal();
} }
defineExpose({ defineExpose({
showModal, showModal,
}) });
function removeHandler(id: string) { function removeHandler(id: string) {
const index = excelDatas.findIndex(item => item.uuid === id) const index = excelDatas.findIndex((item) => item.uuid === id);
excelDatas.splice(index, 1) excelDatas.splice(index, 1);
} }
function afterLeave() { function afterLeave() {
excelDatas.length = 0 excelDatas.length = 0;
} }
</script> </script>
<template> <template>
<n-modal v-model:show="show" transform-origin="center" @after-leave="afterLeave"> <n-modal v-model:show="show" transform-origin="center" @after-leave="afterLeave">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true"> <n-card
:style="cardStyle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div class="wrapper"> <div class="wrapper">
<div class="wrapper-header"> <div class="wrapper-header">
<span class="wrapper-left">批量导入</span> <span class="wrapper-left">批量导入</span>
@ -203,17 +206,41 @@ function afterLeave() {
</div> </div>
<n-divider /> <n-divider />
<div class="wrapper-content"> <div class="wrapper-content">
<div class="wrapper-content-dragger" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover"> <div
<input ref="inputRef" class="excel-upload-input" type="file" accept=".xlsx, .xls,.csv" @change="handleClick"> class="wrapper-content-dragger"
<SvgIcon style="margin-top: 30px;" size="45" name="upload" @click="handleUpload" /> @drop="handleDrop"
<span style="margin-top: 20px;" class="wrapper-tip1">点击或拖拽审批文件到这里上传</span> @dragover="handleDragover"
<span style="margin-top: 15px;margin-bottom: 20px;" class="wrapper-tip2">支持上传格式.xls .xlsx .csv的文件</span> @dragenter="handleDragover"
>
<input
ref="inputRef"
class="excel-upload-input"
type="file"
accept=".xlsx, .xls,.csv"
@change="handleClick"
/>
<SvgIcon
style="margin-top: 32px; margin-bottom: 13px"
size="45"
name="upload"
@click="handleUpload"
/>
<span class="wrapper-tip1">点击或拖拽审批文件到这里上传</span>
<span style="margin-top: 3px; margin-bottom: 19px" class="wrapper-tip2"
>支持上传格式.xls .xlsx .csv的文件</span
>
</div> </div>
<div v-for="(item, index) in excelDatas" :key="index" class="wrapper-content-files"> <div
v-for="(item, index) in excelDatas"
:key="index"
class="wrapper-content-files"
>
<div>{{ item.fileName }}</div> <div>{{ item.fileName }}</div>
<div> <div>
<SvgIcon <SvgIcon
size="16px" style="display: block; margin-left: auto; cursor: pointer" name="clear" size="16px"
style="display: block; margin-left: auto; cursor: pointer"
name="clear"
@click="removeHandler(item.uuid)" @click="removeHandler(item.uuid)"
/> />
</div> </div>
@ -222,9 +249,7 @@ function afterLeave() {
</div> </div>
<template #footer> <template #footer>
<div class="footer"> <div class="footer">
<n-button type="info" @click="handleSumbit"> <n-button type="info" @click="handleSumbit"> </n-button>
确认
</n-button>
</div> </div>
</template> </template>
</n-card> </n-card>
@ -237,34 +262,41 @@ function afterLeave() {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 10px; padding: 6px 0 0 24px;
// padding: 10px;
} }
&-left { &-left {
font-weight: bold;
font-size: 16px; font-size: 16px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: bolder;
text-align: left;
color: #222222;
line-height: 24px;
} }
&-right { &-right {
&-close { &-close {
width: 18px; width: 12px;
height: 18px; height: 12px;
cursor: pointer; cursor: pointer;
margin-right: 25px;
color: #999999;
} }
&-icon { &-icon {
background: #000; background: #000;
display: inline-block; display: inline-block;
width: 18px; width: 12px;
height: 1px; height: 1px;
transform: rotate(45deg); transform: rotate(45deg);
-webkit-transform: rotate(45deg); -webkit-transform: rotate(45deg);
margin-bottom: 8px; margin-bottom: 8px;
&:after { &:after {
content: ''; content: "";
display: block; display: block;
width: 18px; width: 12px;
height: 1px; height: 1px;
background: #000; background: #000;
transform: rotate(-90deg); transform: rotate(-90deg);
@ -274,19 +306,18 @@ function afterLeave() {
} }
&-content { &-content {
margin-top: 20px; margin: 33px 24px 0 25px;
&-dragger { &-dragger {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
border: 1px dashed #1980FF; border: 1px dashed #1980ff;
width: 600px; // width: 600px;
margin: 0 auto;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
border-radius: 2px; border-radius: 2px;
text-align: center; text-align: center;
background: rgba(202, 210, 221, 0.1);
} }
&-files { &-files {
@ -297,7 +328,6 @@ function afterLeave() {
justify-content: space-between; justify-content: space-between;
} }
} }
} }
.excel-upload-input { .excel-upload-input {
@ -324,4 +354,19 @@ function afterLeave() {
margin-top: 0px; margin-top: 0px;
margin-bottom: 0px; margin-bottom: 0px;
} }
.wrapper-tip1 {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: lighter;
color: #666666;
line-height: 24px;
}
.wrapper-tip2 {
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: lighter;
text-align: left;
color: #999999;
line-height: 22px;
}
</style> </style>

@ -1,103 +1,101 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, h, reactive, ref, unref } from 'vue' import { computed, h, reactive, ref, unref } from "vue";
import { NDataTable, useDialog } from 'naive-ui' import { NDataTable, useDialog } from "naive-ui";
import type { DataTableColumns, DataTableRowKey } from 'naive-ui' import type { DataTableColumns, DataTableRowKey } from "naive-ui";
import Action from '../comp/Action.vue' import Action from "../comp/Action.vue";
import { RejectModal } from './index' import { RejectModal } from "./index";
import type { RowData } from '@/config/final' import type { RowData } from "@/config/final";
import { getFinalList } from '@/api/final' import { getFinalList } from "@/api/final";
import type { ApprovalParam } from '/#/api' import type { ApprovalParam } from "/#/api";
import { audit } from '@/api/task/task' import { audit } from "@/api/task/task";
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'commit', columns: any[]) (e: "commit", columns: any[]);
}>() }>();
const show = ref(false) const show = ref(false);
function showModal() { function showModal() {
show.value = true show.value = true;
} }
function closeModal() { function closeModal() {
show.value = false show.value = false;
} }
async function handleSumbit(e: MouseEvent) { async function handleSumbit(e: MouseEvent) {
e.preventDefault() e.preventDefault();
closeModal() closeModal();
} }
defineExpose({ defineExpose({
showModal, showModal,
}) });
const columns: DataTableColumns<RowData> = [ const columns: DataTableColumns<RowData> = [
{ {
type: 'selection', type: "selection",
fixed: 'left', fixed: "left",
width: 50, width: 50,
}, },
{ {
title: '任务Id', title: "任务Id",
key: 'id', key: "id",
fixed: 'left', fixed: "left",
width: 100, width: 100,
}, },
{ {
title: '任务名称', title: "任务名称",
key: 'fromtaskname', key: "fromtaskname",
fixed: 'left', fixed: "left",
width: 200, width: 200,
}, },
{ {
title: '审批节点', title: "审批节点",
key: 'approvalnode', key: "approvalnode",
width: 100, width: 100,
}, },
{ {
title: '审批状态', title: "审批状态",
key: 'states', key: "states",
width: 100, width: 100,
}, },
{ {
title: '图片相似度', title: "图片相似度",
key: 'similarity', key: "similarity",
width: 100, width: 100,
}, },
{ {
title: '提报时间', title: "提报时间",
key: 'fromuptime', key: "fromuptime",
width: 200, width: 200,
}, },
{ {
title: '更新时间', title: "更新时间",
key: 'updatetime', key: "updatetime",
width: 200, width: 200,
}, },
{ {
title: '操作', title: "操作",
key: 'actions', key: "actions",
width: 200, width: 200,
fixed: 'right', fixed: "right",
render(row) { render(row) {
return h( return h(Action, {
Action,
{
id: row.id, id: row.id,
status: row.states, status: row.states,
trigger: actionHandler, trigger: actionHandler,
}, });
)
}, },
}, },
] ];
const rejectModalRef = ref(null) const rejectModalRef = ref(null);
const columnsRef = ref(columns) const columnsRef = ref(columns);
const tableRef = ref<InstanceType<typeof NDataTable>>() const tableRef = ref<InstanceType<typeof NDataTable>>();
const rowKey = (row: RowData) => row.id const rowKey = (row: RowData) => row.id;
const loading = ref(true) const loading = ref(true);
const total = ref(0);
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
pageCount: 1, pageCount: 1,
@ -122,31 +120,37 @@ const pagination = reactive({
}, },
], ],
showQuickJumper: true, showQuickJumper: true,
}) prefix:()=>`${total.value} 条数据`
const tableData = ref<Array<RowData>>([]) });
const selectionIds = ref<DataTableRowKey[]>([]) const tableData = ref<Array<RowData>>([]);
const selectionIds = ref<DataTableRowKey[]>([]);
const deviceHeight = ref(600) const deviceHeight = ref(600);
const maxHeight = computed(() => { const maxHeight = computed(() => {
return tableData.value.length ? `${unref(deviceHeight)}px` : 'auto' return tableData.value.length ? `${unref(deviceHeight)}px` : "auto";
}) });
async function query(page: number, pageSize: number) { async function query(page: number, pageSize: number) {
const result = await getFinalList({ sortorder: 'asc', pageSize: 10, currPage: 1, sortname: '' }) const result = await getFinalList({
const { data, pageCount } = result sortorder: "asc",
tableData.value = data pageSize: 10,
pagination.page = page currPage: 1,
pagination.pageCount = pageCount sortname: "",
loading.value = false });
const { data, pageCount } = result;
total.value = data.totalCount;
tableData.value = data;
pagination.page = page;
pagination.pageCount = pageCount;
loading.value = false;
} }
async function handlePageChange(currentPage) { async function handlePageChange(currentPage) {
if (loading.value) if (loading.value) return;
return
const { pageSize } = pagination const { pageSize } = pagination;
await query(currentPage, pageSize) await query(currentPage, pageSize);
} }
async function handlePageSizeChange(currentPageSize) { async function handlePageSizeChange(currentPageSize) {
if (loading.value) return; if (loading.value) return;
@ -158,56 +162,55 @@ async function handlePageSizeChange(currentPageSize) {
} }
function handleCheck(rowKeys: DataTableRowKey[]) { function handleCheck(rowKeys: DataTableRowKey[]) {
selectionIds.value = rowKeys selectionIds.value = rowKeys;
} }
function actionHandler(action: any) { function actionHandler(action: any) {
const { key } = action const { key } = action;
switch (key) { switch (key) {
case 'view': case "view":
break;
break case "reset":
case 'reset': resetHandler();
resetHandler() break;
break case "approval":
case 'approval': approvalHandler();
approvalHandler() break;
break case "reject":
case 'reject': (rejectModalRef.value as any).showModal();
(rejectModalRef.value as any).showModal() break;
break
default: default:
break break;
} }
} }
const dialog = useDialog() const dialog = useDialog();
function resetHandler() { function resetHandler() {
dialog.info({ dialog.info({
title: '确认提示', title: "确认提示",
content: '确认重置当前选中的任务的审批吗?', content: "确认重置当前选中的任务的审批吗?",
positiveText: '确定', positiveText: "确定",
negativeText: '取消', negativeText: "取消",
onPositiveClick: async () => { onPositiveClick: async () => {
// TODO // TODO
// const result = await resetApproval() // const result = await resetApproval()
}, },
onNegativeClick: () => {}, onNegativeClick: () => {},
}) });
} }
function approvalHandler() { function approvalHandler() {
dialog.info({ dialog.info({
title: '确认提示', title: "确认提示",
content: '确认给该任务审批为【通过】吗?', content: "确认给该任务审批为【通过】吗?",
positiveText: '确定', positiveText: "确定",
negativeText: '取消', negativeText: "取消",
onPositiveClick: () => { onPositiveClick: () => {
// TODO // TODO
}, },
onNegativeClick: () => {}, onNegativeClick: () => {},
}) });
} }
function rejectHandler(idOrDesc: string, isOther: boolean) { function rejectHandler(idOrDesc: string, isOther: boolean) {
@ -218,22 +221,26 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
// approvd: false, // approvd: false,
// taskComment: '', // taskComment: '',
// } // }
// if (isOther) // if (isOther)
// param.taskComment = idOrDesc // param.taskComment = idOrDesc
// else // else
// param.taskComment = idOrDesc // param.taskComment = idOrDesc
// audit(param) // audit(param)
} }
query(pagination.page, pagination.pageSize) query(pagination.page, pagination.pageSize);
</script> </script>
<template> <template>
<div> <div>
<n-modal v-model:show="show" transform-origin="center"> <n-modal v-model:show="show" transform-origin="center">
<n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true"> <n-card
class="cardstyle"
:bordered="false"
size="huge"
role="dialog"
aria-modal="true"
>
<div class="wrapper"> <div class="wrapper">
<span class="wrapper-title">重复任务</span> <span class="wrapper-title">重复任务</span>
<div class="wrapper-bar"> <div class="wrapper-bar">
@ -243,8 +250,16 @@ query(pagination.page, pagination.pageSize)
</div> </div>
<div class="wrapper-content"> <div class="wrapper-content">
<NDataTable <NDataTable
ref="tableRef" remote :columns="columnsRef" :scroll-x="1250" :max-height="maxHeight" :data="tableData" ref="tableRef"
:loading="loading" :pagination="pagination" :row-key="rowKey" @update:page="handlePageChange" remote
:columns="columnsRef"
:scroll-x="1250"
:max-height="maxHeight"
:data="tableData"
:loading="loading"
:pagination="pagination"
:row-key="rowKey"
@update:page="handlePageChange"
@update-page-size="handlePageSizeChange" @update-page-size="handlePageSizeChange"
@update:checked-row-keys="handleCheck" @update:checked-row-keys="handleCheck"
/> />
@ -252,9 +267,7 @@ query(pagination.page, pagination.pageSize)
</div> </div>
<template #footer> <template #footer>
<div class="wrapper-footer"> <div class="wrapper-footer">
<n-button type="info" @click="handleSumbit"> <n-button type="info" @click="handleSumbit"> </n-button>
确认
</n-button>
<n-button secondary style="margin-left: 15px" @click="closeModal"> <n-button secondary style="margin-left: 15px" @click="closeModal">
取消 取消
</n-button> </n-button>
@ -284,7 +297,7 @@ query(pagination.page, pagination.pageSize)
&-content { &-content {
flex: auto; flex: auto;
background: #FFF; background: #fff;
margin-top: 20px; margin-top: 20px;
} }
@ -299,7 +312,7 @@ query(pagination.page, pagination.pageSize)
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
content: ''; content: "";
width: 5px; width: 5px;
border-radius: 2px; border-radius: 2px;
top: 0; top: 0;

@ -374,6 +374,7 @@ onUnmounted(() => {
const tableRef = ref<InstanceType<typeof NDataTable>>() const tableRef = ref<InstanceType<typeof NDataTable>>()
const rowKey = (row: RowData) => row.id const rowKey = (row: RowData) => row.id
const loading = ref(true) const loading = ref(true)
const total = ref(0);
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
pageCount: 1, pageCount: 1,
@ -398,6 +399,7 @@ const pagination = reactive({
}, },
], ],
showQuickJumper: true, showQuickJumper: true,
prefix:()=>`${total.value} 条数据`
}) })
const tableData = ref<Array<RowData>>([]) const tableData = ref<Array<RowData>>([])
const selectionIds = ref<DataTableRowKey[]>([]) const selectionIds = ref<DataTableRowKey[]>([])
@ -418,7 +420,7 @@ async function query(page: number, pageSize: number, filterId?: any) {
}) })
const { data, pageCount } = result const { data, pageCount } = result
tableData.value = data tableData.value = data
console.log(data, 'tableData') total.value = data.totalCount;
pagination.page = page pagination.page = page
pagination.pageCount = pageCount pagination.pageCount = pageCount
loading.value = false loading.value = false

@ -399,7 +399,7 @@ onMounted(() => {
background: #507AFD !important; background: #507AFD !important;
} }
.n-button--default-type{ .n-button--default-type{
background: #CAD2DD !important; background: #fff !important;
color: #333333; color: #333333;
} }
} }
@ -407,6 +407,7 @@ onMounted(() => {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
font-size: 14px;
&:before { &:before {
background-color: #1980FF; background-color: #1980FF;
@ -468,7 +469,8 @@ onMounted(() => {
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
::v-deep(.n-card > .n-card-header .n-card-header__main){ ::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important; font-weight: lighter !important;
font-size: 14px;
} }
::v-deep(.n-scrollbar){ ::v-deep(.n-scrollbar){
border-left: 1px solid #cad2dd !important; border-left: 1px solid #cad2dd !important;
@ -491,5 +493,7 @@ onMounted(() => {
height: 44px !important; height: 44px !important;
} }
} }
::v-deep(.n-button--info-type){
background: #507AFD !important;
}
</style> </style>

@ -75,7 +75,7 @@ const columns: DataTableColumns<RowData> = [
width: 180 width: 180
}, },
]; ];
const total = ref(0);
const loading = ref(true); const loading = ref(true);
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
@ -102,6 +102,7 @@ const pagination = reactive({
}, },
], ],
showQuickJumper: true, showQuickJumper: true,
prefix:()=>`${total.value} 条数据`
}); });
const tableData = ref<Array<RowData>>([]); const tableData = ref<Array<RowData>>([]);
const keyword = ref(""); const keyword = ref("");
@ -112,8 +113,10 @@ async function query(page: number, pageSize: number) {
}; };
const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 0); const result = await getConditionList({ pageNo: page, pageSize }, searchParam, 0);
const { data, pageCount } = result; const { data, pageCount } = result;
total.value = data.total;
tableData.value = data; tableData.value = data;
pagination.page = page; pagination.page = page;
total.value = data.total;
pagination.pageCount = pageCount; pagination.pageCount = pageCount;
loading.value = false; loading.value = false;
} }

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { createPackage, getCheckDuplicateStatus, getLastCheckNo, getPictureList, oneClickCheckTaskPackage, queryPageListByCheckNo } from '@/api/home/main' import { createPackage, getCheckDuplicateStatus, getLastCheckNo, getPictureList, oneClickCheckTaskPackage, queryPageListByCheckNo, removeCheckDuplicate } from '@/api/home/main'
import avatar from '@/assets/images/avatar.jpg' import avatar from '@/assets/images/avatar.jpg'
import { timeOptions, viewOptions } from '@/config/home' import { timeOptions, viewOptions } from '@/config/home'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
@ -15,9 +15,12 @@ import { cloneDeep, debounce } from 'lodash-es'
import Masonry from 'masonry-layout' import Masonry from 'masonry-layout'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue' import { computed, nextTick, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import CheckingTaskModal from './modal/CheckingTaskModal.vue'
import FinishPackageModal from './modal/FinishPackageModal.vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue' import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import LoginSuccessModal from './modal/LoginSuccessModal.vue' import LoginSuccessModal from './modal/LoginSuccessModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue' import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import QueryRepeatedTasksModal from './modal/QueryRepeatedTasksModal.vue'
import type { PictureSortParam } from "/#/api" import type { PictureSortParam } from "/#/api"
const deviceHeight = ref(600) const deviceHeight = ref(600)
@ -33,7 +36,10 @@ const pagination = reactive({
const configStore = useConfig() const configStore = useConfig()
const packageModalRef = ref(null) const packageModalRef = ref(null)
const generateModalRef = ref(null) const generateModalRef = ref(null)
const queryRepeatedTasksModalRef = ref(null)
const LoginSuccessModalRef = ref(null) const LoginSuccessModalRef = ref(null)
const checkingTaskModalRef = ref(null)
const finishPackageModal = ref(null)
const loading = ref(false) const loading = ref(false)
const message = useMessage() const message = useMessage()
const totalCount = ref(0) const totalCount = ref(0)
@ -196,6 +202,8 @@ const gridHeight = computed(() => {
async function oneCheck() { async function oneCheck() {
const asideVal = cloneDeep(configStore.getAsideValue) const asideVal = cloneDeep(configStore.getAsideValue)
asideVal.izyear = dayjs(asideVal.izyear[0]).format("YYYY/MM/DD") + '-' + dayjs(asideVal.izyear[1]).format("YYYY/MM/DD") asideVal.izyear = dayjs(asideVal.izyear[0]).format("YYYY/MM/DD") + '-' + dayjs(asideVal.izyear[1]).format("YYYY/MM/DD")
const tasksLoadingModal = queryRepeatedTasksModalRef.value as any
const checkingTaskModal = checkingTaskModalRef.value as any
delete asideVal.izsimilarity delete asideVal.izsimilarity
if (checkDuplicateNo.value) { if (checkDuplicateNo.value) {
getCheckDuplicateStatus(checkDuplicateNo.value).then((res) => { getCheckDuplicateStatus(checkDuplicateNo.value).then((res) => {
@ -208,19 +216,23 @@ async function oneCheck() {
} }
if (checkTaskStatus.value === 2 && isRefresh) { if (checkTaskStatus.value === 2 && isRefresh) {
checkingTaskModal.closeModal()
tasksLoadingModal.closeModal()
isRefresh.value = false isRefresh.value = false
message.success('任务执行完毕,正在刷新数据...'); message.success('任务执行完毕,正在刷新数据...');
reset() reset()
loadMore() loadMore()
} else if (checkTaskStatus.value === 1) { } else if (checkTaskStatus.value === 1) {
message.success("请等待,查重任务正在创建中..."); checkingTaskModal.showModal()
tasksLoadingModal.showModal()
return return
} }
} }
}) })
return return
} }
message.success("请等待,查重任务正在创建中..."); checkingTaskModal.showModal()
tasksLoadingModal.showModal()
oneClickCheckTaskPackage(asideVal).then((res) => { oneClickCheckTaskPackage(asideVal).then((res) => {
if (res.code === "OK") { if (res.code === "OK") {
checkDuplicateNo.value = res.data.checkDuplicateNo checkDuplicateNo.value = res.data.checkDuplicateNo
@ -241,11 +253,13 @@ async function commitHandler(settingParam) {
checkDuplicateNo: checkDuplicateNo.value checkDuplicateNo: checkDuplicateNo.value
} }
const modal = generateModalRef.value as any const modal = generateModalRef.value as any
const finishModal = finishPackageModal.value as any
modal.showModal() modal.showModal()
createPackage(params).then((res) => { createPackage(params).then((res) => {
if (res.code === "OK") { if (res.code === "OK") {
message.success(res.data); message.success(res.data);
modal.closeModal() modal.closeModal()
finishModal.showModal()
} }
}) })
const asideVal = configStore.getAsideValue const asideVal = configStore.getAsideValue
@ -367,6 +381,19 @@ function previewHandler(index: number, event: MouseEvent) {
if (imageRef.value?.[index] && (imageRef.value[index] as any).src) if (imageRef.value?.[index] && (imageRef.value[index] as any).src)
(imageRef.value?.[index] as any).mergedOnClick(); (imageRef.value?.[index] as any).mergedOnClick();
} }
function refresh(val) {
oneCheck()
}
function cancel(val) {
if (checkTaskStatus.value === 1) {
removeCheckDuplicate(checkDuplicateNo.value).then((res) => {
if (res.code === "OK") {
message.success("查重任务取消成功")
}
})
}
}
</script> </script>
<template> <template>
@ -378,9 +405,8 @@ function previewHandler(index: number, event: MouseEvent) {
</div> </div>
<SvgIcon v-show="checkTaskStatus !== 2" style="cursor: pointer;" size="105" name="yijianchachong" <SvgIcon v-show="checkTaskStatus !== 2" style="cursor: pointer;" size="105" name="yijianchachong"
@click="oneCheck" /> @click="oneCheck" />
<div v-show="checkTaskStatus === 2" style="cursor: pointer;" size="105" name="magnifying" @click="oneCheck"> <SvgIcon v-show="checkTaskStatus === 2" style="cursor: pointer;" size="105" name="shengchengrenwubao"
生成任务包 @click="oneCheck" />
</div>
</div> </div>
<div class="wrapper-content"> <div class="wrapper-content">
<div style="display: flex;justify-content: space-between;"> <div style="display: flex;justify-content: space-between;">
@ -458,7 +484,10 @@ function previewHandler(index: number, event: MouseEvent) {
</div> </div>
<PackageSettingsModal ref="packageModalRef" @commit="commitHandler" /> <PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
<GeneratePackageModal ref="generateModalRef" /> <GeneratePackageModal ref="generateModalRef" />
<QueryRepeatedTasksModal ref="queryRepeatedTasksModalRef" />
<LoginSuccessModal ref="LoginSuccessModalRef" /> <LoginSuccessModal ref="LoginSuccessModalRef" />
<FinishPackageModal ref="finishPackageModal" />
<CheckingTaskModal ref="checkingTaskModalRef" @refresh="refresh" @cancel="cancel" />
</div> </div>
</template> </template>

@ -0,0 +1,92 @@
<script lang="ts" setup>
import { defineOptions, ref } from 'vue';
import { useRouter } from 'vue-router';
defineOptions({ name: 'ShortcutModal' })
const emit = defineEmits<{
(e: 'refresh', value: any),
(e: 'cancel', value: any)
}>()
const show = ref(false)
const isFold = ref(false)
const router = useRouter()
const cardStyle = {
'width': '29vw',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
}
function toggle() {
isFold.value = !isFold.value
}
function showModal() {
show.value = true
}
function closeModal() {
show.value = false
}
function refresh() {
emit('refresh', true)
}
function cancel() {
closeModal()
emit('cancel', true)
}
defineExpose({
showModal,
closeModal
})
</script>
<template>
<div>
<n-modal v-model:show="show" transform-origin="center" style="position: fixed;right: 0;bottom: 0;">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true" style="padding: 8px 8px 0 8px;">
<div class="wrapper">
<div class="title">查重进度</div>
<div class="icon-list">
<svg-icon size="20" name="refresh" @click="refresh" style="margin-right: 16px;cursor: pointer;" />
<svg-icon size="20" name="fold" style="margin-right: 16px;cursor: pointer;" @click="toggle"/>
<svg-icon size="20" name="close-none-border" @click="cancel" style="margin-right: 16px;cursor: pointer;"/>
</div>
</div>
<div v-show="!isFold" style="display: flex;background-color: #F9F9F9;height: 54px;margin-top: 24px;margin-bottom: 6px;">
<div><svg-icon size="40" name="robot2" /></div>
<div class="msg">
<div>正在查重中</div>
</div>
</div>
</n-card>
</n-modal>
</div>
</template>
<style lang="less" scoped>
.wrapper{
display: flex;
justify-content: space-between;
border-bottom: 1px solid rgba(0, 0, 0, 0.09);
margin: 0 -18px;
}
.icon-list{
}
.title {
padding-left: 24px;
padding-bottom: 10px;
color: #333333;
font-size: 16px
}
.msg {
text-align: center;
margin-left: 20px;
font-size: 14px;
font-size: 14px;
line-height: 54px;
}
</style>

@ -0,0 +1,81 @@
<script lang="ts" setup>
import { defineOptions, ref } from 'vue';
import { useRouter } from 'vue-router';
defineOptions({ name: 'ShortcutModal' })
const show = ref(false)
const router = useRouter()
const cardStyle = {
'width': '29vw',
'--n-padding-bottom': '10px',
'--n-padding-left': '10px',
}
function showModal() {
show.value = true
}
function closeModal(path) {
show.value = false
router.push(path)
}
defineExpose({
showModal,
})
</script>
<template>
<div>
<n-modal v-model:show="show" transform-origin="center" style="padding: 8px;">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div style="display: flex;">
<div><svg-icon size="80" name="robot2" /></div>
<div style="height: 130px;text-align: center;margin-left: 20px;">
<div class="msg-title">生成任务提示</div>
<div class="msg-text">AI已根据您的配置要求生成任务包</div>
</div>
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="closeModal('/worksheet')">
进入AI工单
</n-button>
<n-button style="margin-left:10px;color: #666666;" @click="closeModal('/task')">
进入任务审批
</n-button>
</div>
</template>
</n-card>
</n-modal>
</div>
</template>
<style lang="less" scoped>
.wrapper-footer {
margin-top: -20px;
text-align: right;
}
.msg-title {
font-size: 16px;
font-family: PingFang SC, PingFang SC-Medium;
font-weight: Medium;
text-align: left;
color: #333333;
line-height: 24px;
margin: 12px 0;
}
.msg-text {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #666666;
line-height: 22px;
}
</style>

@ -0,0 +1,51 @@
<script lang="ts" setup>
import { ref } from 'vue';
const show = ref(false)
const stys = {
'width': '424px',
'height': '192px',
'--n-padding-bottom': '0px',
'--n-padding-left': '0px',
'background': 'linear-gradient(132deg, rgba(255, 255, 255, 0.32) 21%, rgba(152, 172, 255, 0.14) 100%)',
'border-radius': '4px',
'box-shadow': '0px 12px 48px 16px rgba(0, 0, 0, 0.03)',
'backdrop-filter': ' blur(10px)',
}
function showModal() {
show.value = true
}
function closeModal() {
show.value = false
}
defineExpose({
showModal,
closeModal,
})
</script>
<template>
<n-modal v-model:show="show" :mask-closable="false" transform-origin="center">
<n-card :style="stys" :bordered="false" role="dialog" aria-modal="true">
<svg-icon size="15" name="close" @click="closeModal" style="position:absolute; right:6px;top:6px;cursor: pointer;"/>
<div class="wrapper">
<svg-icon size="90" name="robot2" />
<span style="margin-top: 24px;">正在查重中</span>
</div>
</n-card>
</n-modal>
</template>
<style lang="less" scoped>
.wrapper {
display: flex;
height: 100%;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>

@ -266,7 +266,7 @@ function forget() {
</template> </template>
</n-input> </n-input>
</n-form-item> </n-form-item>
<n-form-item class="form-item"> <!-- <n-form-item class="form-item"> -->
<n-button <n-button
:class="{ 'btn-disabled': computedForm() }" :class="{ 'btn-disabled': computedForm() }"
class="btn" class="btn"
@ -278,7 +278,7 @@ function forget() {
> >
下一步 下一步
</n-button> </n-button>
</n-form-item> <!-- </n-form-item> -->
</n-form> </n-form>
</div> </div>
<div v-if="tab === 1" class="form-1"> <div v-if="tab === 1" class="form-1">
@ -347,8 +347,7 @@ function forget() {
box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.04); box-shadow: 0px 6px 12px 0px rgba(0, 0, 0, 0.04);
backdrop-filter: blur(12px); backdrop-filter: blur(12px);
position: relative; position: relative;
padding: 3rem 1.6875rem 2.625rem; padding: 3rem 1.6875rem 2rem;
.img-close { .img-close {
position: absolute; position: absolute;
right: 0; right: 0;
@ -357,7 +356,6 @@ function forget() {
height: 1.75rem; height: 1.75rem;
cursor: pointer; cursor: pointer;
} }
.tab { .tab {
font-size: 1.5rem; font-size: 1.5rem;
font-family: PingFang SC, PingFang SC-Medium; font-family: PingFang SC, PingFang SC-Medium;
@ -389,8 +387,8 @@ function forget() {
height: 2.75rem; height: 2.75rem;
background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%); background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%);
border-radius: 3px; border-radius: 3px;
margin-top: .625rem; margin-top: 1rem;
margin-bottom: .875rem; // margin-bottom: .875rem;
font-size: 1rem; font-size: 1rem;
&-disabled { &-disabled {
opacity: 0.5; opacity: 0.5;
@ -436,4 +434,27 @@ function forget() {
line-height: 1.3125rem; line-height: 1.3125rem;
cursor: pointer; cursor: pointer;
} }
//
::v-deep(.n-base-clear > .n-base-clear__clear > .n-base-icon > svg) {
color: #c9c9c9;
}
::v-deep(.n-input .n-input__input-el) {
height: 2.75rem !important;
font-size: 1rem !important;
}
::v-deep(.n-input .n-input-wrapper) {
height: 2.75rem !important;
}
.save-btn {
font-size: 0.9375rem;
}
::v-deep(.n-form-item .n-form-item-feedback-wrapper) {
height: 1rem;
padding: 0 !important;
margin: 0 !important;
line-height: normal !important;
min-height: 0 !important;
// margin-bottom: .5rem;
}
</style> </style>

@ -8,6 +8,7 @@ import { PageEnum } from "@/enums/pageEnum";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { ResultEnum } from "@/enums/httpEnum"; import { ResultEnum } from "@/enums/httpEnum";
import { getCode, smsLogin } from "@/api/login/login"; import { getCode, smsLogin } from "@/api/login/login";
import SvgIcon from "@/components/Icon/SvgIcon.vue";
const emit = defineEmits(["close", "forget"]); const emit = defineEmits(["close", "forget"]);
interface FormState { interface FormState {
@ -54,50 +55,46 @@ const tab = ref(0);
const countTime = ref("获取验证码"); const countTime = ref("获取验证码");
const rules = { const rules = {
enterprisecode: [ enterprisecode: [
{ required: true, message: "请输入企业编码", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
validator(_rule, value) { validator(_rule, value) {
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入企业编码");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
}, },
], ],
agentcode: [ agentcode: [
{ required: true, message: "请输入验证码", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
validator(_rule, value) { validator(_rule, value) {
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入验证码");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
}, },
], ],
phone: [ phone: [
{ required: true, message: "请输入手机号", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
validator(_rule, value) { validator(_rule, value) {
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入手机号");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
},], },
],
phonecode: [ phonecode: [
{ required: true, message: "请输入验证码", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
@ -105,45 +102,39 @@ const rules = {
if (value.length < 4 && value.length > 0) { if (value.length < 4 && value.length > 0) {
return new Error("请正确填写4位手机短信验证码"); return new Error("请正确填写4位手机短信验证码");
} }
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入验证码");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
}, },
], ],
username: [ username: [
{ required: true, message: "请输入账号", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
validator(_rule, value) { validator(_rule, value) {
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入账号");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
}, },
], ],
password: [ password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ {
trigger: ["blur", "input", "change"], trigger: ["blur", "input", "change"],
level: "error", level: "error",
validator(_rule, value) { validator(_rule, value) {
if (loginSuccess.value) { if (loginSuccess.value || !value) {
return true; return true;
} }
if (!value) {
return new Error("请输入密码");
}
return new Error(loginRejectMessge.value); return new Error(loginRejectMessge.value);
}, },
},], },
],
captcha: [{ required: true, message: "请输入验证码", trigger: "blur" }], captcha: [{ required: true, message: "请输入验证码", trigger: "blur" }],
}; };
@ -506,7 +497,7 @@ function forget() {
<style lang="less" scoped> <style lang="less" scoped>
.form-login { .form-login {
width: 26.25rem; width: 26.25rem;
height: 28.0625rem; height: 26.0625rem;
box-sizing: border-box; box-sizing: border-box;
background: linear-gradient( background: linear-gradient(
136deg, 136deg,
@ -572,7 +563,7 @@ function forget() {
margin-top: 1.8125rem; margin-top: 1.8125rem;
.form-item { .form-item {
height: 4.75rem; height: 3.75rem;
} }
.item-input { .item-input {
@ -589,7 +580,7 @@ function forget() {
height: 2.75rem; height: 2.75rem;
background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%); background: linear-gradient(234deg, #96aaff 0%, #1c43ff 100%);
border-radius: 3px; border-radius: 3px;
// margin-top: 1rem; margin-top: 1rem;
// margin-bottom: -0.875rem; // margin-bottom: -0.875rem;
&-disabled { &-disabled {

@ -287,7 +287,8 @@ function close() {
.item-footer { .item-footer {
width: 60.625rem; width: 60.625rem;
height: 7.4375rem; height: 7.4375rem;
position: fixed; position: absolute;
// position: fixed;
left: 44.5rem; left: 44.5rem;
bottom: 0; bottom: 0;
margin-left: -30.3125rem; margin-left: -30.3125rem;

@ -43,7 +43,7 @@ const tab = ref(1)
async function getList() { async function getList() {
const res = await getMessageList({ const res = await getMessageList({
pageNo: state.pageNo, pageNo: state.pageNo,
pageSize: '10', pageSize: '7',
msgCategory: tab.value, msgCategory: tab.value,
}) })
if (res.code === 'OK') { if (res.code === 'OK') {

@ -221,7 +221,7 @@ function removeHandler(id: string) {
}); });
if (index !== -1) onList.value.splice(index, 1); if (index !== -1) onList.value.splice(index, 1);
index = offList.value.findIndex(v=>v.id==id); index = offList.value.findIndex((v) => v.id == id);
offList.value[index].checked = false; offList.value[index].checked = false;
} }
@ -249,8 +249,8 @@ onMounted(async () => {
fix: v.isrequired == 2, fix: v.isrequired == 2,
checked: checked:
v.isrequired == 2 || v.isrequired == 2 ||
Boolean(userFieldFixed?.find(v2=>v2==v.name)) || Boolean(userFieldFixed?.find((v2) => v2 == v.name)) ||
Boolean(userFieldUnFixed?.find(v2=>v2==v.name)) Boolean(userFieldUnFixed?.find((v2) => v2 == v.name)),
}; };
if (item.fix) { if (item.fix) {
fixList.value.push(item); fixList.value.push(item);
@ -274,8 +274,8 @@ onMounted(async () => {
} }
} }
}); });
console.log(offList.value,'offList.value'); console.log(offList.value, "offList.value");
console.log(useList, 'useList'); console.log(useList, "useList");
}); });
</script> </script>
@ -377,6 +377,7 @@ onMounted(async () => {
:class="{ fix: item.fix }" :class="{ fix: item.fix }"
class="cursor-move draggable-item" class="cursor-move draggable-item"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" v-if="!item.fix"
@ -408,14 +409,14 @@ onMounted(async () => {
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 32px;
&-title { &-title {
font-weight: bold; font-weight: bold;
font-size: 16px; font-size: 16px;
} }
&-bar { &-bar {
background-color: #e8e8e8;
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
@ -428,6 +429,7 @@ onMounted(async () => {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
color: #333333;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -476,10 +478,11 @@ onMounted(async () => {
} }
.draggable-item { .draggable-item {
padding: 10px 16px; padding: 11px 16px;
color: #333; color: #333;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #E8E8E8;
} }
.disable-check { .disable-check {
@ -487,9 +490,7 @@ onMounted(async () => {
} }
} }
::v-deep( ::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {
.n-card.n-card--content-segmented > .n-card__content:not(:first-child)
) {
border: 0px; border: 0px;
} }
@ -503,4 +504,5 @@ onMounted(async () => {
::v-deep(.n-scrollbar) { ::v-deep(.n-scrollbar) {
border-top: none !important; border-top: none !important;
} }
</style> </style>

@ -215,6 +215,8 @@ function onCheckChange(checked: any, item: any) {
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 32px;
&-title { &-title {
font-weight: bold; font-weight: bold;
@ -222,7 +224,6 @@ function onCheckChange(checked: any, item: any) {
} }
&-bar { &-bar {
background-color: #e8e8e8;
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
@ -235,6 +236,7 @@ function onCheckChange(checked: any, item: any) {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
color: #333333;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -282,10 +284,11 @@ function onCheckChange(checked: any, item: any) {
} }
.draggable-item { .draggable-item {
padding: 10px 16px; padding: 11px 16px;
color: #333; color: #333;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #E8E8E8;
} }
.disable-check { .disable-check {
@ -303,4 +306,5 @@ function onCheckChange(checked: any, item: any) {
--n-padding-top: 0px; --n-padding-top: 0px;
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
</style> </style>

@ -1,4 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getAllfieldList, getfieldList } from "@/api/home/filter";
import { useWindowSizeFn } from "@/hooks/event/useWindowSizeFn";
import { useUser } from "@/store/modules/user";
import { useWorkOrder } from "@/store/modules/workOrder";
import { getViewportOffset } from "@/utils/domUtils";
import { debounce } from "lodash-es"; import { debounce } from "lodash-es";
import { import {
computed, computed,
@ -7,15 +12,10 @@ import {
onMounted, onMounted,
ref, ref,
unref, unref,
watch, watch
} from "vue"; } from "vue";
import CustomFieldModalVue from "../modal/CustomFieldModal.vue"; import CustomFieldModalVue from "../modal/CustomFieldModal.vue";
import WorkSheetList from "./WorkSheetList.vue"; import WorkSheetList from "./WorkSheetList.vue";
import { getViewportOffset } from "@/utils/domUtils";
import { useWorkOrder } from "@/store/modules/workOrder";
import { useWindowSizeFn } from "@/hooks/event/useWindowSizeFn";
import { useUser } from "@/store/modules/user";
import { getAllfieldList, getfieldList, savefield } from "@/api/home/filter";
defineOptions({ name: "AsideContent" }); defineOptions({ name: "AsideContent" });
const collapse = ref(false); const collapse = ref(false);
@ -25,7 +25,7 @@ const packageListRef = ref<HTMLDivElement | null>(null);
// //
const showFieldList = ref<any[]>([]); const showFieldList = ref<any[]>([]);
const reviewType = 1; const reviewType = 1;
const dicts = ref<any>([]);
function collapseHandler() { function collapseHandler() {
collapse.value = !collapse.value; collapse.value = !collapse.value;
} }
@ -68,6 +68,7 @@ async function getshowFieldList() {
let res; let res;
res = await getAllfieldList(reviewType); // res = await getAllfieldList(reviewType); //
const allList = res.data; const allList = res.data;
dicts.value = res.data;
res = await getfieldList(reviewType, userInfo.id); // res = await getfieldList(reviewType, userInfo.id); //
const useList = res.data; const useList = res.data;
/** /**
@ -158,7 +159,7 @@ const inputHandler = debounce((word) => {
<div v-show="!showSearch" class="warpper"> <div v-show="!showSearch" class="warpper">
<div class="left"> <div class="left">
<svg-icon name="all-worksheet" size="32" /> <svg-icon name="all-worksheet" size="32" />
<span style="margin-left: 8px">所有工单</span> <span style="margin-left: 8px">所有任务包</span>
</div> </div>
<div class="right"> <div class="right">
<SvgIcon <SvgIcon
@ -197,6 +198,7 @@ const inputHandler = debounce((word) => {
ref="packageListRef" ref="packageListRef"
class="work-sheet-list" class="work-sheet-list"
:showFieldList="showFieldList" :showFieldList="showFieldList"
:dicts="dicts"
/> />
<CustomFieldModalVue <CustomFieldModalVue
ref="filterModalRef" ref="filterModalRef"
@ -266,5 +268,5 @@ const inputHandler = debounce((word) => {
z-index: 10; z-index: 10;
} }
} }
</style> </style>
../types

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed, onMounted } from "vue";
import type { PackageListItem } from "/#/workorder"; import type { PackageListItem } from "/#/workorder";
defineOptions({ name: "ListItem" }); defineOptions({ name: "ListItem" });
@ -17,38 +17,52 @@ const props = defineProps({
type: Array, type: Array,
default: () => [], default: () => [],
}, },
dicts: {
type: Array,
default: () => [],
},
}); });
console.log(props.dicts, "dicts");
console.log(props.listItem, "listItem");
const svgName = computed(() => { const svgName = computed(() => {
return props.selected ? "taskpack-select" : "taskpack"; return props.selected ? "taskpack-select" : "taskpack";
}); });
function getValueByLabel(label) {
const result = props.dicts.filter(item => item.name === label)
if (result.length === 0) {
return ""
} else {
return props.dicts.filter(item => item.name === label)[0].fieldDesc
}
}
onMounted(async () => {
})
</script> </script>
<template> <template>
<div class="list-item" :class="{ 'list-item-selected': selected }"> <div class="list-item" :class="{ 'list-item-selected': selected }">
<div v-for="(item, index) in showFieldList" :key="index"> <div>
<div class="list-item-header" v-if="item.id == 'packagename'"> <div class="list-item-header">
<div style="display: flex"> <div style="display: flex">
<SvgIcon :name="svgName" size="28" /> <SvgIcon :name="svgName" size="28" />
<span <span class="list-item-header-name" :class="{ 'list-item-header-selected': selected }">
class="list-item-header-name" {{ listItem.name }}
:class="{ 'list-item-header-selected': selected }"
>
{{ listItem.packagename }}
</span> </span>
<span class="list-item-header-selected">({{ listItem.pictureno }})</span> <span class="list-item-header-selected">({{ listItem.pictureCount }})</span>
</div> </div>
<!-- <SvgIcon v-show="selected" size="14" name="more-ver" /> --> <!-- <SvgIcon v-show="selected" size="14" name="more-ver" /> -->
</div> </div>
<ul class="list-item-detail" v-else> <ul class="list-item-detail">
<li> <li v-for="(key, index) in Object.keys(listItem.search)" :key="index" v-if="listItem.search">
<div v-if="getValueByLabel(key)">
{{ {{
item.name getValueByLabel(key)
}}{{ }}{{
listItem[item.id] listItem.search[key]
}} }}
</div>
</li> </li>
<!-- <li>筛选时间{{ listItem.createTime }}</li>
<li>执行人{{ listItem.createBy }}</li> -->
</ul> </ul>
</div> </div>
<!-- <div class="list-item-header"> <!-- <div class="list-item-header">

@ -1,18 +1,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import NotPassed from '@/components/NotPassed.vue'
import { useWorkOrder } from '@/store/modules/workOrder'
import { isEmpty } from '@/utils'
import { useInfiniteScroll } from '@vueuse/core' import { useInfiniteScroll } from '@vueuse/core'
import { reactive, ref, unref, watch } from 'vue' import { reactive, ref, unref, watch } from 'vue'
import ApprovalModal from '../modal/ApprovalModal.vue' import ApprovalModal from '../modal/ApprovalModal.vue'
import ListItem from './ListItem.vue' import ListItem from './ListItem.vue'
import NotPassed from '@/components/NotPassed.vue'
import type { PackageListItem } from '/#/workorder' import type { PackageListItem } from '/#/workorder'
import { isEmpty } from '@/utils'
import { useWorkOrder } from '@/store/modules/workOrder'
defineProps({ defineProps({
showFieldList: { showFieldList: {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
dicts: {
type: Array,
default: () => [],
},
}) })
const workStore = useWorkOrder() const workStore = useWorkOrder()
const data = ref<PackageListItem[]>([]) const data = ref<PackageListItem[]>([])
@ -37,7 +41,7 @@ function showModal(modalRef: any, id) {
function selectHandler(id: string, index: number) { function selectHandler(id: string, index: number) {
workStore.setActive(index) workStore.setActive(index)
showModal(approvalModalRef, id) // showModal(approvalModalRef, id)
} }
useInfiniteScroll( useInfiniteScroll(
@ -58,6 +62,10 @@ async function loadMore() {
isLoading.value = true isLoading.value = true
try { try {
const more = await fetchList() const more = await fetchList()
more.forEach(ele=>{
ele.search = JSON.parse(ele.search)
ele.search.createTime = ele.search.submit_date_timestamp
})
data.value.push(...more) data.value.push(...more)
} }
finally { finally {
@ -131,9 +139,10 @@ defineExpose({
<ListItem <ListItem
v-for="(item, index) in data" v-for="(item, index) in data"
:key="item.id" :key="item.id"
:selected="activeId === item.id" :selected="activeId === item.checkDuplicateId"
:list-item="item" :list-item="item"
:show-field-list="showFieldList" :show-field-list="showFieldList"
:dicts="dicts"
@click="selectHandler(item.id, index)" @click="selectHandler(item.id, index)"
/> />
</div> </div>

@ -1,23 +1,22 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onUnmounted, onUpdated, reactive, ref, unref, watch } from "vue";
import { useDialog, useMessage } from "naive-ui";
import { clone, debounce, pickBy } from "lodash-es";
import { useInfiniteScroll } from "@vueuse/core";
import imagesloaded from "imagesloaded";
import ConfrimModal from "../modal/ConfrimModal.vue";
import type { PictureSortParam, SetTFParam } from "/#/api";
import { useWorkOrder } from "@/store/modules/workOrder";
import { formatToDateHMS } from "@/utils/dateUtil";
import { import {
clearTF, clearTF, getTaskDetailInfo,
getPackageTaskList,
getTaskDetailInfo,
getTaskDetailPictureList, getTaskDetailPictureList,
setTF, setTF
} from "@/api/work/work"; } from "@/api/work/work";
import { fieldMap } from "@/config/workorder"; import { fieldMap } from "@/config/workorder";
import { hideDownload } from "@/utils/image"; import { useWorkOrder } from "@/store/modules/workOrder";
import { isEmpty } from "@/utils"; import { isEmpty } from "@/utils";
import { formatToDateHMS } from "@/utils/dateUtil";
import { hideDownload } from "@/utils/image";
import { useInfiniteScroll } from "@vueuse/core";
import { format } from 'date-fns';
import imagesloaded from "imagesloaded";
import { clone, debounce, pickBy } from "lodash-es";
import { useDialog, useMessage } from "naive-ui";
import { computed, onUnmounted, onUpdated, reactive, ref, unref, watch } from "vue";
import ConfrimModal from "../modal/ConfrimModal.vue";
import type { SetTFParam, SimilarityPictureSortParam } from "/#/api";
const batch = ref(false); const batch = ref(false);
const selectItems = ref<any[]>([]); const selectItems = ref<any[]>([]);
@ -54,9 +53,9 @@ const taskpagination = reactive({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
}); });
const sortBy: PictureSortParam = { const sortBy: SimilarityPictureSortParam = {
orderbyname: "asc", orderType: "asc",
orderbyvalue: "pictureResult", orderName: "similarityScore",
}; };
const workStore = useWorkOrder(); const workStore = useWorkOrder();
const selectTask = ref<any>(null); const selectTask = ref<any>(null);
@ -223,20 +222,20 @@ async function loadMore() {
} }
async function featchList() { async function featchList() {
loading.value = true; loading.value = true;
try { try {
taskpagination.pageNo += 1; taskpagination.pageNo += 1;
const taskId = selectTask.value.id;
const { data, total, pageCount } = await getTaskDetailPictureList( const { data, total, pageCount } = await getTaskDetailPictureList(
workStore.activeId, { ...taskpagination, ...sortBy ,checkDuplicateId: workStore.activeId}
taskId,
{ ...taskpagination, ...sortBy }
); );
totalCount.value = total; totalCount.value = total;
canloadMore = pageCount >= taskpagination.pageNo && pageCount > 0; canloadMore = pageCount >= taskpagination.pageNo && pageCount > 0;
return data; return data;
} catch (error) { } catch (error) {
debugger
canloadMore = false; canloadMore = false;
return []; return [];
} }
@ -272,23 +271,33 @@ watch(
totalCount.value = 0; totalCount.value = 0;
return; return;
} }
queryDetail(packageid)
const res = await getPackageTaskList(newValue, packagepagination); // const res = await getPackageTaskList(newValue, packagepagination);
const { data } = res; // const { data } = res;
taskList.value = data; // taskList.value = data;
if (taskList.value.length > 0) handleSelect(taskList.value[0]); // if (taskList.value.length > 0) handleSelect(taskList.value[0]); //
} }
); );
const packageName = computed(() => { const packageName = computed(() => {
const index = workStore.getCurrentIndex; const index = workStore.getCurrentIndex;
return workStore.getOrderList[index]?.packagename || ""; return workStore.getOrderList[index]?.name || "";
}); });
async function queryDetail(checkDuplicateId: any) {
taskDetailInfo.value = await getTaskDetailInfo(checkDuplicateId);
const packageid = workStore.getActiveId;
if (isEmpty(packageid)) {
listData.value.length = 0;
totalCount.value = 0;
return;
}
refreshHandler();
}
async function handleSelect(item: any) { async function handleSelect(item: any) {
selectTask.value = item; taskDetailInfo.value = await getTaskDetailInfo( workStore.activeId);
const taskId = item.id;
taskDetailInfo.value = await getTaskDetailInfo(taskId, workStore.activeId);
const packageid = workStore.getActiveId; const packageid = workStore.getActiveId;
@ -301,11 +310,10 @@ async function handleSelect(item: any) {
refreshHandler(); refreshHandler();
} }
async function sortHandler(orderby: "pictureResult" | "fromuptime") { async function sortHandler(orderby: "similarityScore" | "createdate") {
if (!selectTask.value) return;
sortBy.orderbyvalue = orderby; sortBy.orderName = orderby;
sortBy.orderbyname = sortBy.orderbyname === "asc" ? "desc" : "asc"; sortBy.orderType = sortBy.orderType === "asc" ? "desc" : "asc";
refreshHandler(); refreshHandler();
} }
@ -359,8 +367,8 @@ onUnmounted(() => {
function getPercent(pictureid: string) { function getPercent(pictureid: string) {
const { ocpictureid, pictureresult } = taskDetailInfo.value; const { ocpictureid, pictureresult } = taskDetailInfo.value;
const index = ocpictureid.split(",").indexOf(String(pictureid)); const index = ocpictureid ? ocpictureid.split(",").indexOf(String(pictureid)):'';
const results = pictureresult.split(","); const results = pictureresult ? pictureresult.split(",") : '';
const percent = results[index] || "0"; const percent = results[index] || "0";
const val = Math.floor(Number.parseFloat(percent)); const val = Math.floor(Number.parseFloat(percent));
return `${val}%`; return `${val}%`;
@ -440,7 +448,7 @@ function previewHandler(event: MouseEvent) {
<div class="wrapper-detail"> <div class="wrapper-detail">
<div <div
class="left" class="left"
:style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }" :style="{ 'background-image': `url(${taskDetailInfo?.imgurl})` }"
@click="showAction" @click="showAction"
@mouseleave="leaveTaskHandler" @mouseleave="leaveTaskHandler"
> >
@ -461,12 +469,12 @@ function previewHandler(event: MouseEvent) {
</div> </div>
<div class="time"> <div class="time">
<SvgIcon color="#FFF" size="16" name="time" /> <SvgIcon color="#FFF" size="16" name="time" />
<span>{{ formatToDateHMS(taskDetailInfo.createdate || 0) }}</span> <span>{{ taskDetailInfo.createTime }} </span>
</div> </div>
<!-- 右下信息 --> <!-- 右下信息 -->
<div class="info"> <div class="info">
<n-grid x-gap="16" y-gap="0" :cols="12"> <n-grid x-gap="16" y-gap="0" :cols="12">
<n-gi span="4"> <!-- <n-gi span="4">
<span style="color: #8b8d8f"> <span style="color: #8b8d8f">
<SvgIcon name="m1" /> <SvgIcon name="m1" />
</span> </span>
@ -482,7 +490,7 @@ function previewHandler(event: MouseEvent) {
> >
<span>{{ mark }}</span> <span>{{ mark }}</span>
<span>图片标记</span> <span>图片标记</span>
</n-gi> </n-gi> -->
<n-gi span="4"> <n-gi span="4">
<span style="color: #8b8d8f"> <span style="color: #8b8d8f">
<SvgIcon name="m2" /> <SvgIcon name="m2" />
@ -511,7 +519,7 @@ function previewHandler(event: MouseEvent) {
<n-image <n-image
ref="imageRef" ref="imageRef"
:img-props="{ onClick: hideDownload }" :img-props="{ onClick: hideDownload }"
:src="taskDetailInfo?.ocrPicture?.imgurl" :src="taskDetailInfo?.imgurl"
/> />
</div> </div>
<!-- 操作 --> <!-- 操作 -->
@ -530,20 +538,66 @@ function previewHandler(event: MouseEvent) {
</div> </div>
<div class="right"> <div class="right">
<n-scrollbar style="max-height: 100%"> <n-scrollbar style="max-height: 100%">
<span class="name">图片名称</span> <span class="name">任务ID{{taskDetailInfo.taskname}}</span>
<div class="tags"> <div class="tags">
<div class="tag tag-actived">重复图片</div> <div class="tag tag-actived">重复图片</div>
<div class="tag">基线任务</div> <div class="tag">基线任务</div>
</div> </div>
<n-divider /> <n-divider />
<div class="property"> <div class="property">
<span class="property-name top" style="font-weight: bold; color: #333333" <span class="property-name top" style=" color: #666666"
>拜访终端 >图片大小
</span>
<span style=" color: #333333; font-size: 16px"
>{{ (taskDetailInfo?.pictureInfo?.imgSize /1000).toFixed(2) }}KB</span
>
</div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>图片格式
</span> </span>
<span style="font-weight: bold; color: #333333; font-size: 16px" <span style=" color: #333333; font-size: 16px"
>拜访终端</span >{{ taskDetailInfo?.pictureInfo?.imgSpace }}</span
> >
</div> </div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>图片尺寸
</span>
<span style=" color: #333333; font-size: 16px"
>{{ taskDetailInfo?.pictureInfo?.imgMeasure }}</span
>
</div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>色彩空间
</span>
<span style=" color: #333333; font-size: 16px"
>{{ taskDetailInfo?.pictureInfo?.imgMeasure }}</span
>
</div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>提报人
</span>
<span style=" color: #333333; font-size: 16px"
>{{ taskDetailInfo?.pictureInfo?.source || "-" }}</span
>
</div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>创建时间
</span>
<span style=" color: #333333; font-size: 16px"
>{{ taskDetailInfo?.pictureInfo && format(taskDetailInfo?.pictureInfo?.createTime, 'yyyy-MM-dd HH:mm:ss')}}</span>
</div>
<div class="property">
<span class="property-name top" style=" color: #666666"
>提报时间
</span>
<span style=" color: #333333; font-size: 16px"
>{{ taskDetailInfo?.uploadTime && format(taskDetailInfo?.pictureInfo?.uploadTime, 'yyyy-MM-dd HH:mm:ss') || '-'}}</span>
</div>
<div v-for="key in Object.keys(propertys)" :key="key" class="property"> <div v-for="key in Object.keys(propertys)" :key="key" class="property">
<span class="property-name">{{ fieldMap[key] }}</span> <span class="property-name">{{ fieldMap[key] }}</span>
<span class="property-content">{{ propertys[key] }}</span> <span class="property-content">{{ propertys[key] }}</span>
@ -557,13 +611,13 @@ function previewHandler(event: MouseEvent) {
><span>({{ totalCount }})</span> ><span>({{ totalCount }})</span>
</div> </div>
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<div style="cursor: pointer" @click="sortHandler('fromuptime')"> <div style="cursor: pointer" @click="sortHandler('createdate')">
<span>按时间排序</span> <span>按时间排序</span>
<SvgIcon style="margin-left: 8px" name="sort" size="12" /> <SvgIcon style="margin-left: 8px" name="sort" size="12" />
</div> </div>
<div <div
style="margin-left: 15px; cursor: pointer" style="margin-left: 15px; cursor: pointer"
@click="sortHandler('pictureResult')" @click="sortHandler('similarityScore')"
> >
<span>相似度排序</span> <span>相似度排序</span>
<SvgIcon style="margin-left: 8px" name="sort" size="12" /> <SvgIcon style="margin-left: 8px" name="sort" size="12" />
@ -582,7 +636,7 @@ function previewHandler(event: MouseEvent) {
> >
<div <div
class="img-wrapper" class="img-wrapper"
:style="{ 'background-image': `url(${item.thumburl})` }" :style="{ 'background-image': `url(${item.imgurl})` }"
/> />
<div class="time"> <div class="time">
<SvgIcon color="#FFF" size="16" name="time" /> <SvgIcon color="#FFF" size="16" name="time" />
@ -744,7 +798,7 @@ function previewHandler(event: MouseEvent) {
right: 2%; right: 2%;
bottom: 2%; bottom: 2%;
width: 136px; width: 136px;
height: 119px; height: 60px;
opacity: 0.44; opacity: 0.44;
background: rgba(216, 216, 216, 0.4); background: rgba(216, 216, 216, 0.4);
border-radius: 7px; border-radius: 7px;
@ -813,15 +867,7 @@ function previewHandler(event: MouseEvent) {
} }
.top { .top {
&::after {
position: absolute;
left: 72px;
top: 4px;
content: "";
width: 1px;
height: 12px;
background: #979797;
}
} }
.property-content { .property-content {

@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import Aside from './aside/Aside.vue' import DataHeader from '@/components/DataHeader/index.vue';
import Content from './content/Content.vue' import Aside from './aside/Aside.vue';
import DataHeader from '@/components/DataHeader/index.vue' import Content from './content/Content.vue';
</script> </script>
<template> <template>
<div> <div style="width: 100%;">
<div class="header"> <div class="header">
<DataHeader v-show="false"/> <DataHeader v-show="false"/>
</div> </div>

@ -363,6 +363,7 @@ onMounted(async () => {
:class="{ fix: item.fix }" :class="{ fix: item.fix }"
class="cursor-move draggable-item" class="cursor-move draggable-item"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" v-if="!item.fix"
@ -394,6 +395,8 @@ onMounted(async () => {
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 32px;
&-title { &-title {
font-weight: bold; font-weight: bold;
@ -401,7 +404,6 @@ onMounted(async () => {
} }
&-bar { &-bar {
background-color: #e8e8e8;
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
@ -414,6 +416,8 @@ onMounted(async () => {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
color: #333333;
font-size: 14px;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -462,10 +466,11 @@ onMounted(async () => {
} }
.draggable-item { .draggable-item {
padding: 10px 16px; padding: 11px 16px;
color: #333; color: #333;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #E8E8E8;
} }
.disable-check { .disable-check {
@ -484,9 +489,13 @@ onMounted(async () => {
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
::v-deep(.n-card > .n-card-header .n-card-header__main){ ::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important; font-weight: lighter !important;
font-size: 14px;
} }
::v-deep(.n-scrollbar){ ::v-deep(.n-scrollbar){
border-top: none !important; border-top: none !important;
} }
::v-deep(.n-button--info-type){
background: #507AFD !important;
}
</style> </style>

@ -377,6 +377,7 @@ onMounted(async () => {
:class="{ fix: item.fix }" :class="{ fix: item.fix }"
class="cursor-move draggable-item" class="cursor-move draggable-item"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" v-if="!item.fix"
@ -408,6 +409,8 @@ onMounted(async () => {
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
border-bottom: 1px solid #e8e8e8;
padding-bottom: 32px;
&-title { &-title {
font-weight: bold; font-weight: bold;
@ -415,7 +418,6 @@ onMounted(async () => {
} }
&-bar { &-bar {
background-color: #e8e8e8;
width: 100%; width: 100%;
margin-top: 20px; margin-top: 20px;
} }
@ -428,6 +430,8 @@ onMounted(async () => {
&-info { &-info {
font-weight: bold; font-weight: bold;
position: relative; position: relative;
color: #333333;
font-size: 14px;
&:before { &:before {
background-color: #1980ff; background-color: #1980ff;
@ -476,10 +480,11 @@ onMounted(async () => {
} }
.draggable-item { .draggable-item {
padding: 10px 16px; padding: 11px 16px;
color: #333; color: #333;
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid #E8E8E8;
} }
.disable-check { .disable-check {
@ -498,9 +503,14 @@ onMounted(async () => {
--n-padding-bottom: 12px; --n-padding-bottom: 12px;
} }
::v-deep(.n-card > .n-card-header .n-card-header__main){ ::v-deep(.n-card > .n-card-header .n-card-header__main){
font-weight: bolder !important; font-weight: lighter !important;
font-size: 14px;
} }
::v-deep(.n-scrollbar){ ::v-deep(.n-scrollbar){
border-top: none !important; border-top: none !important;
} }
::v-deep(.n-button--info-type){
background: #507AFD !important;
}
</style> </style>

5
types/api.d.ts vendored

@ -7,6 +7,11 @@ export interface PictureSortParam {
orderbyname?: 'asc' | 'desc' orderbyname?: 'asc' | 'desc'
orderbyvalue?: 'pictureResult' | 'fromuptime' orderbyvalue?: 'pictureResult' | 'fromuptime'
} }
export interface SimilarityPictureSortParam {
checkDuplicateId?: string
orderType?: 'asc' | 'desc'
orderName?: 'similarityScore' | 'createdate'
}
export interface FilterSearchParam { export interface FilterSearchParam {
search_searchname?: { search_searchname?: {

@ -1,5 +1,6 @@
// 任务包 // 任务包
export interface PackageListItem { export interface PackageListItem {
checkDuplicateId: string
id: string id: string
packagename: string packagename: string
pictureno: number pictureno: number
@ -11,6 +12,7 @@ export interface PackageListItem {
// 任务包状态 // 任务包状态
export interface OrderState { export interface OrderState {
name: string
activeId: string activeId: string
currentIndex: number currentIndex: number
packageList: PackageListItem[] packageList: PackageListItem[]

Loading…
Cancel
Save