elseif 2 years ago
parent 8084dab1f9
commit 6a50a92ed0

@ -1,6 +1,5 @@
import { http } from '@/utils/http/axios'
import type { PageParam } from '/#/api'
import { ContentTypeEnum } from '@/enums/httpEnum'
/**
*
@ -26,7 +25,6 @@ export async function getPictureTypeList(): Promise<any> {
const res = await http.request({
url: `/ocr/ocrPicturetype/rootList`,
method: 'get',
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
const { data } = res
@ -87,7 +85,6 @@ export async function getIzShowList(): Promise<any> {
const res = await http.request({
url: `/ocr/ocrPictureclass/rootList`,
method: 'get',
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
const { data } = res
@ -123,26 +120,12 @@ export async function getIzsSearchManager(): Promise<any> {
}
/**
* izproject
*
* @returns
*/
export async function getIzProjectList(): Promise<any> {
const res = await http.request({
url: `/ocr/ocrPictureclass/todo`,
method: 'get',
})
const { data } = res
return data
}
/**
* izcustomtype
* @returns
*/
export async function getIzCustomtypeList(): Promise<any> {
const res = await http.request({
url: `/ocr/ocrPictureclass/todo`,
url: `/backstage/oa/category/listall`,
method: 'get',
})
@ -188,7 +171,7 @@ export async function getIztaskstatusList(enabled: string) {
*/
export async function getIzvisitproList(): Promise<any> {
const res = await http.request({
url: `/ocr/ocrPictureclass/todo`,
url: `/backstage/ocrnewtest/ocrprovince/listall`,
method: 'get',
})
@ -229,34 +212,29 @@ export async function getIzproductnameList(enabled: string) {
}
/**
*
*
* @param enabled
* @returns
*/
export async function getIzfiled2List(enabled: string) {
export async function getizcustomnameList(enabled: string) {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMTYPE`,
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMNAME`,
method: 'get',
params: { enabled },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
debugger
const list = res.data[0].distionaryList
return list
}
/**
*
* @param enabled
* izcustomtype
* @returns
*/
export async function getIzfiled3List(enabled: string) {
export async function getIzCustomtypeList(): Promise<any> {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMNAME`,
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMTYPE`,
method: 'get',
params: { enabled },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
const list = res.data[0].distionaryList
@ -268,12 +246,11 @@ export async function getIzfiled3List(enabled: string) {
* @param enabled
* @returns
*/
export async function getIzfiled6List(enabled: string) {
export async function getIzcustomlevel(enabled: string) {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/IZCUSTOMLEVEL`,
method: 'get',
params: { enabled },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
const list = res.data[0].distionaryList
@ -285,14 +262,28 @@ export async function getIzfiled6List(enabled: string) {
* @param enabled
* @returns
*/
export async function getIzfiled17List(enabled: string) {
export async function getIzprojecttypeList(enabled: string) {
const res = await http.request({
url: `/static/admin/web/distionary/bytypecode/IZPROJECTTYPE`,
method: 'get',
params: { enabled },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
const list = res.data[0].distionaryList
return list
}
/**
*
* @param enabled
* @returns
*/
export async function getIzvisitcityList() {
const res = await http.request({
url: `/ocr/ocrarea/listall`,
method: 'get',
})
const { data } = res
return data
}

@ -1,6 +1,9 @@
import { pickBy } from 'lodash-es'
import { http } from '@/utils/http/axios'
import type { CheckParam, PageParam, QueryPictureParam, UploadParam } from '/#/api'
import { ContentTypeEnum } from '@/enums/httpEnum'
import { notEmpty } from '@/utils'
import { formatToDate2 } from '@/utils/dateUtil'
/**
*
@ -69,10 +72,19 @@ export async function saveNote(note: string) {
* @returns
*/
export async function oneClickCheck(params: Partial<CheckParam> = { search_history: '0' }) {
const notEmptyParams = pickBy(params, notEmpty)
Object.keys(notEmptyParams).forEach((key) => {
const val = notEmptyParams[key]
if (Array.isArray(val))
notEmptyParams[key] = val.join(',')
})
return http.request({
url: `/ocr/ocrPicture/createorder`,
method: 'get',
params,
params: notEmptyParams,
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
}
@ -83,10 +95,25 @@ export async function oneClickCheck(params: Partial<CheckParam> = { search_histo
* @returns
*/
export async function getPictureList(params: any): Promise<any> {
const notEmptyParams = pickBy(params, notEmpty)
Object.keys(notEmptyParams).forEach((key) => {
const val = notEmptyParams[key]
if (key === 'izyear') {
const start = formatToDate2(val[0])
const end = formatToDate2(val[1])
notEmptyParams[key] = `${start}-${end}`
}
if (Array.isArray(val))
notEmptyParams[key] = val.join(',')
})
const res = await http.request({
url: `/ocr/ocrPicture/list`,
method: 'get',
params,
params: notEmptyParams,
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})

@ -1,5 +1,6 @@
import { http } from '@/utils/http/axios'
import type { PageParam, PictureSortParam, SetTFParam } from '/#/api'
import { ContentTypeEnum } from '@/enums/httpEnum'
/**
*
@ -69,12 +70,31 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
})
const { data: { records, pages } } = res
// 精简一下数据
const list = records.map((item) => {
return {
id: item.id,
pictureid: item.pictureid,
imgurl: item.ocrPicture.imgurl,
iztrueorfalse: item.iztrueorfalse,
states: item.states,
history: hasHistory(item.ocpictureid, item.picturecompare),
}
})
return {
pageCount: pages,
data: records,
data: list,
}
}
// ocpictureid 比 picturecompare数据多说明有历史数据
function hasHistory(ocpictureid: string, picturecompare: string) {
const ids = ocpictureid.split(',')
const compares = picturecompare.split(',')
return ids.length > compares.length
}
/**
*
* @param params
@ -82,9 +102,10 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
*/
export async function setTF(params: SetTFParam) {
return await http.request({
url: `/ocr/ocrPackagetask/ordertrueorfalse`,
url: `/backstage/jifen/ocrtaskchildpicture/ordertrueorfalse`,
method: 'post',
params,
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
}
@ -93,11 +114,12 @@ export async function setTF(params: SetTFParam) {
* @param id
* @returns
*/
export async function clearTF(id: string): Promise<any> {
export async function clearTF(id: string, childId: string): Promise<any> {
return await http.request({
url: `/ocr/ocrPackagetask/listorderbytask`,
method: 'get',
params: { packageid: id },
url: `/backstage/jifen/ocrtaskchildpicture/clearmark`,
method: 'post',
params: { packageid: id, taskchildpictureid: childId },
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
})
}

@ -0,0 +1,19 @@
<?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(-1720.000000, -5402.000000)">
<g id="假" transform="translate(1720.000000, 5402.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M37.6322905,14.984487 L38.7393781,15.7671543 L38.9111675,14.4945245 L39.9673545,13.7373098 L38.7584658,13.100995 L38.3003606,11.8283652 L37.3841502,12.7446586 L36.0416475,12.7446586 L36.6779047,13.915478 L36.3088755,15.156292 L37.6322905,14.984487 Z M26.5932278,15.7353386 L26.4596138,14.4627088 L25.4097894,13.6291363 L26.6823038,13.1264476 L27.1722219,11.9301756 L28.0757071,12.9101005 L29.430935,12.9991846 L28.7437772,14.1127356 L29.0873561,15.3853654 L27.7639411,15.0926605 L26.5932278,15.7353386 Z M18.589112,21.1058362 L17.7365273,20.1322744 L16.4003872,20.0559166 L17.1193578,18.9296393 L16.8330421,17.6570095 L18.1373694,17.9369881 L19.2953575,17.2306785 L19.378071,18.5033083 L20.3833574,19.3814228 L19.1108429,19.9095642 L18.589112,21.1058362 Z M13.3654403,29.2633929 L12.1247387,29.7724449 L12.2901655,28.4425467 L11.4884815,27.424443 L12.7609959,27.1126486 L13.5054169,25.9800082 L14.1416741,27.1190118 L15.4141885,27.4308061 L14.5107033,28.4489099 L14.5488787,29.778808 L13.3654403,29.2633929 Z M49.1485461,35.1811213 L50.4210606,35.6519944 L51.6299493,35.1302162 L51.5917739,36.4028459 L52.5143469,37.3700446 L51.2418324,37.7009283 L50.6055752,38.8144793 L49.8484291,37.7263809 L48.5313767,37.4527655 L49.3521484,36.447388 L49.1485461,35.1811213 Z M44.8856228,43.6250198 L44.4147925,44.8340181 L43.2059037,45.470333 L44.243003,46.2466372 L44.3957048,47.5192669 L45.5091549,46.7429627 L46.7816693,46.9593098 L46.4253653,45.68668 L47.0616225,44.528587 L45.7254823,44.528587 L44.8856228,43.6250198 Z M36.2325246,49.2882223 L34.9600102,48.9509754 L35.2590511,50.2236052 L34.546443,51.3053404 L35.8825832,51.4453297 L36.7160801,52.4697967 L37.2441737,51.2989773 L38.516688,50.8408306 L37.4795888,49.9563529 L37.3905128,48.6837232 L36.2325246,49.2882223 Z M25.9124326,48.7791704 L25.6324794,50.0518001 L24.5190293,50.688115 L25.6642923,51.3944246 L26.0078711,52.6670543 L26.9813447,51.8907502 L28.3047597,52.0243763 L27.7703037,50.8026517 L28.2538591,49.6000166 L26.9368067,49.6700112 L25.9124326,48.7791704 Z M27.1213213,4.42802313 C11.8990931,7.12223613 1.74157104,21.6457508 4.43190188,36.8700021 C7.12223271,52.0942534 21.6420033,62.2561667 36.8655174,59.5692305 C52.0890316,56.8822943 62.2534937,42.3636368 59.5704394,27.1381012 C56.8695479,11.9124888 42.3497315,1.75054342 27.1213213,4.42802313 Z M36.525203,57.7639365 C26.1142305,59.6004364 15.6222161,54.9840716 9.94162608,46.0674705 C4.26103605,37.1508694 4.5105813,25.6900291 10.5738979,17.0291831 C16.6372146,8.368337 27.3202191,4.2131149 37.6413859,6.50111265 C47.9625527,8.7891104 55.8892755,17.0697396 57.7252934,27.4817113 C60.2137431,41.6945273 50.7305662,55.2403043 36.525203,57.7639365 L36.525203,57.7639365 Z M27.9102802,8.90131673 C18.5577823,10.5488373 11.1187133,17.6687527 9.06224204,26.9407297 C7.00577079,36.2127067 10.7369337,45.8105645 18.5157235,51.2583951 C26.2945133,56.7062257 36.5888429,56.9310407 44.5980086,51.827999 C52.6071743,46.7249572 56.7537147,37.2991384 55.1039137,27.9462212 C52.8420869,15.184222 40.6753602,6.66332507 27.9102802,8.90131673 Z M52.4952591,41.0161288 C48.0172284,51.177241 36.7727048,56.5249368 26.0654898,53.5856581 C15.3582748,50.6463793 8.4192751,40.3070546 9.75566929,29.2835197 C11.0920635,18.2599848 20.300594,9.87859619 31.3999245,9.58342599 C42.499255,9.2882558 52.1401577,17.1683717 54.0604519,28.1052999 C54.8274005,32.4689969 54.2826901,36.9621579 52.4952591,41.0161288 L52.4952591,41.0161288 Z M39.1338576,19.3050651 C34.6554251,16.7886428 29.1826556,16.8178072 24.7312918,19.3818162 C20.279928,21.9458253 17.508386,26.6654278 17.4374864,31.8022893 L18.366422,31.8022893 C18.4484757,27.0044487 21.0460383,22.6028621 25.2062521,20.2121526 C29.366466,17.8214432 34.476946,17.7935243 38.6630272,20.1386375 L39.1338576,19.3050651 Z M34.3619285,45.3939752 C31.2608066,45.9396236 28.0664258,45.3955629 25.3207134,43.8540932 L24.8626082,44.6622131 C29.3371087,47.1765976 34.8046351,47.1499504 39.2544194,44.5920714 C43.7042036,42.0341924 46.4792451,37.3227465 46.5589793,32.1904414 L45.6300437,32.1904414 C45.5544744,38.7549571 40.8146097,44.3347621 34.3492033,45.470333 L34.3619285,45.3939752 Z" id="形状" fill="#FF7E7E" fill-rule="nonzero" mask="url(#mask-2)"></path>
<path d="M26.7439299,40.1322318 L26.7439299,28.2342318 C26.9839299,27.5622318 27.2539299,26.6862318 27.5539299,25.6062318 L27.5539299,25.6062318 L27.5539299,40.1322318 L29.8939299,40.1322318 L29.8939299,37.3962318 L32.9899299,37.3962318 L32.9899299,35.1102318 L29.8939299,35.1102318 L29.8939299,34.1382318 L32.5039299,34.1382318 L32.5039299,31.8522318 L29.8939299,31.8522318 L29.8939299,30.7902318 L32.9899299,30.7902318 L32.9899299,24.9942318 L27.7159299,24.9942318 L27.7519299,24.8682318 L25.4839299,24.2922318 C25.0999299,25.7922318 24.6709299,27.1692318 24.1969299,28.4232318 C23.7229299,29.6772318 23.1619299,30.8742318 22.5139299,32.0142318 L22.5139299,32.0142318 L23.8459299,34.3362318 C24.1339299,33.8922318 24.3679299,33.5082318 24.5479299,33.1842318 L24.5479299,33.1842318 L24.5479299,40.1322318 L26.7439299,40.1322318 Z M38.9299299,30.7902318 L38.9299299,24.9942318 L33.4939299,24.9942318 L33.4939299,27.2802318 L37.0399299,27.2802318 L37.0399299,28.5042318 L33.4939299,28.5042318 L33.4939299,30.7902318 L38.9299299,30.7902318 Z M31.0999299,28.5042318 L29.8939299,28.5042318 L29.8939299,27.2802318 L31.0999299,27.2802318 L31.0999299,28.5042318 Z M38.5159299,40.3482318 L39.3619299,38.1702318 C38.7019299,37.8942318 38.0659299,37.4982318 37.4539299,36.9822318 C38.1259299,36.0102318 38.6179299,34.9182318 38.9299299,33.7062318 L38.9299299,33.7062318 L38.9299299,31.4202318 L32.9719299,31.4202318 L32.9719299,33.7062318 L36.7339299,33.7062318 C36.5299299,34.2822318 36.2719299,34.8042318 35.9599299,35.2722318 C35.6839299,34.8522318 35.4379299,34.3542318 35.2219299,33.7782318 L35.2219299,33.7782318 L33.1879299,34.3182318 C33.4759299,35.2542318 33.8839299,36.1242318 34.4119299,36.9282318 C33.5239299,37.5882318 32.5459299,37.9782318 31.4779299,38.0982318 L31.4779299,38.0982318 L32.8459299,40.2222318 C33.9739299,39.9222318 34.9879299,39.4062318 35.8879299,38.6742318 C36.6439299,39.3702318 37.5199299,39.9282318 38.5159299,40.3482318 L38.5159299,40.3482318 Z" fill="#FF7E7E" fill-rule="nonzero" mask="url(#mask-2)" transform="translate(30.937930, 32.320232) rotate(-25.000000) translate(-30.937930, -32.320232) "></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.0 KiB

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="96px" height="96px" viewBox="0 0 96 96" 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="96" height="96"></rect>
<linearGradient x1="80.921%" y1="13.935%" x2="8.40499214%" y2="108.92891%" id="linearGradient-3">
<stop stop-color="#94B3FF" offset="0%"></stop>
<stop stop-color="#3955FF" offset="100%"></stop>
</linearGradient>
<path d="M37.4400001,11.1199999 C18.8832001,11.1199999 3.84000013,26.1631999 3.84000013,44.7199999 C3.84000013,63.2767999 18.8832001,78.3199999 37.4400001,78.3199999 C55.9968001,78.3199999 71.0400001,63.2767999 71.0400001,44.7199999 C71.0400001,26.1631999 55.9968001,11.1199999 37.4400001,11.1199999 Z" id="path-4"></path>
<filter x="0.0%" y="0.0%" width="100.0%" height="100.0%" filterUnits="objectBoundingBox" id="filter-5">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feColorMatrix values="0 0 0 0 0.328065454 0 0 0 0 0.41948512 0 0 0 0 1 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
</filter>
<linearGradient x1="39.928%" y1="17.244%" x2="88.179%" y2="85.071%" id="linearGradient-6">
<stop stop-color="#BACFFA" stop-opacity="0.18" offset="0%"></stop>
<stop stop-color="#DBEDF7" stop-opacity="0.2" offset="100%"></stop>
</linearGradient>
<linearGradient x1="13.9030991%" y1="12.1433261%" x2="93.3488115%" y2="77.2722619%" id="linearGradient-7">
<stop stop-color="#EAF3FF" offset="0%"></stop>
<stop stop-color="#91A6BF" offset="100%"></stop>
</linearGradient>
<rect id="path-8" x="24" y="18.8" width="67.2" height="67.2" rx="33.6"></rect>
<linearGradient x1="29.119%" y1="29.2684975%" x2="83.923%" y2="72.200046%" id="linearGradient-9">
<stop stop-color="#E9F2FC" stop-opacity="0.9" offset="0%"></stop>
<stop stop-color="#CDDEFF" offset="100%"></stop>
</linearGradient>
<path d="M32.3028907,16.7405789 C32.8821221,17.394115 33.1213698,18.0036631 33.0206339,18.5692232 C32.919898,19.1347833 32.5925064,19.7066274 32.0384589,20.2847555 L20.0634794,32.3500376 C19.8620076,32.5259896 19.6227598,32.6642377 19.3457361,32.7647817 C19.0687124,32.8653257 18.7853927,32.9218817 18.495777,32.9344497 C18.2061613,32.9470177 17.9228416,32.9155977 17.6458179,32.8401897 C17.3687942,32.7647817 17.1421384,32.6391017 16.9658506,32.4631496 C13.9689577,29.4468291 11.2868645,26.7447086 8.91957097,24.3567882 L5.93527007,21.3781717 C4.95309509,20.3978675 4.077952,19.5181074 3.3098408,18.7388913 C2.54172959,17.9596751 1.91213025,17.331275 1.42104276,16.8536909 C0.929955269,16.3761068 0.671819537,16.1121788 0.646635563,16.0619068 C0.571083642,15.9613628 0.438867779,15.7791267 0.249987976,15.5151987 C0.0611081718,15.2512706 -0.0207397432,14.9433546 0.00444423068,14.5914505 L0.00444423068,13.8750744 L0.00444423068,12.3669141 C0.00444423068,11.788786 0.0107402241,11.1415339 0.0233322111,10.4251578 C0.035924198,9.70878168 0.0422201914,8.98612156 0.0422201914,8.25717743 C0.0674041653,6.52279313 0.0925881391,4.5998888 0.117772113,2.48846443 C0.168140061,2.16169638 0.243691982,1.86634832 0.344427877,1.60242028 C0.445163773,1.33849223 0.634043577,1.06828019 0.911067289,0.791784137 C1.16290703,0.515288089 1.43363475,0.314200055 1.72325044,0.188520033 C2.01286614,0.0628400109 2.28359386,-2.61624101e-16 2.5354336,-2.61624101e-16 L14.699293,-2.61624101e-16 C14.7496609,-2.61624101e-16 14.8629888,0.00628400109 15.0392766,0.0188520033 C15.2155644,0.0314200055 15.3414843,0.0502720087 15.4170362,0.0754080131 C15.5681401,0.125680022 15.7066519,0.188520033 15.8325718,0.263928046 C15.9584917,0.339336059 16.0844115,0.439880076 16.2103314,0.565560098 L32.3028907,16.7405789 Z M5.82194219,9.42600164 C6.82930114,9.42600164 7.67926026,9.07409757 8.37181954,8.37028945 C9.06437882,7.66648133 9.41065846,6.81185718 9.41065846,5.80641701 C9.41065846,4.80097683 9.06437882,3.94635268 8.37181954,3.24254456 C7.67926026,2.53873644 6.82930114,2.18683238 5.82194219,2.18683238 C5.31826271,2.18683238 4.85235919,2.2810924 4.42423164,2.46961243 C3.99610408,2.65813246 3.61834448,2.91577651 3.29095282,3.24254456 C2.96356116,3.56931262 2.70542542,3.95263669 2.51654562,4.39251676 C2.32766582,4.83239684 2.23322592,5.30369692 2.23322592,5.80641701 C2.23322592,6.30913709 2.32766582,6.78043718 2.51654562,7.22031725 C2.70542542,7.66019733 2.96356116,8.0435214 3.29095282,8.37028945 C3.61834448,8.69705751 3.99610408,8.95470155 4.42423164,9.14322159 C4.85235919,9.33174162 5.31826271,9.42600164 5.82194219,9.42600164 L5.82194219,9.42600164 Z" id="path-10"></path>
<filter x="-21.2%" y="-21.3%" width="157.5%" height="157.7%" filterUnits="objectBoundingBox" id="filter-11">
<feOffset dx="3" dy="3" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.341176471 0 0 0 0 0.474509804 0 0 0 0 1 0 0 0 0.280509895 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter2"></feOffset>
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter2" result="shadowBlurOuter2"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter2" result="shadowMatrixOuter2"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
<feMergeNode in="shadowMatrixOuter2"></feMergeNode>
</feMerge>
</filter>
<filter x="-13.6%" y="-13.7%" width="142.4%" height="142.5%" filterUnits="objectBoundingBox" id="filter-12">
<feGaussianBlur stdDeviation="1.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="无法上传iconfont" transform="translate(-548.000000, -80.000000)">
<g id="图片标记" transform="translate(548.000000, 80.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="矩形-1"></g>
<g id="路径" mask="url(#mask-2)" transform="translate(37.440000, 44.720000) rotate(-0.000000) translate(-37.440000, -44.720000) ">
<use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
<use fill="url(#linearGradient-3)" fill-rule="evenodd" xlink:href="#path-4"></use>
</g>
<path id="glass" d="M57.6,18.12 C76.5323212,18.12 91.88,33.4676788 91.88,52.4 C91.88,71.3323212 76.5323212,86.68 57.6,86.68 C38.6676788,86.68 23.32,71.3323212 23.32,52.4 C23.32,33.4676788 38.6676788,18.12 57.6,18.12 Z M57.6,19.48 C39.418786,19.48 24.68,34.218786 24.68,52.4 C24.68,70.581214 39.418786,85.32 57.6,85.32 C75.781214,85.32 90.52,70.581214 90.52,52.4 C90.52,34.218786 75.781214,19.48 57.6,19.48 Z" fill-rule="nonzero"></path>
<g id="编组" mask="url(#mask-2)">
<g transform="translate(41.078490, 35.931429)" id="形状">
<use fill="black" fill-opacity="1" filter="url(#filter-11)" xlink:href="#path-10"></use>
<use fill="url(#linearGradient-9)" fill-rule="evenodd" xlink:href="#path-10"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-10"></use>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="96px" height="96px" viewBox="0 0 96 96" 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="96" height="96"></rect>
<linearGradient x1="80.921%" y1="13.935%" x2="8.40499214%" y2="108.92891%" id="linearGradient-3">
<stop stop-color="#42E7B4" offset="0%"></stop>
<stop stop-color="#21BC86" offset="100%"></stop>
</linearGradient>
<path d="M28.1928199,7.23280356 L53.7928199,7.23280356 C64.3966871,7.23280356 72.9928199,15.8289364 72.9928199,26.4328036 L72.9928199,52.0328036 C72.9928199,62.6366708 64.3966871,71.2328036 53.7928199,71.2328036 L28.1928199,71.2328036 C17.5889527,71.2328036 8.99281987,62.6366708 8.99281987,52.0328036 L8.99281987,26.4328036 C8.99281987,15.8289364 17.5889527,7.23280356 28.1928199,7.23280356 Z" id="path-4"></path>
<filter x="0.0%" y="0.0%" width="100.0%" height="100.0%" filterUnits="objectBoundingBox" id="filter-5">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feColorMatrix values="0 0 0 0 0.175456896 0 0 0 0 0.836008265 0 0 0 0 0.633207406 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
</filter>
<linearGradient x1="39.928%" y1="17.244%" x2="88.179%" y2="85.071%" id="linearGradient-6">
<stop stop-color="#BAFAE1" stop-opacity="0.18" offset="0%"></stop>
<stop stop-color="#DBF7E9" stop-opacity="0.2" offset="100%"></stop>
</linearGradient>
<linearGradient x1="13.9030991%" y1="12.1433261%" x2="93.3488115%" y2="77.2722619%" id="linearGradient-7">
<stop stop-color="#EAFFF3" offset="0%"></stop>
<stop stop-color="#91BFA9" offset="100%"></stop>
</linearGradient>
<rect id="path-8" x="27.2" y="14.88" width="64" height="64" rx="19.2"></rect>
<linearGradient x1="23.0891446%" y1="17.7506798%" x2="83.923%" y2="71.7600396%" id="linearGradient-9">
<stop stop-color="#E8FAF3" stop-opacity="0.9" offset="0%"></stop>
<stop stop-color="#BAF7E5" offset="100%"></stop>
</linearGradient>
<path d="M43.641,63.3381257 L41.331,63.3381257 L41.331,26.4904457 L43.641,26.4904457 L43.641,63.3381257 Z M55.17,57.5741257 L43.641,57.5741257 L43.641,32.2544457 L55.17,32.2544457 L55.17,57.5741257 Z M76.359,57.5741257 L64.83,57.5741257 L64.83,32.2544457 L76.359,32.2544457 L76.359,57.5741257 Z M78.669,63.3381257 L76.359,63.3381257 L76.359,26.4904457 L78.669,26.4904457 L78.669,63.3381257 Z" id="path-10"></path>
<filter x="-18.7%" y="-19.0%" width="150.9%" height="151.6%" filterUnits="objectBoundingBox" id="filter-11">
<feOffset dx="3" dy="3" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.537254902 0 0 0 0 0.960784314 0 0 0 0 0.82870759 0 0 0 0.69 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter2"></feOffset>
<feGaussianBlur stdDeviation="1.5" in="shadowOffsetOuter2" result="shadowBlurOuter2"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0" type="matrix" in="shadowBlurOuter2" result="shadowMatrixOuter2"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
<feMergeNode in="shadowMatrixOuter2"></feMergeNode>
</feMerge>
</filter>
<filter x="-12.1%" y="-12.2%" width="137.5%" height="138.0%" filterUnits="objectBoundingBox" id="filter-12">
<feGaussianBlur stdDeviation="1.5" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="无法上传iconfont" transform="translate(-860.000000, -80.000000)">
<g id="分组-1" transform="translate(860.000000, 80.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="矩形-1"></g>
<g id="BG" mask="url(#mask-2)" transform="translate(40.992820, 39.232804) rotate(-29.999999) translate(-40.992820, -39.232804) ">
<use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-4"></use>
<use fill="url(#linearGradient-3)" fill-rule="evenodd" xlink:href="#path-4"></use>
</g>
<path id="glass" d="M72,14.2 C82.9794208,14.2 91.88,23.1005792 91.88,34.08 L91.88,34.08 L91.88,59.68 C91.88,70.6594208 82.9794208,79.56 72,79.56 L72,79.56 L46.4,79.56 C35.4205792,79.56 26.52,70.6594208 26.52,59.68 L26.52,59.68 L26.52,34.08 C26.52,23.1005792 35.4205792,14.2 46.4,14.2 L46.4,14.2 Z M72,15.56 L46.4,15.56 C36.1716864,15.56 27.88,23.8516864 27.88,34.08 L27.88,34.08 L27.88,59.68 C27.88,69.9083136 36.1716864,78.2 46.4,78.2 L46.4,78.2 L72,78.2 C82.2283136,78.2 90.52,69.9083136 90.52,59.68 L90.52,59.68 L90.52,34.08 C90.52,23.8516864 82.2283136,15.56 72,15.56 L72,15.56 Z" fill-rule="nonzero"></path>
<g id="Justify_space-between" mask="url(#mask-2)">
<g transform="translate(41.331000, 26.490446)"></g>
</g>
<g id="形状" mask="url(#mask-2)">
<use fill="black" fill-opacity="1" filter="url(#filter-11)" xlink:href="#path-10"></use>
<use fill="url(#linearGradient-9)" fill-rule="evenodd" xlink:href="#path-10"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-10"></use>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

@ -5,8 +5,8 @@
<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(-1192.000000, -5402.000000)">
<g id="真" transform="translate(1192.000000, 5402.000000)">
<g id="PrevailCloud-Design-图标集" transform="translate(-1984.000000, -5402.000000)">
<g id="真" transform="translate(1984.000000, 5402.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

@ -1,5 +1,5 @@
import type { Component } from 'vue'
import { IzCustomtypesVue, IzProductVue, IzProjectVue, IzSearchManagerVue, IzSearchVue, IzShowVue, Izfiled17Vue, Izfiled2Vue, Izfiled3Vue, Izfiled6Vue, IzfirmVue, IztaskrromVue, IztaskstatusVue, IzvisitproVue, PictureDownloadVue, PictureTypeVue, PictureUploadVue, PlaceHolderVue, PlanVue, RegionVue, ReportUserVue, SimilarityVue, TimeVue } from '@/views/home/aside/comp/items'
import { IzCustomlevel, IzCustomname, IzCustomtype, IzProductVue, IzProjectVue, IzProjecttype, IzShowVue, IzfirmVue, IztaskrromVue, IztaskstatusVue, IzvisitproVue, PictureDownloadVue, PictureTypeVue, PictureUploadVue, PlaceHolderVue, PlanVue, ReportUserVue, SimilarityVue, TimeVue } from '@/views/home/aside/comp/items'
export interface AsideEntity {
label: string
@ -50,14 +50,14 @@ export const asideMap: Recordable<AsideEntity> = {
},
izyear: {
label: '年份',
defaultValue: [1183135260000, Date.now()],
defaultValue: [1704038400000, Date.now()],
isDefaultFilter: false,
key: 'izyear',
component: TimeVue,
},
izpicturetype: {
label: '图片类型',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izpicturetype',
component: PictureTypeVue,
@ -68,132 +68,106 @@ export const asideMap: Recordable<AsideEntity> = {
isDefaultFilter: false,
key: 'izupload',
component: PictureUploadVue,
inFilterList: false,
},
izcustomtype: {
label: '客户类型',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomtype',
component: IzCustomtypesVue,
component: IzCustomtype,
},
izcustomlevel: {
label: '客户级别',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomlevel',
component: PlaceHolderVue,
component: IzCustomlevel,
},
izcustomname: {
label: '客户名称',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izcustomname',
component: PlaceHolderVue,
component: IzCustomname,
},
izprojecttype: {
label: '项目类型',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izprojecttype',
component: PlaceHolderVue,
component: IzProjecttype,
},
iztaskrrom: {
label: '任务来源',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'iztaskrrom',
component: IztaskrromVue,
},
iztaskstatus: {
label: '任务状态',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'iztaskstatus',
component: IztaskstatusVue,
},
izvisitpro: {
label: '拜访省份',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izvisitpro',
component: IzvisitproVue,
},
izvisitcity: {
label: '拜访城市',
defaultValue: [],
label: '发布地区',
defaultValue: null,
isDefaultFilter: false,
key: 'izvisitpro',
key: 'izvisitcity',
component: PlaceHolderVue,
},
izfirm: {
label: '厂商',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izfirm',
component: IzfirmVue,
},
izproductname: {
label: '产品名称',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izproductname',
component: IzProductVue,
},
izdesc: {
label: 'izdesc',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izdesc',
component: PlaceHolderVue,
inFilterList: false,
},
izsearchmanager: {
label: 'izsearchmanager',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izsearchmanager',
component: IzSearchManagerVue,
component: PlaceHolderVue,
inFilterList: false,
},
izshow: {
label: '分类',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izshow',
component: IzShowVue,
},
izsearch: {
label: 'izsearch',
defaultValue: [],
defaultValue: null,
isDefaultFilter: false,
key: 'izsearch',
component: IzSearchVue,
},
izfiled2: {
label: 'izfiled2',
defaultValue: [],
isDefaultFilter: false,
key: 'izfiled2',
component: Izfiled2Vue,
},
izfiled6: {
label: 'izfiled6',
defaultValue: [],
isDefaultFilter: false,
key: 'izfiled6',
component: Izfiled6Vue,
},
izfiled3: {
label: 'izfiled3',
defaultValue: [],
isDefaultFilter: false,
key: 'izfiled3',
component: Izfiled3Vue,
},
izfiled17: {
label: 'izfiled17',
defaultValue: [],
isDefaultFilter: false,
key: 'izfiled17',
component: Izfiled17Vue,
component: PlaceHolderVue,
inFilterList: false,
},
}

@ -87,3 +87,22 @@ export const workPackageMap: Recordable<PackageEntity> = {
key: 'upuser',
},
}
export const fieldMap = {
field1: '提报人',
field2: '拜访客户类型',
field3: '拜访客户名称',
field4: '任务来源',
field5: '厂商1',
field6: '拜访客户级别',
field7: '科室名称',
field8: '拜访小结',
field9: '产品名称',
field10: '定位信息',
field11: 2002,
field12: '定位距离',
field13: '病历号',
field14: '是否重复',
field15: '任务类型',
field16: '任务状态',
}

@ -1,30 +1,22 @@
<script lang="ts" setup>
import { computed, inject, onMounted, ref } from 'vue'
defineOptions({ name: 'Settings' })
import { useUser } from '@/store/modules/user'
import { getImgUrl } from '@/utils/urlUtils'
const emit = defineEmits<{
(e: 'logout'): void
}>()
const options = [
{
label: '北京李白有限科技有限公司',
key: '1',
},
{
label: '北京杜甫有限科技有限公司',
key: '2',
},
{
label: '北京白居易有限科技有限公司',
key: '3',
},
]
const userStore = useUser()
const useInfo = userStore.getUserInfo
const aiDisabled = ref(false)
function handleSelect() { }
function handleSelect(key: string) {
userStore.updateTenantId(key)
location.reload()
}
function logIt(e) {
// console.log('e:', e)
@ -52,6 +44,23 @@ function logOut() {
(popRef.value as any).setShow(false)
emit('logout')
}
const currentCompanyName = computed(() => {
const tenantList = useInfo.tenantList
const currentId = userStore.getTenantId
const current = tenantList.find(item => item.id === currentId)
return current.name || 'name'
})
const options = computed(() => {
const tenantList = useInfo.tenantList
return tenantList.map((item) => {
return {
label: item.name,
key: item.id,
}
})
})
</script>
<template>
@ -61,21 +70,21 @@ function logOut() {
>
<template #trigger>
<div class="setting">
<span>柳小树</span>
<span>{{ useInfo.username }}</span>
<SvgIcon style="margin-left: 6px;" :name="iconName" size="14" />
</div>
</template>
<div class="container">
<div class="header">
<n-avatar round size="medium" />
<n-avatar :src="getImgUrl(useInfo.usericon)" round size="medium" />
<div style="margin-left: 10px">
<span style="display: block; font-size: 20px">阿飞</span>
<span style="display: block; font-size: '20px'">北京李白有限科技有限公司</span>
<span style="display: block; font-size: 20px">{{ useInfo.username }}</span>
<span style="display: block; font-size: '20px'">{{ useInfo.departname }}</span>
</div>
</div>
<n-dropdown placement="left-start" trigger="hover" :options="options" @select="handleSelect">
<div class="trigger">
<span>北京李白有限科技有限公司</span>
<span>{{ currentCompanyName }}</span>
<span>icon</span>
</div>
</n-dropdown>

@ -6,8 +6,8 @@ import UserSettings from './UserSettings.vue'
import QuillModal from './QuillModal.vue'
import ShortcutModal from './ShortcutModal.vue'
import RecycleModal from './RecycleModal.vue'
import { useUserStore } from '@/store/modules/user'
import { useUser } from '@/store/modules/user'
import { getImgUrl } from '@/utils/urlUtils'
export default defineComponent({
name: 'PageHeader',
@ -22,10 +22,12 @@ export default defineComponent({
},
emits: ['update:collapsed'],
setup() {
const userStore = useUserStore()
const message = useMessage()
const dialog = useDialog()
const userStore = useUser()
const useInfo = userStore.getUserInfo
const name = ''
const state = reactive({
@ -127,6 +129,8 @@ export default defineComponent({
quillHandler,
shortcutHandler,
recycleHandler,
useInfo,
getImgUrl,
}
},
})
@ -154,12 +158,7 @@ export default defineComponent({
</div>
<!-- 个人中心 -->
<div class="layout-header-trigger layout-header-trigger-min">
<div class="avatar">
<n-avatar round>
{{ username }}
<template #icon />
</n-avatar>
</div>
<n-avatar :src="getImgUrl(useInfo.usericon)" round />
</div>
<!-- 设置 -->
<UserSettings @logout="doLogout" />

@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import { store } from '@/store'
import { getIzCustomtypeList, getIzProjectList, getIzSearchList, getIzShowList, getIzfiled17List, getIzfiled2List, getIzfiled3List, getIzfiled6List, getIzfirmList, getIzproductnameList, getIzsSearchManager, getIztaskrromList, getIztaskstatusList, getIzvisitproList, getPersonList, getPictureTypeList, getPlanList, getRegionList, getTFList } from '@/api/dictionary'
import { getIzCustomtypeList, getIzProjectList, getIzShowList, getIzcustomlevel, getIzfirmList, getIzproductnameList, getIzprojecttypeList, getIztaskrromList, getIztaskstatusList, getIzvisitcityList, getIzvisitproList, getPersonList, getPictureTypeList, getPlanList, getRegionList, getTFList, getizcustomnameList } from '@/api/dictionary'
export interface DictionaryState {
regionList: any
@ -9,19 +9,17 @@ export interface DictionaryState {
planList: any
tfList: any
izShowList: any
izSearchList: any
izsSearchManagerList: any
izProjectList: any
izCustomtypeList: any
iztaskrromList: any
iztaskstatusList: any
izvisitproList: any
izfirmList: any
izproductnameList: any
izfiled2List: any
izfiled3List: any
izfiled6List: any
izfiled17List: any
izCustomtypeList: any
izcustomnameList: any
izcustomlevelList: any
izizprojecttypeList: any
izvisitcityList: any
}
export const useDictionaryStore = defineStore({
@ -33,19 +31,17 @@ export const useDictionaryStore = defineStore({
personList: null,
planList: null,
izShowList: null,
izSearchList: null,
izsSearchManagerList: null,
izProjectList: null,
izCustomtypeList: null,
iztaskrromList: null,
iztaskstatusList: null,
izvisitproList: null,
izfirmList: null,
izproductnameList: null,
izfiled3List: null,
izfiled6List: null,
izfiled17List: null,
izfiled2List: null,
izcustomnameList: null,
izCustomtypeList: null,
izcustomlevelList: null,
izizprojecttypeList: null,
izvisitcityList: null,
}),
getters: {
getRegionList: (state) => {
@ -63,18 +59,9 @@ export const useDictionaryStore = defineStore({
getizshow: (state) => {
return state.izShowList
},
getizsearch: (state) => {
return state.izSearchList
},
getizsearchmanager: (state) => {
return state.izsSearchManagerList
},
getizproject: (state) => {
return state.izProjectList
},
getizcustomtype: (state) => {
return state.izCustomtypeList
},
getiztaskrrom: (state) => {
return state.iztaskrromList
},
@ -90,17 +77,17 @@ export const useDictionaryStore = defineStore({
getizproductname: (state) => {
return state.izproductnameList
},
getizfiled3: (state) => {
return state.izfiled3List
getizcustomname: (state) => {
return state.izcustomnameList
},
getizfiled6: (state) => {
return state.izfiled6List
getizcustomtype: (state) => {
return state.izCustomtypeList
},
getizfiled17: (state) => {
return state.izfiled17List
getizcustomlevel: (state) => {
return state.izcustomlevelList
},
getizfiled2: (state) => {
return state.izfiled2List
getizizprojecttype: (state) => {
return state.izizprojecttypeList
},
},
actions: {
@ -116,7 +103,7 @@ export const useDictionaryStore = defineStore({
// 获取图片类型列表
async fetchPictureTypeList() {
const list = await getPictureTypeList()
this.pictureTypeList = generateOptions(list, 'id', 'typename')
this.pictureTypeList = generateOptions2(list, 'id', 'typename')
return this.pictureTypeList
},
// 获取提报人列表
@ -134,39 +121,20 @@ export const useDictionaryStore = defineStore({
// 获取图片真假原因
async fetchTFList() {
const list = await getTFList()
this.settfList(list)
return list
this.tfList = generateOptions2(list)
return this.tfList
},
// 分类列表
async fetchIzShowList() {
const list = await getIzShowList()
this.izShowList = generateOptions(list, 'id', 'classname')
this.izShowList = generateOptions2(list, 'id', 'classname')
return this.izShowList
},
async fetchIzSearchList() {
const list = await getIzSearchList()
// TODO
this.izSearchList = list
return this.izSearchList
},
async fetchIzsSearchManagerList() {
const list = await getIzsSearchManager()
// TODO
this.izsSearchManagerList = list
return this.izsSearchManagerList
},
async fetchIzProjectList() {
const list = await getIzProjectList()
// TODO
this.izProjectList = generateOptions(list)
this.izProjectList = generateOptions(list, 'id', 'categoryname')
return this.izProjectList
},
async fetchIzCustomtypeList() {
const list = await getIzCustomtypeList()
// TODO
this.izCustomtypeList = generateOptions(list)
return this.izCustomtypeList
},
async fetchIztaskrromList() {
const list = await getIztaskrromList('1')
this.izCustomtypeList = generateOptions(list)
@ -179,8 +147,7 @@ export const useDictionaryStore = defineStore({
},
async fetchIzvisitproList() {
const list = await getIzvisitproList()
// TODO
this.izvisitproList = generateOptions(list)
this.izvisitproList = generateOptions(list, 'id', 'proname')
return this.izvisitproList
},
async fetchIzfirmList() {
@ -193,25 +160,30 @@ export const useDictionaryStore = defineStore({
this.izproductnameList = generateOptions(list)
return this.izproductnameList
},
async fetchIzfiled2List() {
const list = await getIzfiled2List('1')
this.izfiled2List = generateOptions(list)
return this.izfiled2List
async fetchizcustomnameList() {
const list = await getizcustomnameList('1')
this.izcustomnameList = generateOptions(list)
return this.izcustomnameList
},
async fetchIzCustomtypeList() {
const list = await getIzCustomtypeList()
this.izCustomtypeList = generateOptions(list)
return this.izCustomtypeList
},
async fetchIzfiled3List() {
const list = await getIzfiled3List('1')
this.izfiled3List = generateOptions(list)
return this.izfiled3List
async fetchIzcustomlevelList() {
const list = await getIzcustomlevel('1')
this.izcustomlevelList = generateOptions(list)
return this.izcustomlevelList
},
async fetchIzfiled6List() {
const list = await getIzfiled6List('1')
this.izfiled6List = generateOptions(list)
return this.izfiled6List
async fetchizizprojecttypeList() {
const list = await getIzprojecttypeList('1')
this.izizprojecttypeList = generateOptions(list)
return this.izizprojecttypeList
},
async fetchIzfiled17List() {
const list = await getIzfiled17List('1')
this.izfiled17List = generateOptions(list)
return this.izfiled17List
async fetchizvisitcityList() {
const list = await getIzvisitcityList()
this.izvisitcityList = generateOptions(list)
return this.izvisitcityList
},
},
})
@ -221,9 +193,22 @@ export function useDictionary() {
return useDictionaryStore(store)
}
// label和value都是name,不用id
function generateOptions(list: any[], idkey: string = 'id', namekey: string = 'name') {
const items = list || []
return items.map((item) => {
return {
label: item[namekey] || 'todo',
value: item[namekey] || 'todo',
}
})
}
// label是name,value是id
function generateOptions2(list: any[], idkey: string = 'id', namekey: string = 'name') {
const items = list || []
return items.map((item) => {
return {
label: item[namekey] || 'todo',

@ -88,11 +88,15 @@ export const useUserStore = defineStore({
this.captchaToken = token
},
// TODO:这样不合理
setTenantId(id: string) {
this.tenantId = id
},
updateTenantId(id: string) {
this.tenantId = id
storage.set(TENANT_ID, id)
},
// 获取验证码token
async getCaptchaToken(type: 'math' | 'char') {
const result = await getCaptchaToken(type)
@ -117,7 +121,7 @@ export const useUserStore = defineStore({
if (code === ResultEnum.SUCCESS) {
const ex = 7 * 24 * 60 * 60
// TODO:不合理
// 默认设置为第一个租户
const firstTenant = data.tenantList.length > 0 ? data.tenantList[0] : null
const tenantId = firstTenant ? firstTenant.id : ''
storage.set(CURRENT_USER, data, ex)

@ -3,6 +3,7 @@ import { format } from 'date-fns'
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm'
const DATE_FORMAT = 'YYYY-MM-DD '
const DATE_FORMAT_HMS = 'yyyy-MM-dd HH:mm:ss'
const DATA_FORMAT_2 = 'yyyy/MM/dd'
export function formatToDateTime(date: Date | number, formatStr = DATE_TIME_FORMAT): string {
return format(date, formatStr)
@ -12,6 +13,10 @@ export function formatToDate(date: Date | number, formatStr = DATE_FORMAT): stri
return format(date, formatStr)
}
export function formatToDate2(date: Date | number, formatStr = DATA_FORMAT_2): string {
return format(date, formatStr)
}
export function formatToDateHMS(date: Date | number, formatStr = DATE_FORMAT_HMS) {
return format(date, formatStr)
}

@ -1,3 +1,5 @@
import { useGlobSetting } from '@/hooks/setting'
/**
* URL
* @param baseUrl url
@ -22,3 +24,11 @@ export function setObjToUrlParams(baseUrl: string, obj: object): string {
return url
}
const globSetting = useGlobSetting()
export function getImgUrl(url: string): string {
const { imgUrl } = globSetting
const fullurl = /(^http|https:\/\/)/g.test(url) ? url : `${imgUrl}${url}`
return fullurl
}

@ -0,0 +1,183 @@
<script lang="ts" setup>
import { computed, onBeforeMount, ref } from 'vue'
import { useDictionary } from '@/store/modules/dictonary'
const emit = defineEmits<{
(e: 'commit', value: any, isOther: boolean)
}>()
const dictonaryStore = useDictionary()
const show = ref(false)
const cardStyle = {
'width': '520px',
'--n-padding-bottom': '10px',
'--n-padding-left': '0px',
}
function showModal() {
show.value = true
}
function closeModal() {
show.value = false
}
defineExpose({
showModal,
})
const backOptions = ref<any[]>([])
const reasonOptions = ref<any[]>([])
const selectBackId = ref(null)
const selectRejectId = ref(null)
const otherValue = ref(null)
const showOther = computed(() => {
return selectRejectId.value === 'other'
})
const comomitValue = computed(() => {
return selectRejectId.value === 'other' ? otherValue.value : selectRejectId.value
})
async function handleSumbit(e: MouseEvent) {
e.preventDefault()
closeModal()
emit('commit', comomitValue, selectRejectId.value === 'other')
}
onBeforeMount(async () => {
const tfList = await dictonaryStore.fetchTFList()
reasonOptions.value = tfList.map((item) => {
return {
label: item.name,
value: item.id,
}
})
//
reasonOptions.value.push({
label: '其他',
value: 'other',
})
})
</script>
<template>
<n-modal v-model:show="show" transform-origin="center">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<div class="wrapper-header">
<span class="wrapper-left">选择不通过原因</span>
<div class="wrapper-right">
<div class="wrapper-right-close" @pointerdown="closeModal">
<div class="wrapper-right-icon" />
</div>
</div>
</div>
<div class="wrapper-content">
<span>处理方式</span>
<n-select v-model:value="selectBackId" style="margin-top: 10px;" :options="backOptions" />
</div>
<div class="wrapper-content">
<span>不通过原因</span>
<n-select v-model:value="selectRejectId" style="margin-top: 10px;" :options="reasonOptions" />
<n-input v-show="showOther" v-model:value="otherValue" type="textarea" placeholder="备注内容" style="margin-top: 10px;" />
</div>
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit">
确认
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
取消
</n-button>
</div>
</template>
</n-card>
</n-modal>
</template>
<style lang="less" scoped>
.wrapper {
&-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
}
&-left {
font-weight: bold;
font-size: 16px;
}
&-right {
&-close {
width: 18px;
height: 18px;
cursor: pointer;
}
&-icon {
background: #000;
display: inline-block;
width: 18px;
height: 1px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
margin-bottom: 8px;
&:after {
content: '';
display: block;
width: 18px;
height: 1px;
background: #000;
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
}
}
}
&-content {
padding: 18px 10px;
}
&-footer {
display: flex;
justify-content: flex-end;
}
&-info {
font-weight: bold;
position: relative;
&:before {
background-color: #1980ff;
content: '';
width: 5px;
border-radius: 2px;
top: 0;
bottom: 0;
position: absolute;
}
}
}
::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {
border: 0px;
}
::v-deep(.n-card > .n-card-header) {
--n-padding-top: 0px;
--n-padding-bottom: 12px;
}
::v-deep(.n-divider:not(.n-divider--vertical)) {
margin-top: 0px;
margin-bottom: 0px;
}
</style>

@ -1,8 +1,13 @@
<script lang="ts" setup>
import { ref } from 'vue'
const emit = defineEmits<{
(e: 'reject', params: any)
(e: 'viewrepeat')
}>()
const cardStyle = {
'width': '620px',
'width': '450px',
'--n-padding-bottom': '10px',
'--n-padding-left': '0px',
}
@ -18,10 +23,12 @@ function closeModal() {
}
async function reject() {
//
emit('reject', { a: 'todo' })
closeModal()
}
async function viewRepeat(e: MouseEvent) {
emit('viewrepeat')
e.preventDefault()
closeModal()
}
@ -35,28 +42,29 @@ defineExpose({
<n-modal v-model:show="show" transform-origin="center">
<n-card :style="cardStyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<div class="close" @click="closeModal">
<SvgIcon size="24" name="clear" />
</div>
<div class="wrapper-header">
<span>任务小结重复任务</span>
<span><span>18</span></span>
<span style="font-weight: bold;">任务小结重复任务</span>
<span><font class="count">18</font></span>
</div>
<div class="wrapper-content">
<n-scrollbar style="max-height: 200px;">
<div class="item">
<img>
<n-grid x-gap="12" y-gap="24" :cols="12">
<n-gi span="2">
<span class="wrapper-content-detail-right-position">任务小结内容</span>
<div v-for="i in 2" :key="i" class="item">
<div class="imgwrapper" />
<n-grid x-gap="12" y-gap="0" :cols="12">
<n-gi span="4">
<span style="color:#8b8d8f;">任务小结内容:</span>
</n-gi>
<n-gi span="10">
<span
class="wrapper-content-detail-right-position"
>今日去拜访中日友好医院今日去拜访中日友好医院今日去拜访中日友好医院今日去拜访中日友好医院</span>
<n-gi span="8">
<span>今日去拜访中日友好医院今日去拜访中日友好医院今日去</span>
</n-gi>
<n-gi span="2">
<span class="wrapper-content-detail-right-position">任务重复数量</span>
<n-gi span="4">
<span style="color:#8b8d8f;">任务重复数量</span>
</n-gi>
<n-gi span="10">
<span class="wrapper-content-detail-right-position">共18</span>
<n-gi span="8">
<span><font class="count">18</font></span>
</n-gi>
</n-grid>
</div>
@ -77,6 +85,13 @@ defineExpose({
position: relative;
flex-direction: column;
.close{
position:absolute;
right: 0px;
top:-45px;
cursor: pointer;
}
&-header {
display: flex;
flex-direction: column;
@ -92,17 +107,35 @@ defineExpose({
background-color: #FFF;
padding: 16px;
.imgwrapper {
width: 160px;
height: 70px;
margin-right: 20px;
border-radius: 8px;
background-image: url('../../../assets/images/test.png');
background-repeat: no-repeat;
background-size: cover;
}
.item {
display: flex;
padding: 20px 0px;
border-bottom: 1px solid #e4e6eb;
}
.footer {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
}
.count {
color: #6684fa;
font-weight: bold;
margin: 0px 5px
}
}
::v-deep(.n-card.n-card--content-segmented > .n-card__content:not(:first-child)) {

@ -1,9 +1,9 @@
<script lang="ts" setup>
import { computed, h, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { computed, h, reactive, ref, unref } from 'vue'
import { NDataTable, useDialog } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import Action from '../comp/Action.vue'
import ConfrimModal from '@/views/task/modal/ConfrimModal.vue'
import { RejectModal } from './index'
import type { RowData } from '@/config/final'
import { getFinalList } from '@/api/final'
import type { ApprovalParam } from '/#/api'
@ -13,7 +13,7 @@ const emit = defineEmits<{
(e: 'commit', columns: any[])
}>()
const show = ref(false)
const show = ref(true)
function showModal() {
show.value = true
@ -86,13 +86,14 @@ const columns: DataTableColumns<RowData> = [
{
id: row.id,
status: row.states,
actionHandler,
trigger: actionHandler,
},
)
},
},
]
const rejectModalRef = ref(null)
const columnsRef = ref(columns)
const tableRef = ref<InstanceType<typeof NDataTable>>()
const rowKey = (row: RowData) => row.id
@ -145,7 +146,7 @@ function actionHandler(action: any) {
approvalHandler()
break
case 'reject':
// showModal(confrimModalRef)
(rejectModalRef.value as any).showModal()
break
default:
break
@ -202,35 +203,38 @@ query(pagination.page, pagination.pageSize)
</script>
<template>
<n-modal v-model:show="show" transform-origin="center">
<n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<span class="wrapper-title">自定义显示列</span>
<div class="wrapper-bar">
<div class="wrapper-info">
<span :style="{ 'margin-left': '18px' }">字段信息</span>
<div>
<n-modal v-model:show="show" transform-origin="center">
<n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper">
<span class="wrapper-title">重复任务</span>
<div class="wrapper-bar">
<div class="wrapper-info">
<span :style="{ 'margin-left': '18px' }">任务信息</span>
</div>
</div>
<div class="wrapper-content">
<NDataTable
ref="tableRef" remote :columns="columnsRef" :scroll-x="1250" :max-height="maxHeight" :data="tableData"
:loading="loading" :pagination="pagination" :row-key="rowKey" @update:page="handlePageChange"
@update:checked-row-keys="handleCheck"
/>
</div>
</div>
<div class="wrapper-content">
<NDataTable
ref="tableRef" remote :columns="columnsRef" :scroll-x="1250" :max-height="maxHeight" :data="tableData"
:loading="loading" :pagination="pagination" :row-key="rowKey" @update:page="handlePageChange"
@update:checked-row-keys="handleCheck"
/>
</div>
</div>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit">
确认
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
取消
</n-button>
</div>
</template>
</n-card>
</n-modal>
<template #footer>
<div class="wrapper-footer">
<n-button type="info" @click="handleSumbit">
确认
</n-button>
<n-button secondary style="margin-left:15px" @click="closeModal">
取消
</n-button>
</div>
</template>
</n-card>
</n-modal>
<RejectModal ref="rejectModalRef" @commit="rejectHandler" />
</div>
</template>
<style lang="less" scoped>
@ -252,6 +256,7 @@ query(pagination.page, pagination.pageSize)
&-content {
flex: auto;
background: #FFF;
margin-top: 20px;
}
&-footer {
@ -277,6 +282,7 @@ query(pagination.page, pagination.pageSize)
.cardstyle {
width: 820px;
height: 800px;
--n-padding-bottom: 20px;
--n-padding-left: 24px;
}

@ -3,5 +3,6 @@ import ImportExcelModal from './ImportExcelModal.vue'
import RepeatModal from './RepeatModal.vue'
import RepeatTaskTableModal from './RepeatTaskTableModal.vue'
import Action from './Action.vue'
import RejectModal from './RejectModal.vue'
export { CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal, Action }
export { CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal, Action, RejectModal }

@ -2,8 +2,7 @@
import { computed, h, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { NDataTable, useDialog } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import { Action, CustomTabelModal, ImportExcelModal, RepeatModal } from '../comp'
import ConfrimModal from '@/views/task/modal/ConfrimModal.vue'
import { Action, CustomTabelModal, ImportExcelModal, RejectModal, RepeatModal, RepeatTaskTableModal } from '../comp'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset } from '@/utils/domUtils'
import type { RowData } from '@/config/final'
@ -67,7 +66,7 @@ const columns: DataTableColumns<RowData> = [
{
id: row.id,
status: row.states,
actionHandler,
trigger: actionHandler,
},
)
},
@ -152,8 +151,9 @@ query(pagination.page, pagination.pageSize)
const customTabelRef = ref(null)
const importExcelRef = ref(null)
const confrimModalRef = ref(null)
const rejectModalRef = ref(null)
const repeatModalRef = ref(null)
const repeatTaskTableModalRef = ref(null)
function showModal(modalRef: any) {
const modal = unref(modalRef)! as any
@ -221,7 +221,7 @@ function actionHandler(action: any) {
approvalHandler()
break
case 'reject':
showModal(confrimModalRef)
showModal(rejectModalRef)
break
default:
break
@ -283,6 +283,9 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
<SvgIcon size="32" name="magnifying" />
</div>
<div>
<n-button class="xjcc" text @click="showModal(repeatModalRef)">
小结查重
</n-button>
<div class="btn">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" />
批量审批
@ -292,7 +295,7 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
placement="bottom-start" trigger="click"
>
<template #trigger>
<SvgIcon size="20" name="more-ver" />
<SvgIcon style="cursor: pointer;" size="20" name="more-ver" />
</template>
<ul class="wrapper-header-action">
<li @click="importHandler">
@ -334,8 +337,9 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
<CustomTabelModal ref="customTabelRef" @commit="commitHandler" />
<ImportExcelModal ref="importExcelRef" :on-success="sucessHandler" :header-config="headRules" />
<ConfrimModal ref="confrimModalRef" @commit="rejectHandler" />
<RepeatModal ref="repeatModalRef" />
<RejectModal ref="rejectModalRef" @commit="rejectHandler" />
<RepeatModal ref="repeatModalRef" @reject="showModal(rejectModalRef)" @viewrepeat="showModal(repeatTaskTableModalRef)" />
<RepeatTaskTableModal ref="repeatTaskTableModalRef" />
</div>
</template>
@ -364,6 +368,12 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
align-items: center;
}
.xjcc{
font-weight: bold;
color: #6a80fc;
margin-right: 20px;
}
.title {
color: #507afd;
font-weight: bold;

@ -92,14 +92,22 @@ configStore.$subscribe(() => {
asideVisible[key] = showKeys.includes(key) && config[key] === 'Y'
})
const items = showKeys.map((key: string) => {
const str = key.toLowerCase()
const items = showKeys.reduce((acc, key) => {
const { inFilterList } = asideMap[key]
return {
key: str,
config: asideMap[str],
if (inFilterList !== false) {
const str = key.toLowerCase()
const o = {
key: str,
config: asideMap[str],
}
return [...acc, o]
}
})
else {
return acc
}
}, [])
showItems.value = items
})

@ -4,7 +4,7 @@ import { computed, ref } from 'vue'
import { useElementHover } from '@vueuse/core'
import { useThemeVars } from 'naive-ui'
import { upload } from '@/api/home/main'
import { useGlobSetting } from '@/hooks/setting'
import { getImgUrl } from '@/utils/urlUtils'
defineOptions({ name: 'Upload' })
@ -16,8 +16,6 @@ const emit = defineEmits<{
(e: 'update:value', value: string): void
}>()
const globSetting = useGlobSetting()
const figureUrl = ref(props.value)
async function customRequest(data: UploadCustomRequestOptions) {
@ -27,11 +25,6 @@ async function customRequest(data: UploadCustomRequestOptions) {
emit('update:value', result.data)
}
function getImgUrl(url: string): string {
const { imgUrl } = globSetting
return /(^http|https:\/\/)/g.test(url) ? url : `${imgUrl}${url}`
}
const showFigure = computed(() => {
return figureUrl.value !== ''
})

@ -0,0 +1,62 @@
<script lang="ts" setup>
import { onBeforeMount, ref } from 'vue'
import type { FormItemRule, FormRules } from 'naive-ui'
import { useDictionary } from '@/store/modules/dictonary'
const props = defineProps<{
value: string[] | null
label: string
}>()
const emit = defineEmits<{
(e: 'update:value', value: string[]): void
}>()
const formValue = ref({
plans: props.value,
})
const rules: FormRules = {
plans: [
{
required: true,
type: 'array',
validator(rule: FormItemRule, value: string[]) {
if (value == null || value.length === 0)
return new Error('请选择拜访客户级别')
return true
},
trigger: ['blur', 'change'],
},
],
}
const options = ref([])
const configStore = useDictionary()
const labStyle = {
fontWeight: 'bold',
}
onBeforeMount(async () => {
const list = await configStore.fetchIzcustomlevelList()
options.value = list
})
function onChange(value: Array<string>) {
emit('update:value', value)
}
</script>
<template>
<n-form :model="formValue" style="padding: 0px 10px;" :rules="rules">
<n-form-item :label="label" path="plans" :label-style="labStyle">
<n-select
v-model:value="formValue.plans" :max-tag-count="2" placeholder="请选择拜访客户级别" multiple
:options="options" @update:value="onChange"
/>
</n-form-item>
</n-form>
</template>
<style lang="less" scoped></style>

@ -0,0 +1,62 @@
<script lang="ts" setup>
import { onBeforeMount, ref } from 'vue'
import type { FormItemRule, FormRules } from 'naive-ui'
import { useDictionary } from '@/store/modules/dictonary'
const props = defineProps<{
value: string[] | null
label: string
}>()
const emit = defineEmits<{
(e: 'update:value', value: string[]): void
}>()
const formValue = ref({
plans: props.value,
})
const rules: FormRules = {
plans: [
{
required: true,
type: 'array',
validator(rule: FormItemRule, value: string[]) {
if (value == null || value.length === 0)
return new Error('请选择拜访客户名称')
return true
},
trigger: ['blur', 'change'],
},
],
}
const options = ref([])
const configStore = useDictionary()
const labStyle = {
fontWeight: 'bold',
}
onBeforeMount(async () => {
const list = await configStore.fetchizcustomnameList()
options.value = list
})
function onChange(value: Array<string>) {
emit('update:value', value)
}
</script>
<template>
<n-form :model="formValue" style="padding: 0px 10px;" :rules="rules">
<n-form-item :label="label" path="plans" :label-style="labStyle">
<n-select
v-model:value="formValue.plans" :max-tag-count="2" placeholder="请选择拜访客户名称" multiple
:options="options" @update:value="onChange"
/>
</n-form-item>
</n-form>
</template>
<style lang="less" scoped></style>

@ -0,0 +1,62 @@
<script lang="ts" setup>
import { onBeforeMount, ref } from 'vue'
import type { FormItemRule, FormRules } from 'naive-ui'
import { useDictionary } from '@/store/modules/dictonary'
const props = defineProps<{
value: string[] | null
label: string
}>()
const emit = defineEmits<{
(e: 'update:value', value: string[]): void
}>()
const formValue = ref({
plans: props.value,
})
const rules: FormRules = {
plans: [
{
required: true,
type: 'array',
validator(rule: FormItemRule, value: string[]) {
if (value == null || value.length === 0)
return new Error('请选择拜访客户类型')
return true
},
trigger: ['blur', 'change'],
},
],
}
const options = ref([])
const configStore = useDictionary()
const labStyle = {
fontWeight: 'bold',
}
onBeforeMount(async () => {
const list = await configStore.fetchIzCustomtypeList()
options.value = list
})
function onChange(value: Array<string>) {
emit('update:value', value)
}
</script>
<template>
<n-form :model="formValue" style="padding: 0px 10px;" :rules="rules">
<n-form-item :label="label" path="plans" :label-style="labStyle">
<n-select
v-model:value="formValue.plans" :max-tag-count="2" placeholder="请选择拜访客户类型" multiple
:options="options" @update:value="onChange"
/>
</n-form-item>
</n-form>
</template>
<style lang="less" scoped></style>

@ -0,0 +1,62 @@
<script lang="ts" setup>
import { onBeforeMount, ref } from 'vue'
import type { FormItemRule, FormRules } from 'naive-ui'
import { useDictionary } from '@/store/modules/dictonary'
const props = defineProps<{
value: string[] | null
label: string
}>()
const emit = defineEmits<{
(e: 'update:value', value: string[]): void
}>()
const formValue = ref({
plans: props.value,
})
const rules: FormRules = {
plans: [
{
required: true,
type: 'array',
validator(rule: FormItemRule, value: string[]) {
if (value == null || value.length === 0)
return new Error('请选择拜访项目类别')
return true
},
trigger: ['blur', 'change'],
},
],
}
const options = ref([])
const configStore = useDictionary()
const labStyle = {
fontWeight: 'bold',
}
onBeforeMount(async () => {
const list = await configStore.fetchizizprojecttypeList()
options.value = list
})
function onChange(value: Array<string>) {
emit('update:value', value)
}
</script>
<template>
<n-form :model="formValue" style="padding: 0px 10px;" :rules="rules">
<n-form-item :label="label" path="plans" :label-style="labStyle">
<n-select
v-model:value="formValue.plans" :max-tag-count="2" placeholder="请选择拜访项目类别" multiple
:options="options" @update:value="onChange"
/>
</n-form-item>
</n-form>
</template>
<style lang="less" scoped></style>

@ -0,0 +1,62 @@
<script lang="ts" setup>
import { onBeforeMount, ref } from 'vue'
import type { FormItemRule, FormRules } from 'naive-ui'
import { useDictionary } from '@/store/modules/dictonary'
const props = defineProps<{
value: string[] | null
label: string
}>()
const emit = defineEmits<{
(e: 'update:value', value: string[]): void
}>()
const formValue = ref({
plans: props.value,
})
const rules: FormRules = {
plans: [
{
required: true,
type: 'array',
validator(rule: FormItemRule, value: string[]) {
if (value == null || value.length === 0)
return new Error('请选择发布地区')
return true
},
trigger: ['blur', 'change'],
},
],
}
const options = ref([])
const configStore = useDictionary()
const labStyle = {
fontWeight: 'bold',
}
onBeforeMount(async () => {
const list = await configStore.fetchizvisitcityList()
options.value = list
})
function onChange(value: Array<string>) {
emit('update:value', value)
}
</script>
<template>
<n-form :model="formValue" style="padding: 0px 10px;" :rules="rules">
<n-form-item :label="label" path="plans" :label-style="labStyle">
<n-select
v-model:value="formValue.plans" :max-tag-count="2" placeholder="请选择发布地区" multiple
:options="options" @update:value="onChange"
/>
</n-form-item>
</n-form>
</template>
<style lang="less" scoped></style>

@ -8,18 +8,16 @@ import PictureUploadVue from './PictureUpload.vue'
import SimilarityVue from './Similarity.vue'
import PlaceHolderVue from './PlaceHolder.vue'
import IzShowVue from './IzShow.vue'
import IzSearchVue from './IzSearch.vue'
import IzSearchManagerVue from './IzSearchManager.vue'
import IzProjectVue from './IzProject.vue'
import IztaskrromVue from './Iztaskrrom.vue'
import IztaskstatusVue from './Iztaskstatus.vue'
import IzvisitproVue from './Izvisitpro.vue'
import IzfirmVue from './Izfirm.vue'
import Izfiled2Vue from './Izfiled2.vue'
import Izfiled3Vue from './Izfiled3.vue'
import Izfiled6Vue from './Izfiled6.vue'
import Izfiled17Vue from './Izfiled17.vue'
import IzCustomlevel from './IzCustomlevel.vue'
import IzCustomname from './IzCustomname.vue'
import IzCustomtype from './IzCustomtype.vue'
import IzProductVue from './IzProduct.vue'
import IzCustomtypesVue from './IzCustomtypes.vue'
import IzProjecttype from './IzProjecttype.vue'
import IzVisitcity from './IzVisitcity.vue'
export { IzCustomtypesVue, Izfiled2Vue, Izfiled3Vue, Izfiled6Vue, Izfiled17Vue, IzfirmVue, IzProductVue, IzvisitproVue, IztaskstatusVue, IztaskrromVue, IzCustomTypeVue, IzProjectVue, IzShowVue, IzSearchVue, IzSearchManagerVue, PictureDownloadVue, PictureUploadVue, PlaceHolderVue, RegionVue, SimilarityVue, ReportUserVue, PlanVue, PictureTypeVue, TimeVue }
export { IzProjecttype, IzVisitcity, IzCustomlevel, IzCustomtype, IzCustomname, IzfirmVue, IzProductVue, IzvisitproVue, IztaskstatusVue, IztaskrromVue, IzProjectVue, IzShowVue, PictureDownloadVue, PictureUploadVue, PlaceHolderVue, RegionVue, SimilarityVue, ReportUserVue, PlanVue, PictureTypeVue, TimeVue }

@ -148,7 +148,7 @@ const operatorOptions = [
},
{
label: '不等于',
value: 'notequal',
value: 'notEq',
},
]

@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, onUpdated, reactive, ref, watch } from 'vue'
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import Masonry from 'masonry-layout'
import { useInfiniteScroll } from '@vueuse/core'
import { debounce, pickBy } from 'lodash-es'
@ -17,6 +17,7 @@ import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg'
import { useConfig } from '@/store/modules/asideConfig'
import emitter from '@/utils/mitt'
import { getImgUrl } from '@/utils/urlUtils'
const deviceHeight = ref(600)
let _masonry: null | Masonry = null
@ -136,6 +137,8 @@ async function featchList() {
const list = data.map((item) => {
return {
imgUrl: item.imgurl,
upname: item.upname,
ocrPictureclass: item.ocrPictureclass,
}
})
@ -170,18 +173,16 @@ async function oneCheck() {
modal.showModal()
}
async function commitHandler(value) {
async function commitHandler(settingParam) {
const contentParams = {
search_month: timeRange.value,
search_history: 0,
}
const asideVal = configStore.getAsideValue
const asideParam = pickBy(asideVal, notEmpty)
const finalParam = { ...contentParams, ...asideParam }
// TODO:
const finalParam = { ...contentParams, ...asideVal }
finalParam.buessinessno = settingParam.packagename
finalParam.search_history = settingParam.comparehistory ? 1 : 0
// TODO
oneClickCheck(finalParam)
}
@ -197,15 +198,18 @@ onUnmounted(() => {
emitter.off('filter', refreshHandler)
})
watch(() => configStore.asideValue, () => {
watch(timeRange, () => {
refreshHandler()
})
watch(() => configStore.asideValue, (newVal, oldVal) => {
refreshHandler()
}, { deep: true })
async function refreshHandler(filterParams?: any) {
async function refreshHandler() {
pagination.pageNo = 1
pagination.pageSize = 30
listData.value.length = 0
loading.value = true
const contentParams = {
@ -213,6 +217,7 @@ async function refreshHandler(filterParams?: any) {
search_history: 0,
}
const filterParams = unref(configStore.getAsideValue)
const result = await getPictureList({ ...pagination, ...contentParams, ...filterParams })
const { data, pageCount } = result
pagination.pageNo += 1
@ -263,12 +268,12 @@ async function refreshHandler(filterParams?: any) {
>
<div class="wrapper-content-item-info">
<div class="wrapper-content-item-info-left">
<n-avatar class="wrapper-content-item-info-avatar" round />
<span>张一元</span>
<n-avatar :src="getImgUrl(item.uphead)" class="wrapper-content-item-info-avatar" round />
<span>{{ item.upname }}</span>
</div>
<div class="wrapper-content-item-info-right">
<span :style="{ marginRight: '5px' }">分类</span>
<span>自提报</span>
<span>{{ item.ocrPictureclass?.classname }}</span>
</div>
</div>
</div>

@ -2,6 +2,7 @@
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { useDialog } from 'naive-ui'
import ConfrimModal from '../modal/ConfrimModal.vue'
import BatchModal from '../modal/BatchModal.vue'
import TaskTable from './TaskTable.vue'
import PictureTable from './PictureTable.vue'
import { useTask } from '@/store/modules/task'
@ -105,9 +106,10 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
}
const confrimModalRef = ref(null)
const batchModalRef = ref(null)
function showModal() {
const modal = unref(confrimModalRef)! as any
function showModal(modalRef: any) {
const modal = unref(modalRef)! as any
modal.showModal()
}
@ -167,7 +169,7 @@ onUnmounted(() => {
</template>
返回
</n-button>
<div style="cursor: pointer;margin-left: 16px;" @click="showModal">
<div style="cursor: pointer;margin-left: 16px;" @click="showModal(confrimModalRef)">
<SvgIcon width="64" height="28" name="a1" />
</div>
<SvgIcon size="24" name="vs" />
@ -186,7 +188,7 @@ onUnmounted(() => {
<n-scrollbar style="max-height: 100%;">
<div class="header">
<span>相似图片(9)</span>
<SvgIcon style="margin-right: 20px;" name="max" size="24" />
<SvgIcon style="margin-right: 20px;cursor: pointer;" name="max" size="24" @click="showModal(batchModalRef)" />
</div>
<div class="list">
<div v-for="(item, index) in taskDetailPictureList" :key="index" class="item">
@ -223,6 +225,7 @@ onUnmounted(() => {
<n-tab-pane name="history" tab="历史审查" />
</n-tabs>
<ConfrimModal ref="confrimModalRef" @commit="rejectHandler" />
<BatchModal ref="batchModalRef" />
</div>
</template>

@ -0,0 +1,528 @@
<script lang="ts" setup>
import { computed, onBeforeMount, onMounted, onUpdated, reactive, ref, watch } from 'vue'
import Masonry from 'masonry-layout'
import { useInfiniteScroll } from '@vueuse/core'
import { debounce } from 'lodash-es'
import imagesloaded from 'imagesloaded'
import { timeOptions, viewOptions } from '@/config/home'
import { off, on } from '@/utils/domUtils'
import img1 from '@/assets/images/1.jpg'
import img2 from '@/assets/images/2.jpg'
import img3 from '@/assets/images/3.jpg'
import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg'
import { useTask } from '@/store/modules/task'
import { getTaskDetailPictureList } from '@/api/work/work'
import type { PictureSortParam } from '/#/api'
const cardStyle = {
'--n-padding-bottom': '40px',
'--n-padding-left': '120px',
}
const timeRange = ref('all')
const timeLabel = computed(() => {
const item = timeOptions.find((option) => {
return option.value === timeRange.value
})
return item?.label
})
const viewMode = ref('masonry')
const viewLabel = computed(() => {
const item = viewOptions.find((option) => {
return option.value === viewMode.value
})
return item?.label
})
const taskStore = useTask()
const masonryRef = ref<ComponentRef>(null)
const el = ref<HTMLDivElement | null>(null)
const listData = ref<any[]>([])
const pagination = reactive({
pageNo: 1,
pageSize: 30,
})
let loading = false
let _masonry: null | Masonry = null
const show = ref(false)
const sortBy: PictureSortParam = {
orderbyname: 'asc',
orderbyvalue: 'fromuptime',
}
const layout = debounce(() => {
if (!show.value)
return
if (_masonry !== null)
(_masonry as any).destroy()
_masonry = new Masonry(masonryRef.value as any, {
itemSelector: '.grid-item',
columnWidth: 214,
percentPosition: true,
stagger: 10,
})
imagesloaded('.grid-item', () => {
(_masonry as any).layout()
const scrollHeight = el.value!.scrollHeight
const clientHeight = el.value!.clientHeight
const top = scrollHeight - clientHeight - 20
el.value!.scrollTo({ top, behavior: 'instant' })
loading = false
})
}, 300)
watch(viewMode, () => {
layout()
})
let canloadMore = true
useInfiniteScroll(
el as any,
() => {
loadMore()
},
{ distance: 10, canLoadMore: () => canloadMore },
)
async function featchList() {
loading = true
try {
const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId
const res = await getTaskDetailPictureList(packageid, taskId, { ...pagination, ...sortBy })
const { data, pageCount } = res
pagination.pageNo += 1
canloadMore = pageCount >= pagination.pageNo
const list = data.map((item) => {
return {
imgUrl: item.imgurl,
}
})
return list
}
catch (error) {
return []
}
}
async function loadMore() {
if (loading || el.value == null)
return
const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId
if (!packageid || !taskId)
return
const more = await featchList()
listData.value.push(...more)
}
onUpdated(() => {
layout()
})
let start: { x: number, y: number } | null = null
let selectionBox: HTMLDivElement | null
const selectIds = ref<string[]>([])
function downHandler(event: MouseEvent) {
if (!selectionBox)
return
selectIds.value.length = 0
start = { x: event.clientX, y: event.clientY }
selectionBox.style.width = '0'
selectionBox.style.height = '0'
selectionBox.style.left = `${start.x}px`
selectionBox.style.top = `${start.y}px`
selectionBox.style.display = 'block'
selectionBox.style.zIndex = '9999'
}
function imUpdateSelectIds(x: number, y: number, w: number, h: number) {
const items = document.querySelectorAll('.grid-item')
items.forEach((item: HTMLDivElement) => {
const rect = item.getBoundingClientRect()
const index = selectIds.value.indexOf(item.dataset.id!)
if (rect.right > x && rect.bottom > y && rect.left < x + w && rect.top < y + h)
index === -1 && selectIds.value.push(item.dataset.id!)
else index !== -1 && selectIds.value.splice(index, 1)
})
}
function isSelected(id: number) {
return selectIds.value.includes(String(id))
}
function moveHandler(e: MouseEvent) {
if (!selectionBox || !start)
return
const x = Math.min(e.clientX, start.x)
const y = Math.min(e.clientY, start.y)
const w = Math.abs(e.clientX - start.x)
const h = Math.abs(e.clientY - start.y)
selectionBox.style.width = `${w}px`
selectionBox.style.height = `${h}px`
selectionBox.style.left = `${x}px`
selectionBox.style.top = `${y}px`
imUpdateSelectIds(x, y, w, h)
}
function upHandler(event: MouseEvent) {
if (!selectionBox)
return
selectionBox.style.display = 'none'
start = null
}
const gridHeight = computed(() => {
return viewMode.value !== 'masonry' ? '157px' : ''
})
function addListeners() {
selectionBox = document.querySelector('.selection-box') as HTMLDivElement
on(el.value!, 'mousedown', downHandler)
on(el.value!, 'mousemove', moveHandler)
on(document, 'mouseup', upHandler)
}
function removeListeners() {
off(el.value!, 'mousedown', downHandler)
on(el.value!, 'mousemove', moveHandler)
on(document, 'mouseup', upHandler)
}
async function afterEnter() {
addListeners()
const list = await featchList()
listData.value = list
}
function afterLeave() {
removeListeners()
pagination.pageNo = 1
pagination.pageSize = 30
}
onMounted(() => {
show.value && addListeners()
})
function showModal() {
show.value = true
}
function closeModal(event: MouseEvent) {
show.value = false
}
defineExpose({
showModal,
})
function forwardHandler() {
taskStore.forward()
}
function backHandler() {
taskStore.back()
}
</script>
<template>
<div>
<n-modal
v-model:show="show" :mask-closable="false" style="position: relative;" transform-origin="center"
@after-enter="afterEnter" @after-leave="afterLeave"
>
<n-card
:style="cardStyle" class="card" style="position: fixed;top:64px" :bordered="false" size="huge"
role="dialog" aria-modal="true"
>
<div class="wrapper">
<div class="wrapper-m32">
<SvgIcon name="recycle" size="16" />
<span style="margin-left: 8px;">任务审批</span>
</div>
<div class="wrapper-title wrapper-m32">
<span>可疑图片文件夹</span>
<SvgIcon size="22" class="forward" name="arrow-left" @click="backHandler" />
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" />
</div>
<div class="wrapper-statistic wrapper-m32">
<table style="width: 100%;">
<thead>
<tr>
<th scope="col">
创建人
</th>
<th scope="col">
状态
</th>
<th scope="col">
创建时间
</th>
<th scope="col">
图片来源
</th>
<th scope="col">
相似匹配
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
张三丰
</td>
<td>待审批</td>
<td>2023-12-02 14:20:11</td>
<td>网络截图</td>
<td>15</td>
</tr>
</tbody>
</table>
</div>
<div class="wrapper-content">
<div class="wrapper-content-form wrapper-m32">
<div>
<n-popselect v-model:value="timeRange" :options="timeOptions" trigger="click">
<div class="wrapper-content-form-dropdown">
<span>{{ timeLabel || '时间模式' }}</span>
<SvgIcon class="wrapper-content-form-dropdown-gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
<n-popselect v-model:value="viewMode" :options="viewOptions" trigger="click">
<div class="wrapper-form-dropdown">
<span>{{ viewLabel || '视图模式' }}</span>
<SvgIcon class="wrapper-content-form-gap" name="arrow-botton" size="14" />
</div>
</n-popselect>
</div>
<div>
<div>移除可疑文件夹</div>
<div class="wrapper-content-form-button">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" />
批量审批
</div>
</div>
</div>
<div ref="el" class="scroll">
<!-- <n-scrollbar :on-scroll="scrollHandler"> -->
<div ref="masonryRef" class="grid">
<div
v-for="(item, index) in listData" :key="index" :data-id="index"
:class="{ 'grid-item-selected': isSelected(index) }" :style="{ height: gridHeight }"
class="grid-item"
>
<img
class="wrapper-content-item-img"
:class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl"
>
<div
style="position:absolute;left: 0px;top: 0px;display: flex;justify-content: space-between;width: 100%;padding: 16px;"
>
<n-checkbox v-model:checked="item.checked" @click.stop />
<div class="percent">
30%
</div>
</div>
</div>
</div>
<!-- </n-scrollbar> -->
</div>
</div>
<div class="close" @pointerdown="closeModal">
<div class="icon" />
</div>
</div>
</n-card>
</n-modal>
</div>
</template>
<style lang="less" scoped>
.card {
width: 100vw;
height: calc(100vh - 64px);
user-select: none;
/* Standard syntax */
}
.close {
position: absolute;
right: -90px;
top: -70px;
width: 18px;
height: 18px;
cursor: pointer;
}
.icon {
background: #FFF;
display: inline-block;
width: 18px;
height: 1px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
&:after {
content: '';
display: block;
width: 18px;
height: 1px;
background: #FFF;
transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
}
}
.wrapper {
display: flex;
flex-direction: column;
position: relative;
&-title {
font-weight: bold;
font-size: 21px;
padding: 24px 0px 12px 0px;
.forward {
cursor: pointer;
margin-left: 16px;
}
.back {
cursor: pointer;
margin-left: 6px;
}
}
&-statistic {
background-color: #fafbfc;
padding: 12px 20px;
border-radius: 3px;
margin-bottom: 10px;
th {
color: #d7d7d7;
text-align: left;
}
td {
text-align: center;
font-weight: bold;
text-align: left;
}
}
&-m32 {
margin-left: 32px;
}
&-content {
&-form {
display: flex;
justify-content: space-between;
&-dropdown {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 24px;
&-gap {
margin-left: 5px;
}
}
&-button {
width: 118px;
height: 36px;
background: linear-gradient(135deg, #5b85f8, #3c6cf0);
border-radius: 17px;
box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.30);
display: flex;
align-items: center;
justify-content: center;
color: #FFF;
margin-left: 18px;
}
div {
display: flex;
align-items: center;
}
}
&-item {
&-img {
border-radius: 7px;
display: block;
height: 100%;
}
&-img-fit {
width: 100%;
object-fit: cover;
}
}
.grid-item {
width: 214px;
padding: 16px;
position: relative;
}
.percent {
text-align: center;
width: 35px;
height: 18px;
opacity: 0.9;
background: #6f92fd;
border-radius: 6px 0px 6px 0px;
z-index: 5;
right: 12px;
top: 2px;
color: #FFF;
}
.grid-item-selected {
background-color: #dae3ff;
}
.scroll {
overflow-y: scroll;
height: calc(100vh - 282px);
}
}
}
</style>

@ -1,14 +1,17 @@
<script lang="ts" setup>
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import { useDialog } from 'naive-ui'
import { pickBy } from 'lodash-es'
import { useDialog, useMessage } from 'naive-ui'
import { clone, pickBy } from 'lodash-es'
import ConfrimModal from '../modal/ConfrimModal.vue'
import type { PictureSortParam, SetTFParam } from '/#/api'
import { useWorkOrder } from '@/store/modules/workOrder'
import { clearTF, getPackageTaskList, getTaskDetailInfo, getTaskDetailPictureList, setTF } from '@/api/work/work'
import { fieldMap } from '@/config/workorder'
const batch = ref(false)
const selectItems = ref<any[]>([])
const message = useMessage()
const dialog = useDialog()
function setBatch(value: boolean) {
batch.value = value
@ -33,21 +36,6 @@ const showActions = computed(() => {
return selectItems.value.length > 0 && batch
})
const dialog = useDialog()
function handleConfirm() {
dialog.info({
title: '确认提示',
content: '确认给该任务图判真吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
setTrueHandler()
},
onNegativeClick: () => { },
})
}
const packagepagination = reactive({
pageNo: 1,
pageSize: 10,
@ -57,7 +45,7 @@ const taskpagination = reactive({
pageSize: 10,
})
const sortBy: PictureSortParam = {
orderbyname: 'asc',
orderbyname: 'desc',
orderbyvalue: 'fromuptime',
}
const workStore = useWorkOrder()
@ -67,50 +55,121 @@ const taskList = ref<any[]>([])
const taskDetailInfo = ref<any>({})
const taskDetailPictureList = ref<any[]>([])
function setTrueHandler() {
let ids: any[] = []
const confrimModalRef = ref(null)
let processItems: any[] = []
function validate(items: any[]) {
if (items.length === 0)
return '至少选中一个任务'
for (const item of items) {
const { iztrueorfalse, history, states } = item
if (iztrueorfalse !== null)
return '存在已经辨识过的任务'
else if (history)
return '包含历史数据'
else if (states !== 1 && states !== 2)
return '审批状态不合法'
}
return null
}
if (batch.value === true)
ids = selectItems.value.map(item => item.id)
else if (overTask.value !== null)
ids = [overTask.value.id]
function falseHandler() {
let cloneItem: any
if (batch.value) { processItems = selectItems.value }
else if (overTask.value) {
cloneItem = clone(overTask.value)
processItems = [cloneItem]
}
const msg = validate(processItems)
if (msg !== null) {
message.error(msg)
return
}
const modal = unref(confrimModalRef)! as any
modal.showModal()
}
function trueHandler() {
let cloneItem: any
if (batch.value) { processItems = selectItems.value }
else if (overTask.value) {
cloneItem = clone(overTask.value)
processItems = [cloneItem]
}
const msg = validate(processItems)
if (msg !== null) {
message.error(msg)
return
}
dialog.info({
title: '确认提示',
content: '确认给该任务图判真吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
setTrue()
},
onNegativeClick: () => { },
})
}
function setTrue() {
const ids: any[] = processItems.map(item => item.id)
const param: SetTFParam = {
taskchildpictureids: ids,
izTrueorfalse: 1,
taskchildpictureids: ids.join(','),
iztrueorfalse: 1,
packageid: workStore.getActiveId,
judgeid: '0',
}
setTF(param)
doSetTF(param)
}
function setFalseHandler(idOrDesc: string, isOther: boolean) {
let ids: any[] = []
if (batch.value === true)
ids = selectItems.value.map(item => item.id)
else if (overTask.value !== null)
ids = [overTask.value.id]
function setFalse(id: string, desc: null | string) {
const ids: any[] = processItems.map(item => item.id)
const param: SetTFParam = {
taskchildpictureids: ids,
izTrueorfalse: 0,
taskchildpictureids: ids.join(','),
iztrueorfalse: 0,
packageid: workStore.getActiveId,
judgeid: id,
}
if (isOther)
param.judgedesc = idOrDesc
else
param.judgeid = idOrDesc
if (desc)
param.judgedesc = desc
setTF(param)
doSetTF(param)
}
const confrimModalRef = ref(null)
function doSetTF(param: SetTFParam) {
setTF(param).then((res) => {
const { code } = res
processItems.length = 0
if (code === 'OK')
updateList(param)
else
message.error(res.message)
})
}
function showModal() {
const modal = unref(confrimModalRef)! as any
modal.showModal()
function updateList(param: SetTFParam) {
const list = taskDetailPictureList.value
const ids = param.taskchildpictureids.split(',')
for (const item of list) {
if (ids.includes(item.id))
item.iztrueorfalse = param.iztrueorfalse
}
}
function forwardHandler() {
@ -126,13 +185,8 @@ watch(() => workStore.activeId, async (newValue, oldValue) => {
const { data } = res
taskList.value = data
if (taskList.value.length > 0) {
if (taskList.value.length > 0)
handleSelect(taskList.value[0])
const taskId = taskList.value[0].id
const res = await getTaskDetailPictureList(workStore.activeId, taskId, { ...taskpagination, ...sortBy })
taskDetailPictureList.value = res.data
}
})
const packageName = computed(() => {
@ -144,6 +198,9 @@ async function handleSelect(item: any) {
selectTask.value = item
const taskId = item.id
taskDetailInfo.value = await getTaskDetailInfo(taskId, workStore.activeId)
const res = await getTaskDetailPictureList(workStore.activeId, taskId, { ...taskpagination, ...sortBy })
taskDetailPictureList.value = res.data
}
async function sortHandler(orderby: 'pictureResult' | 'fromuptime') {
@ -161,20 +218,36 @@ async function sortHandler(orderby: 'pictureResult' | 'fromuptime') {
const propertys = computed(() => {
const { ocrPicture } = taskDetailInfo.value
const v = pickBy(ocrPicture, (value, key: string) => {
return key.startsWith('field')
return key.startsWith('field') && value !== null
})
return v
})
async function clearHandler() {
const res = await clearTF(selectTask.value.id)
if (res.ok)
selectTask.value.status = ''
dialog.info({
title: '确认提示',
content: '确认给该任务图片的标记印记吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
clearMark()
},
onNegativeClick: () => { },
})
}
async function clearMark() {
const res = await clearTF(workStore.activeId, selectTask.value.id)
if (res.code === 'OK') {
taskDetailInfo.value.iztrueorfalse = null
message.info('清除标记成功')
}
else { message.error(res.message) }
}
function overTaskHandelr(item: any) {
// TODOitem
// overTask.value = item
if (validate([item]) == null && batch.value === false)
overTask.value = item
}
function leaveTaskHandler() {
@ -184,6 +257,15 @@ function leaveTaskHandler() {
onUnmounted(() => {
workStore.reset()
})
function getPercent(pictureid: string) {
const { ocpictureid, pictureresult } = taskDetailInfo.value
const index = ocpictureid.split(',').indexOf(String(pictureid))
const results = pictureresult.split(',')
const percent = results[index] || '0'
const val = Number.parseFloat(percent)
return `${val}%`
}
</script>
<template>
@ -195,10 +277,17 @@ onUnmounted(() => {
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" />
</div>
<div class="right">
<div v-show="!showActions" class="btn" @click="setBatch(true)">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" />
辨别真假
<div v-show="!showActions" style="display: flex;">
<n-button text @click="clearHandler">
<SvgIcon size="12" name="delete" />
清除标记
</n-button>
<div class="btn" style="margin-left: 20px;" @click="setBatch(true)">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" />
辨别真假
</div>
</div>
<div v-show="showActions" class="batch">
<n-button text @click="setBatch(false)">
<template #icon>
@ -206,19 +295,42 @@ onUnmounted(() => {
</template>
返回
</n-button>
<div style="cursor: pointer;margin-left: 16px;" @click="showModal">
<div style="cursor: pointer;margin-left: 16px;" @click="falseHandler">
<SvgIcon width="64" height="28" name="t4" />
</div>
<SvgIcon size="24" name="vs" />
<div style="cursor: pointer;" @click="handleConfirm">
<div style="cursor: pointer;" @click="trueHandler">
<SvgIcon width="64" height="28" name="t3" />
</div>
</div>
</div>
</div>
<div class="wrapper-detail">
<div class="left">
<img style="overflow: hidden;" src="../../../assets/images/test.png">
<div class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }">
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" />
</div>
<div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 1" size="128" name="zhen" />
</div>
<div class="info">
<n-grid x-gap="16" y-gap="0" :cols="12">
<n-gi span="4">
<span style="color:#8b8d8f;"><SvgIcon name="m1" /></span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>未标记</span>
<span>图片标记</span>
</n-gi>
<n-gi span="4">
<span style="color:#8b8d8f;"><SvgIcon name="m2" /></span>
</n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>14</span>
<span>相似匹配</span>
</n-gi>
</n-grid>
</div>
</div>
<div class="right">
<n-scrollbar style="max-height: 100%;">
@ -238,7 +350,7 @@ onUnmounted(() => {
<span style="font-weight: bold;color: #333333;font-size: 16px;">拜访终端</span>
</div>
<div v-for="(key) in Object.keys(propertys)" :key="key" class="property">
<span class="property-name">{{ key }}</span>
<span class="property-name">{{ fieldMap[key] }}</span>
<span class="property-content ">{{ propertys[key] }}</span>
</div>
</n-scrollbar>
@ -262,9 +374,7 @@ onUnmounted(() => {
v-for="(item, index) in taskDetailPictureList" :key="index" :class="{ 'item-selected': item === selectTask }"
class="item" @click="handleSelect(item)" @mouseover="overTaskHandelr(item)" @mouseleave="leaveTaskHandler"
>
<div style="width: 210px;overflow: hidden;">
<img src="../../../assets/images/test.png">
</div>
<div class="img-wrapper" :style="{ 'background-image': `url(${item.imgurl})` }" />
<div class="check">
<n-checkbox
v-show="batch" v-model:checked="item.checked" @click.stop
@ -274,22 +384,22 @@ onUnmounted(() => {
<div class="percent">
<SvgIcon size="42" name="tag" />
<div class="val">
96%
{{ getPercent(item.pictureid) }}
</div>
</div>
<div>
<div v-show="overTask && overTask.id === item.id" class="action">
<div>
假假假
</div>
<div @click="setTrueHandler">
真真真
</div>
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 0" name="jia" />
</div>
<div class="mark">
<SvgIcon v-show="item.iztrueorfalse === 1" name="zhen" />
</div>
<div v-show="overTask && overTask.id === item.id" class="action">
<SvgIcon style="cursor: pointer;" name="t1" @click.stop @click="trueHandler" />
<SvgIcon style="cursor: pointer;" name="t2" @click.stop @click="falseHandler" />
</div>
</div>
</div>
<ConfrimModal ref="confrimModalRef" @commit="setFalseHandler" />
<ConfrimModal ref="confrimModalRef" @commit="setFalse" />
</div>
</template>
@ -371,10 +481,38 @@ onUnmounted(() => {
.left {
flex: 1;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 8px;
position: relative;
img {
max-height: 100%;
width: auto;
.mark {
position: absolute;
z-index: 3;
right: 15%;
top: 0px;
width: 128px;
height: 80px;
overflow: hidden;
overflow: hidden;
svg {
position: absolute;
top: -48px;
}
}
.info {
position: absolute;
z-index: 3;
right: 2%;
bottom: 2%;
width: 136px;
height: 119px;
opacity: 0.44;
background: #d8d8d8;
border-radius: 7px;
}
}
@ -415,14 +553,14 @@ onUnmounted(() => {
border: 1px solid #FE9800;
}
.property {
.property {
display: flex;
align-items: center;
margin-top: 10px;
}
.property-name {
width: 88px;
width: 100px;
color: #999999;
position: relative;
}
@ -463,12 +601,20 @@ onUnmounted(() => {
border-radius: 8px;
padding: 9px 10px;
position: relative;
overflow: hidden;
margin: 0px 5px 5px 0px;
.img-wrapper {
width: 230px;
height: 130px;
overflow: hidden;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 8px;
}
.check {
position: absolute;
z-index: 5;
z-index: 3;
left: 12px;
top: 12px;
}
@ -476,7 +622,7 @@ onUnmounted(() => {
.percent {
position: absolute;
text-align: center;
z-index: 5;
z-index: 3;
right: 12px;
top: 2px;
color: #FFF;
@ -494,16 +640,34 @@ onUnmounted(() => {
}
}
.mark {
position: absolute;
z-index: 3;
right: 62px;
top: 9px;
width: 64px;
height: 40px;
overflow: hidden;
overflow: hidden;
svg {
position: absolute;
top: -20px;
}
}
.action {
position: absolute;
z-index: 5;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
left: 10px;
top: 9px;
width: 230px;
height: 130px;
display: flex;
border-radius: 8px;
align-items: center;
justify-content: space-around;
background-color: #666666;
}
}
}

@ -3,7 +3,7 @@ import { computed, onBeforeMount, ref } from 'vue'
import { useDictionary } from '@/store/modules/dictonary'
const emit = defineEmits<{
(e: 'commit', value: any, isOther: boolean)
(e: 'commit', id: any, desc: null | string)
}>()
const dictonaryStore = useDictionary()
@ -32,34 +32,23 @@ const options = ref<any[]>([])
const selectId = ref(null)
const otherValue = ref(null)
const showOther = computed(() => {
return selectId.value === 'other'
})
for (const item of options.value) {
if (item.value === selectId.value && item.label === '其他')
return true
}
const comomitValue = computed(() => {
return selectId.value === 'other' ? otherValue.value : selectId.value
return false
})
async function handleSumbit(e: MouseEvent) {
e.preventDefault()
closeModal()
emit('commit', comomitValue, selectId.value === 'other')
emit('commit', selectId.value, otherValue.value)
}
onBeforeMount(async () => {
const tfList = await dictonaryStore.fetchTFList()
options.value = tfList.map((item) => {
return {
label: item.name,
value: item.id,
}
})
//
options.value.push({
label: '其他',
value: 'other',
})
options.value = tfList
})
</script>

4
types/api.d.ts vendored

@ -87,8 +87,8 @@ export interface AsideConfig {
// ----------任务工单----------
export interface SetTFParam {
taskchildpictureids: string[]
izTrueorfalse?: number
taskchildpictureids: string
iztrueorfalse?: number
judgeid?: string
judgedesc?: string
packageid: string

@ -0,0 +1,46 @@
## 一键查重
izsearch --- 是自定义过滤条件的开关,不是搜索参数
izsearchmanager --- 自定义筛选的开关,不是搜索参数
izdesc -- 添加备注开关,不是搜索参数
izcustomtype -- 已经调整替代filed2字段查询
izcustomlevel --已经调整替代izfield6
izprojecttype --已经调整替代izfield17
izvisitcity --已经调整替代原来的isarea
izproject --数据字典,项目列表
izvisitpro --数据字典,省份列表
----------------------------------------
缺少参数,字典?
izsearch,izsearchmanager,
izdesc,izcustomtype
izcustomlevelizprojecttypeizvisitcity
缺少字典
izprojectizvisitpro
字典缺少数据
提报人
系统配置无效
izfiled2,izfield6,izfield3,izfield17
添加自定义过滤条件
增加逻辑与和或
生成任务包参数
增加是否对比历史数据,是否给重复图片添加重复标识
## 终审
小结查重弹框数据
## 其他
1. 列表字段个性化展示配置
2. 可疑文件夹的增、删、改、查
3. 任务导出excel
4. 重复任务列表
Loading…
Cancel
Save