Merge branch 'main' into shen

bak
Dragon 1 year ago
commit 26bb511100

36
components.d.ts vendored

@ -9,44 +9,10 @@ declare module 'vue' {
export interface GlobalComponents { export interface GlobalComponents {
Application: typeof import('./src/components/Application/Application.vue')['default'] Application: typeof import('./src/components/Application/Application.vue')['default']
BasicModal: typeof import('./src/components/Modal/BasicModal.vue')['default'] BasicModal: typeof import('./src/components/Modal/BasicModal.vue')['default']
NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NCollapse: typeof import('naive-ui')['NCollapse']
NCollapseItem: typeof import('naive-ui')['NCollapseItem']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDatePicker: typeof import('naive-ui')['NDatePicker']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NDivider: typeof import('naive-ui')['NDivider']
NDropdown: typeof import('naive-ui')['NDropdown']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NGridItem: typeof import('naive-ui')['NGridItem']
NImage: typeof import('naive-ui')['NImage']
NInput: typeof import('naive-ui')['NInput']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NModal: typeof import('naive-ui')['NModal']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NPopover: typeof import('naive-ui')['NPopover']
NPopselect: typeof import('naive-ui')['NPopselect']
NScrollbar: typeof import('naive-ui')['NScrollbar']
NSelect: typeof import('naive-ui')['NSelect']
NSlider: typeof import('naive-ui')['NSlider']
NSpace: typeof import('naive-ui')['NSpace']
NSpin: typeof import('naive-ui')['NSpin']
NSwitch: typeof import('naive-ui')['NSwitch']
NTabPane: typeof import('naive-ui')['NTabPane']
NTabs: typeof import('naive-ui')['NTabs']
NTag: typeof import('naive-ui')['NTag']
NTooltip: typeof import('naive-ui')['NTooltip']
NUpload: typeof import('naive-ui')['NUpload']
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
Quill: typeof import('./src/components/RichEditor/Quill.vue')['default'] Quill: typeof import('./src/components/RichEditor/Quill.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
Search: typeof import('./src/components/Search/Search.vue')['default']
SvgIcon: typeof import('./src/components/Icon/SvgIcon.vue')['default'] SvgIcon: typeof import('./src/components/Icon/SvgIcon.vue')['default']
} }
} }

12909
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -25,7 +25,7 @@
"masonry-layout": "^4.2.2", "masonry-layout": "^4.2.2",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"naive-ui": "^2.34.4", "naive-ui": "^2.38.1",
"pinia": "^2.0.33", "pinia": "^2.0.33",
"qs": "^6.11.2", "qs": "^6.11.2",
"sortablejs": "^1.15.1", "sortablejs": "^1.15.1",

@ -39,8 +39,8 @@ dependencies:
specifier: ^1.1.0 specifier: ^1.1.0
version: 1.1.0 version: 1.1.0
naive-ui: naive-ui:
specifier: ^2.34.4 specifier: ^2.38.1
version: 2.34.4(vue@3.3.10) version: 2.38.1(vue@3.3.10)
pinia: pinia:
specifier: ^2.0.33 specifier: ^2.0.33
version: 2.1.7(typescript@4.9.5)(vue@3.3.10) version: 2.1.7(typescript@4.9.5)(vue@3.3.10)
@ -1300,8 +1300,8 @@ packages:
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
dev: true dev: true
/@types/katex@0.14.0: /@types/katex@0.16.7:
resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==} resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
dev: false dev: false
/@types/lodash-es@4.17.12: /@types/lodash-es@4.17.12:
@ -2587,15 +2587,19 @@ packages:
/csstype@3.1.2: /csstype@3.1.2:
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
dev: false
/dargs@7.0.0: /dargs@7.0.0:
resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/date-fns-tz@1.3.8(date-fns@2.30.0): /date-fns-tz@2.0.1(date-fns@2.30.0):
resolution: {integrity: sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==} resolution: {integrity: sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==}
peerDependencies: peerDependencies:
date-fns: '>=2.0.0' date-fns: 2.x
dependencies: dependencies:
date-fns: 2.30.0 date-fns: 2.30.0
dev: false dev: false
@ -5230,20 +5234,21 @@ packages:
thenify-all: 1.6.0 thenify-all: 1.6.0
dev: true dev: true
/naive-ui@2.34.4(vue@3.3.10): /naive-ui@2.38.1(vue@3.3.10):
resolution: {integrity: sha512-aPG8PDfhSzIzn/jSC9y3Jb3Pe2wHJ7F0cFV1EWlbImSrZECeUmoc+fIcOSWbizoztkKfaUAeKwYdMl09MKkj1g==} resolution: {integrity: sha512-AnU1FQ7K/CbhguAX++V4kCFjk7h7RvWt4nvZPRjORMpq+fUIlzD+EcQ5Cv1VqDloNF8+eMv4Akc2Ogacc9S+5A==}
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
dependencies: dependencies:
'@css-render/plugin-bem': 0.15.12(css-render@0.15.12) '@css-render/plugin-bem': 0.15.12(css-render@0.15.12)
'@css-render/vue3-ssr': 0.15.12(vue@3.3.10) '@css-render/vue3-ssr': 0.15.12(vue@3.3.10)
'@types/katex': 0.14.0 '@types/katex': 0.16.7
'@types/lodash': 4.14.202 '@types/lodash': 4.14.202
'@types/lodash-es': 4.17.12 '@types/lodash-es': 4.17.12
async-validator: 4.2.5 async-validator: 4.2.5
css-render: 0.15.12 css-render: 0.15.12
csstype: 3.1.3
date-fns: 2.30.0 date-fns: 2.30.0
date-fns-tz: 1.3.8(date-fns@2.30.0) date-fns-tz: 2.0.1(date-fns@2.30.0)
evtd: 0.2.4 evtd: 0.2.4
highlight.js: 11.9.0 highlight.js: 11.9.0
lodash: 4.17.21 lodash: 4.17.21

@ -312,6 +312,6 @@ export async function getBackList() {
method: 'get', method: 'get',
}) })
const list = res.data[0].distionaryList const list = res.data
return list return list
} }

@ -6,11 +6,14 @@ import type { FilterCondition, FilterParam, FilterSearchParam, FilterUpdate, Pag
* @param params * @param params
* @returns 1 * @returns 1
*/ */
export async function getConditionList(params: PageParam & FilterSearchParam): Promise<any> { export async function getConditionList(params: PageParam, searchParam: FilterSearchParam): Promise<any> {
const res = await http.request({ const res = await http.request({
url: `/ocr/ocrUsersearch/list`, url: `/ocr/ocrUsersearch/list?`,
method: 'get', method: 'get',
params, params: {
...params,
search_searchname: JSON.stringify(searchParam.search_searchname),
},
}) })
const { data: { records, pages } } = res const { data: { records, pages } } = res

@ -1,3 +1,4 @@
import qs from 'qs'
import { http } from '@/utils/http/axios' import { http } from '@/utils/http/axios'
import type { ApprovalParam, PageParam } from '/#/api' import type { ApprovalParam, PageParam } from '/#/api'
import { ContentTypeEnum } from '@/enums/httpEnum' import { ContentTypeEnum } from '@/enums/httpEnum'
@ -10,7 +11,7 @@ export async function getApprovalList(params: PageParam, assigneeId: string) {
const res = await http.request({ const res = await http.request({
url: `/flow/task/listdata`, url: `/flow/task/listdata`,
method: 'get', method: 'get',
params, params: { ...params, assigneeId },
}) })
const { data: { list, totalPage } } = res const { data: { list, totalPage } } = res
@ -26,9 +27,9 @@ export async function getApprovalList(params: PageParam, assigneeId: string) {
*/ */
export async function audit(params: ApprovalParam) { export async function audit(params: ApprovalParam) {
return http.request({ return http.request({
url: `/flow/task/completeBatchFlow`, url: `/flow/task/completeBatchFlow?`,
method: 'post', method: 'post',
params, params: qs.stringify(params, { indices: false }),
headers: { 'Content-Type': ContentTypeEnum.FORM_DATA }, headers: { 'Content-Type': ContentTypeEnum.FORM_DATA },
}) })
} }

@ -71,14 +71,13 @@ export async function getTaskDetailPictureList(packageid: string, taskchildpictu
const { data: { records, pages, total } } = res const { data: { records, pages, total } } = res
debugger
// 精简一下数据 // 精简一下数据
const list = records.map((item) => { const list = records.map((item) => {
return { return {
id: item.id, id: item.id,
taskid: item.taskId, taskId: item.taskId,
taskname: item.fromtaskname, taskname: item.fromtaskname,
assignee: item.assignee,
pictureid: item.pictureid, pictureid: item.pictureid,
imgurl: item.ocrPicture.imgurl, imgurl: item.ocrPicture.imgurl,
iztrueorfalse: item.iztrueorfalse, iztrueorfalse: item.iztrueorfalse,

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="28px" height="28px" viewBox="0 0 28 28" 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="28" height="28"></rect>
</defs>
<g id="任务审批" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.0备份-8" transform="translate(-995.000000, -199.000000)">
<g id="编组-8" transform="translate(484.720905, 182.572383)">
<g id="失败" transform="translate(510.279095, 16.427617)">
<g transform="translate(0.000000, 0.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M14,1.75 C20.7654882,1.75 26.25,7.23451181 26.25,14 C26.25,20.7654882 20.7654882,26.25 14,26.25 C7.23451181,26.25 1.75,20.7654882 1.75,14 C1.75,7.23451181 7.23451181,1.75 14,1.75 Z M14,3.9375 C8.44263471,3.9375 3.9375,8.44263471 3.9375,14 C3.9375,19.5573653 8.44263471,24.0625 14,24.0625 C19.5573653,24.0625 24.0625,19.5573653 24.0625,14 C24.0625,8.44263471 19.5573653,3.9375 14,3.9375 Z M18.317447,8.91076112 L18.3862477,8.96661573 L18.3862477,8.96661573 L19.0068311,9.5834638 C19.1782001,9.7538018 19.1790364,10.03081 19.0086989,10.2021796 L15.2337382,14.000005 L19.0086839,17.7978145 C19.1577296,17.9477627 19.1757199,18.1785908 19.0630846,18.3480678 L19.0068157,18.41653 L19.0068157,18.41653 L18.3862314,19.0333775 C18.2148618,19.203715 17.9378535,19.2028786 17.7675156,19.0315093 L14.00002,15.241195 L10.232526,19.0315093 C10.0834806,19.1814577 9.85276538,19.2008416 9.68261124,19.0892317 L9.61381053,19.0333773 L9.61381053,19.0333773 L8.99322583,18.4165285 C8.84327757,18.267483 8.82389374,18.0367677 8.93550373,17.8666136 L8.9913579,17.7978129 L8.9913579,17.7978129 L12.7663035,14.000005 L8.99134235,10.2021788 C8.84229682,10.0522305 8.82430649,9.82140245 8.9369419,9.65192539 L8.99321049,9.58346322 L8.99321049,9.58346322 L9.61379457,8.96661547 C9.76374284,8.81756995 9.99457094,8.79957963 10.164048,8.91221504 L10.2325102,8.96848364 L10.2325102,8.96848364 L14.0000209,12.7588151 L17.7675324,8.96848361 C17.9165777,8.81853511 18.1472929,8.79915119 18.317447,8.91076112 Z" id="形状结合" fill="#507AFD" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710483988979" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9416" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0h1024v1024H0z" fill="#FFFFFF" fill-opacity="0" p-id="9417"></path><path d="M743.8336 230.4C842.0352 230.4 921.6 306.7392 921.6 400.896v249.2416c0 79.2576-66.9696 143.4624-149.6064 143.4624h-77.1072c-30.976 0-60.928-10.4448-84.6336-29.5424l-92.16-74.3936a7.8848 7.8848 0 0 0-10.0864 0.256L426.496 760.832a134.656 134.656 0 0 1-88.3712 32.768H257.536a158.6176 158.6176 0 0 1-109.7216-43.5712A145.7152 145.7152 0 0 1 102.4 644.8128V400.896C102.4 306.688 182.016 230.4 280.2176 230.4z m0 74.24H280.2176c-55.3984 0-100.352 43.0592-100.4544 96.256v243.9168c0 41.216 34.816 74.5472 77.7216 74.5472h80.7424c13.4144 0 26.368-4.8128 36.3008-13.4656l81.408-70.9632a87.8592 87.8592 0 0 1 111.9744-2.048l92.2624 74.3424c9.728 7.8336 22.016 12.1344 34.7648 12.1344h77.1072c39.8336 0 72.192-30.976 72.192-69.2224V400.896c0-53.1456-44.9536-96.256-100.352-96.256z m-46.336 140.6976c38.4 0 69.5296 29.8496 69.5296 66.6624 0 36.864-31.1296 66.6624-69.5296 66.6624-38.4 0-69.5808-29.8496-69.5808-66.6624 0-36.864 31.1296-66.6624 69.5808-66.6624z m-370.944 0c38.4 0 69.5808 29.8496 69.5808 66.6624 0 23.808-13.312 45.824-34.816 57.7536a72.192 72.192 0 0 1-69.5296 0A66.2016 66.2016 0 0 1 257.024 512c0-36.864 31.1296-66.6624 69.5296-66.6624z" fill="#507AFD" p-id="9418"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="167px" height="60px" viewBox="0 0 167 60" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>按钮</title>
<defs>
<linearGradient x1="0%" y1="45.4803708%" x2="100%" y2="54.5196292%" id="linearGradient-1">
<stop stop-color="#3258E8" offset="0%"></stop>
<stop stop-color="#786EFC" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="45.8510597%" x2="100%" y2="51.7669561%" id="linearGradient-2">
<stop stop-color="#D7DFFE" offset="0%"></stop>
<stop stop-color="#D7D5FF" offset="100%"></stop>
</linearGradient>
<rect id="path-3" x="0" y="0" width="153" height="46" rx="23"></rect>
<filter x="-6.9%" y="-18.5%" width="113.7%" height="145.7%" filterUnits="objectBoundingBox" id="filter-4">
<feMorphology radius="0.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
<feOffset dx="0" dy="2" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="3" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"></feComposite>
<feColorMatrix values="0 0 0 0 0.454901961 0 0 0 0 0.6 0 0 0 0 0.992156863 0 0 0 0.3 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="搜索/首次登录弹框" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录提示" transform="translate(-655.000000, -402.000000)">
<g id="编组-8备份" transform="translate(500.000000, 120.000000)">
<g id="按钮" transform="translate(162.063866, 287.492764)">
<g id="矩形">
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
<use stroke="url(#linearGradient-2)" stroke-width="1" fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-3"></use>
</g>
<text id="我知道了" font-family="YouSheBiaoTiHei" font-size="24" font-weight="normal" fill="#FFFFFF">
<tspan x="32" y="32">我知道了</tspan>
</text>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710418001545" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16757" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1024 628.992l-256.448-224v125.12H384v197.824h383.616v125.056l256.384-224z m-384-354.88H256.384v-125.12L0 372.992l256.448 224v-125.056H640V274.112z" p-id="16758"></path></svg>

After

Width:  |  Height:  |  Size: 509 B

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" 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="16" height="16"></rect>
<path d="M1.23062252,0.07675 C0.311122521,0.3595 -0.205377479,1.33425 0.0773725213,2.254 L0.0773725213,2.254 L0.814122521,4.65125 L2.65962252,4.65125 L3.40287252,2.25225 C3.45437252,2.08575 3.48037252,1.9125 3.48037252,1.738 L3.48037252,1.738 C3.48037252,0.778 2.70237252,0 1.74262252,0 L1.74262252,0 C1.56912252,0 1.39637252,0.026 1.23062252,0.07675 L1.23062252,0.07675 Z" id="path-3"></path>
</defs>
<g id="搜索/首次登录弹框" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="index_1.0搜索_默认" transform="translate(-336.000000, -285.000000)">
<g id="编组-19" transform="translate(320.000000, 130.000000)">
<g id="编组-29" transform="translate(0.000000, 147.000000)">
<g id="任务审批" transform="translate(16.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g id="编组-2" mask="url(#mask-2)">
<g transform="translate(2.504695, 1.728956)">
<path d="M10.98479,12.0210444 C10.98479,12.2971868 10.7609324,12.5210444 10.48479,12.5210444 L0.532401515,12.5210444 L0.522,12.52 L0.510215659,12.5201602 C0.234073284,12.5201602 0.0102156588,12.2963026 0.0102156588,12.0201602 L0.00941441329,0.847060864 C0.00323761107,0.815662374 4.06696373e-18,0.783209279 0,0.75 L0,0.5 C-3.38176876e-17,0.223857625 0.223857625,5.07265313e-17 0.5,0 L4.75,0 C4.88807119,-2.53632657e-17 5,0.111928813 5,0.25 L5,1 C5,1.13807119 4.88807119,1.25 4.75,1.25 L1.26,1.25 L1.26,11.271 L9.734,11.271 L9.73449602,7.26969488 C9.73449602,7.13162369 9.84642483,7.01969488 9.98449602,7.01969488 L10.734496,7.01969488 C10.8725672,7.01969488 10.984496,7.13162369 10.984496,7.26969488 L10.98479,12.0210444 Z" id="形状结合" fill="#666666" transform="translate(5.492395, 6.260522) scale(1, -1) translate(-5.492395, -6.260522) "></path>
<path d="M7.84134673,4.52104444 C7.97941791,4.52104444 8.09134673,4.63297325 8.09134673,4.77104444 L8.09134673,5.52104444 C8.09134673,5.65911562 7.97941791,5.77104444 7.84134673,5.77104444 L2.24530486,5.77104444 C2.10723367,5.77104444 1.99530486,5.65911562 1.99530486,5.52104444 L1.99530486,4.77104444 C1.99530486,4.63297325 2.10723367,4.52104444 2.24530486,4.52104444 L7.84134673,4.52104444 Z M7.86057251,2.27715875 C7.99864369,2.27715875 8.11057251,2.38908757 8.11057251,2.52715875 L8.11057251,3.27715875 C8.11057251,3.41522994 7.99864369,3.52715875 7.86057251,3.52715875 L4.07979829,3.52715875 C3.9417271,3.52715875 3.82979829,3.41522994 3.82979829,3.27715875 L3.82979829,2.52715875 C3.82979829,2.38908757 3.9417271,2.27715875 4.07979829,2.27715875 L7.86057251,2.27715875 Z" id="形状结合" fill="#666666" transform="translate(5.052939, 4.024102) rotate(-180.000000) translate(-5.052939, -4.024102) "></path>
<g id="印章" stroke-width="1" fill="none" transform="translate(5.673315, 5.970411)">
<path d="M5.57,3.67563355 C5.84614237,3.67563355 6.07,3.89949117 6.07,4.17563355 L6.06594752,4.23229356 C6.06900137,4.25463739 6.07057905,4.27745123 6.07057905,4.30063355 L6.07057905,6.00221104 L6.06955159,6.03460166 C6.06984953,6.04168763 6.07,6.04881174 6.07,6.05597098 C6.07,6.33211336 5.84614237,6.55597098 5.57,6.55597098 L0.5,6.55597098 C0.223857625,6.55597098 3.38176876e-17,6.33211336 0,6.05597098 L0.000739837533,6.02964465 C0.000248730695,6.02056244 1.12725625e-18,6.01141579 0,6.00221104 L0,4.30063355 L0.00394400362,4.23873718 C0.00134118979,4.21806893 2.61759879e-18,4.19700786 0,4.17563355 C-3.38176876e-17,3.89949117 0.223857625,3.67563355 0.5,3.67563355 L5.57,3.67563355 Z M1,5.55563355 L5.07,5.55563355 L5.07,4.67563355 L1,4.67563355 L1,5.55563355 Z" id="形状结合" fill="#666666"></path>
<g id="编组" transform="translate(1.295103, 0.000000)">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Clip-2"></g>
<path d="M1.55297252,3.65125 L1.92247252,3.65125 L2.44747252,1.9565 C2.46947252,1.88575 2.48047252,1.81225 2.48047252,1.738 C2.48047252,1.331 2.14947252,1 1.74247252,1 C1.66847252,1 1.59497252,1.011 1.52397252,1.033 C1.13347252,1.153 0.912972521,1.569 1.03322252,1.96025 L1.55297252,3.65125 Z M3.39672252,5.65125 L0.0754725213,5.65125 L-0.878527479,2.54775 C-1.32252748,1.1025 -0.508277479,-0.43475 0.936722521,-0.879 C1.19872252,-0.95925 1.46972252,-1 1.74247252,-1 C3.25222252,-1 4.48047252,0.22825 4.48047252,1.738 C4.48047252,2.01275 4.43922252,2.28525 4.35797252,2.54775 L3.39672252,5.65125 Z" id="Fill-1" fill="#666666" mask="url(#mask-4)"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="49px" height="59px" viewBox="0 0 49 59" 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="32" height="32"></rect>
<filter x="-371.5%" y="-374.7%" width="843.0%" height="849.3%" filterUnits="objectBoundingBox" id="filter-3">
<feGaussianBlur stdDeviation="6.34032634" in="SourceGraphic"></feGaussianBlur>
</filter>
<rect id="path-4" x="0" y="0" width="28.4444444" height="28.2051282"></rect>
<linearGradient x1="105.502715%" y1="2.31847174%" x2="14.6827115%" y2="89.8245624%" id="linearGradient-6">
<stop stop-color="#94B3FF" offset="0%"></stop>
<stop stop-color="#3955FF" offset="100%"></stop>
</linearGradient>
<path d="M4.83555556,5.87512821 L4.83555556,15.2787179 C4.83555556,18.5223077 7.48942222,21.1538462 10.7605333,21.1538462 L22.6133333,21.1538462 C25.8844444,21.1538462 28.5383111,18.5223077 28.5383111,15.2787179 L28.5383111,5.87512821 C28.5383111,2.63153846 25.8844444,0 22.6133333,0 L10.7605333,0 C7.48942222,0 4.83555556,2.63153846 4.83555556,5.87512821 Z" id="path-7"></path>
<filter x="0.0%" y="0.0%" width="100.0%" height="100.0%" filterUnits="objectBoundingBox" id="filter-8">
<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>
<path d="M2.27555556,11.7982051 L2.27555556,21.2017949 C2.27555556,24.4453846 4.92942222,27.0769231 8.20053333,27.0769231 L20.0533333,27.0769231 C23.3244444,27.0769231 25.9783111,24.4453846 25.9783111,21.2017949 L25.9783111,11.7982051 C25.9783111,8.55461538 23.3244444,5.92307692 20.0533333,5.92307692 L8.20053333,5.92307692 C4.92942222,5.92307692 2.27555556,8.55461538 2.27555556,11.7982051 Z" id="path-9"></path>
<rect id="path-10" x="0" y="0" width="17.0666667" height="16.9230769"></rect>
<linearGradient x1="69.7214326%" y1="60.74758%" x2="-51.0955919%" y2="70.4452809%" id="linearGradient-12">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="搜索/首次登录弹框" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录提示" transform="translate(-588.000000, -281.000000)">
<g id="编组-8备份" transform="translate(500.000000, 120.000000)">
<g id="编组-51" transform="translate(77.063866, 161.492764)">
<g id="任务总数" transform="translate(11.000000, 0.000000)">
<g id="Group-194756" fill="#E9EEFF" fill-rule="nonzero">
<path d="M48,24 C48,37.2548455 37.2548455,48 24,48 C10.7451553,48 0,37.2548455 0,24 C0,10.7451553 10.7451553,0 24,0 C37.2548455,0 48,10.7451553 48,24 C48,24 48,24 48,24 Z" id="Ellipse-930"></path>
</g>
<g id="Group-1" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g transform="translate(0.888889, 1.777778)">
<path d="M14.5066667,24.2564103 C13.0929778,24.2564103 11.9466667,25.3930769 11.9466667,26.7948718 C11.9466667,28.1966667 13.0929778,29.3333333 14.5066667,29.3333333 C15.9203556,29.3333333 17.0666667,28.1966667 17.0666667,26.7948718 C17.0666667,25.3930769 15.9203556,24.2564103 14.5066667,24.2564103 Z" id="路径" fill="#8B9CFF" filter="url(#filter-3)"></path>
<g id="image-landscape-png-svgrepo-com(1)-1">
<mask id="mask-5" fill="white">
<use xlink:href="#path-4"></use>
</mask>
<g id="路径"></g>
<g id="路径" mask="url(#mask-5)">
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
<use fill="url(#linearGradient-6)" fill-rule="evenodd" xlink:href="#path-7"></use>
</g>
<path id="路径" d="M20.0533333,5.67307692 C23.462045,5.67307692 26.2283111,8.41606915 26.2283111,11.7982051 L26.2283111,11.7982051 L26.2283111,21.2017949 C26.2283111,24.5839308 23.462045,27.3269231 20.0533333,27.3269231 L20.0533333,27.3269231 L8.20053333,27.3269231 C4.79182166,27.3269231 2.02555556,24.5839308 2.02555556,21.2017949 L2.02555556,21.2017949 L2.02555556,11.7982051 C2.02555556,8.41606915 4.79182166,5.67307692 8.20053333,5.67307692 L8.20053333,5.67307692 Z M20.0533333,6.17307692 L8.20053333,6.17307692 C5.06702278,6.17307692 2.52555556,8.69316162 2.52555556,11.7982051 L2.52555556,11.7982051 L2.52555556,21.2017949 C2.52555556,24.3068384 5.06702278,26.8269231 8.20053333,26.8269231 L8.20053333,26.8269231 L20.0533333,26.8269231 C23.1868439,26.8269231 25.7283111,24.3068384 25.7283111,21.2017949 L25.7283111,21.2017949 L25.7283111,11.7982051 C25.7283111,8.69316162 23.1868439,6.17307692 20.0533333,6.17307692 L20.0533333,6.17307692 Z" fill="#FFFFFF" fill-rule="nonzero"></path>
<g id="收起" mask="url(#mask-5)">
<g transform="translate(5.688889, 8.038462)">
<mask id="mask-11" fill="white">
<use xlink:href="#path-10"></use>
</mask>
<g id="蒙版" stroke="none" fill="none"></g>
<path d="M14.8482532,1.96153846 L2.77396401,1.96153846 C2.65086938,1.96174328 2.53290922,2.01089215 2.44608611,2.09815093 C2.359263,2.18540971 2.31070509,2.30361448 2.31111367,2.42670874 L2.31111367,5.67748274 L15.3111035,5.67748274 L15.3111035,2.42670874 C15.3115121,2.30361448 15.2629542,2.18540971 15.1761311,2.09815093 C15.0893079,2.01089215 14.9713478,1.96174328 14.8482532,1.96153846 L14.8482532,1.96153846 Z M4.1594113,4.39961896 C3.83838548,4.39961896 3.57814264,4.13937581 3.57814264,3.81834961 C3.57814264,3.49732342 3.83838548,3.23708027 4.1594113,3.23708027 C4.48022339,3.23708027 4.74029297,3.49715016 4.74029297,3.81796263 C4.74029297,4.1387751 4.48022339,4.39884499 4.1594113,4.39884499 L4.1594113,4.39961896 Z M2.31111626,14.4963682 C2.31111626,14.7548821 2.51854636,14.9615385 2.77396401,14.9615385 L14.8459312,14.9615385 C14.9690255,14.9615385 15.087067,14.9125866 15.1740352,14.8254731 C15.2610034,14.7383596 15.3097584,14.6202365 15.3095536,14.4971422 L15.3095536,11.2463682 L2.31111626,11.2463682 L2.31111626,14.4971422 L2.31111626,14.4963682 Z M4.1594113,12.5242319 C4.48000965,12.5242319 4.73990597,12.7841286 4.73990597,13.1047273 C4.73990597,13.425326 4.48000965,13.6852227 4.1594113,13.6852227 C3.83881294,13.6852227 3.57891662,13.425326 3.57891662,13.1047273 C3.57891662,12.7841286 3.83881294,12.5242319 4.1594113,12.5242319 L4.1594113,12.5242319 Z M2.31111626,10.3183496 L15.3111009,10.3183496 L15.3111009,6.60472731 L2.31111626,6.60472731 L2.31111626,10.3191236 L2.31111626,10.3183496 Z M4.1594113,7.88026912 C4.48022338,7.88026912 4.74029295,8.140339 4.74029295,8.46115146 C4.74029295,8.78196392 4.48022338,9.0420338 4.1594113,9.0420338 C3.83881295,9.0420338 3.57891664,8.78213719 3.57891664,8.46153846 C3.57891664,8.14093974 3.83881295,7.88104312 4.1594113,7.88104312 L4.1594113,7.88026912 Z" id="形状" stroke="none" fill="url(#linearGradient-12)" fill-rule="evenodd" mask="url(#mask-11)"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.2 KiB

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="49px" height="57px" viewBox="0 0 49 57" 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="32" height="32"></rect>
<linearGradient x1="103.941749%" y1="-9.86447236%" x2="15.6759798%" y2="100%" id="linearGradient-3">
<stop stop-color="#94B3FF" offset="0%"></stop>
<stop stop-color="#3955FF" offset="100%"></stop>
</linearGradient>
<path d="M4.81965071,11.9835294 C4.81965071,18.6007843 10.107091,23.964183 16.6334651,23.964183 C23.1570041,23.964183 28.4444444,18.6007843 28.4444444,11.9835294 C28.4444444,5.36339869 23.1570041,0 16.6334651,0 C10.107091,0 4.81965071,5.36339869 4.81965071,11.9835294 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>
<rect id="path-6" x="0" y="0" width="28.3508865" height="28.7581699"></rect>
<path d="M2.26807092,15.4345098 C2.26807092,22.0517647 7.55551126,27.4151634 14.0818853,27.4151634 C20.6054243,27.4151634 25.8928647,22.0517647 25.8928647,15.4345098 C25.8928647,8.81437908 20.6054243,3.45098039 14.0818853,3.45098039 C7.55551126,3.45098039 2.26807092,8.81437908 2.26807092,15.4345098 Z" id="path-8"></path>
<linearGradient x1="50.4207596%" y1="35.9999974%" x2="1.68579345%" y2="100.000001%" id="linearGradient-9">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<filter x="-338.5%" y="-333.7%" width="776.9%" height="767.3%" filterUnits="objectBoundingBox" id="filter-10">
<feGaussianBlur stdDeviation="5.75725631" in="SourceGraphic"></feGaussianBlur>
</filter>
</defs>
<g id="搜索/首次登录弹框" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录提示" transform="translate(-840.000000, -281.000000)">
<g id="编组-8备份" transform="translate(500.000000, 120.000000)">
<g id="编组-29" transform="translate(329.063866, 161.492764)">
<g id="已审批" transform="translate(11.000000, 0.000000)">
<g id="Statistics/icon/down" fill-rule="nonzero">
<g id="Frame-4273186251">
<rect x="0" y="0" width="44" height="44"></rect>
<g id="Group-194756" fill="#E9EEFF">
<path d="M48,24 C48,37.2548455 37.2548455,48 24,48 C10.7451553,48 0,37.2548455 0,24 C0,10.7451553 10.7451553,0 24,0 C37.2548455,0 48,10.7451553 48,24 C48,24 48,24 48,24 Z" id="Ellipse-930"></path>
</g>
</g>
</g>
<g id="Group-1" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g transform="translate(0.888889, 1.777778)">
<g id="路径">
<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>
<g id="user-person-profile-block-account-circle-svgrepo-com-1" transform="translate(0.000000, 0.575163)">
<mask id="mask-7" fill="white">
<use xlink:href="#path-6"></use>
</mask>
<g id="路径"></g>
<path id="路径" d="M14.0818853,3.20098039 C20.7447477,3.20098039 26.1428647,8.67755358 26.1428647,15.4345098 C26.1428647,22.189044 20.7443,27.6651634 14.0818853,27.6651634 C7.41708336,27.6651634 2.01807092,22.1894977 2.01807092,15.4345098 C2.01807092,8.6770998 7.41663558,3.20098039 14.0818853,3.20098039 Z M14.0818853,3.70098039 C7.69438694,3.70098039 2.51807092,8.95165837 2.51807092,15.4345098 C2.51807092,21.9149209 7.69481587,27.1651634 14.0818853,27.1651634 C20.4665486,27.1651634 25.6428647,21.9144854 25.6428647,15.4345098 C25.6428647,8.9520939 20.4669775,3.70098039 14.0818853,3.70098039 Z" fill="#FFFFFF" fill-rule="nonzero"></path>
<g id="crowd" mask="url(#mask-7)">
<g transform="translate(6.992746, 8.243529)">
<rect id="矩形" fill="#000000" fill-rule="nonzero" opacity="0" x="0" y="0" width="14.1754433" height="14.379085"></rect>
<path d="M9.97279608,7.06413654 C11.7104753,7.06413654 13.1206339,8.48665684 13.1183622,10.2372746 C13.1138106,11.9833035 11.7059264,13.401235 9.97734498,13.4035294 C8.23966571,13.4035294 6.82950715,11.9833035 6.82950715,10.2326858 C6.82950715,8.48436245 8.23739126,7.06413654 9.97279608,7.06413654 Z M6.57931772,11.9465933 C6.70213798,12.2310974 6.85680054,12.4949519 7.04330538,12.738157 L1.11836495,12.738157 L1.11836495,11.9465933 L6.57931772,11.9465933 Z M11.232841,8.7711609 L9.59751195,10.5286618 L8.64451769,9.61090675 L8.06680757,10.1500878 L9.62253089,11.6987994 L11.8787846,9.41588381 L11.232841,8.7711609 Z M6.28136486,0.403529412 C7.88940052,0.403529412 9.19493442,1.72050788 9.19493442,3.3426399 C9.19493442,3.84969955 9.06756526,4.32693217 8.84466923,4.74221632 L8.84239478,4.7445107 C8.76278905,4.89135151 8.66726218,5.03130915 8.56491196,5.16438363 C8.1236688,5.87334939 7.72336572,6.43547435 7.9530851,7.11231868 C6.94322961,7.77769108 6.27454152,8.92717925 6.27454152,10.2326858 C6.27454152,10.4781853 6.29956046,10.4850684 6.342775,10.7168016 L1.11836495,10.7168016 L1.11836495,8.09431656 L4.00009222,8.09431656 C5.56718778,6.84846411 4.60964463,6.13261519 3.98871997,5.15291169 C3.60206359,4.6527352 3.36779531,4.02636739 3.36779531,3.3426399 C3.36779531,1.72050788 4.67332921,0.403529412 6.28136486,0.403529412 Z" id="形状结合" fill="url(#linearGradient-9)" fill-rule="evenodd"></path>
</g>
</g>
</g>
<path d="M15.5929876,24.1568627 C14.1839485,24.1568627 13.0414078,25.315817 13.0414078,26.745098 C13.0414078,28.1743791 14.1839485,29.3333333 15.5929876,29.3333333 C17.0020266,29.3333333 18.1445674,28.1743791 18.1445674,26.745098 C18.1445674,25.315817 17.0020266,24.1568627 15.5929876,24.1568627 Z" id="路径" fill="#8B9CFF" filter="url(#filter-10)"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="49px" height="58px" viewBox="0 0 49 58" 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="32" height="32"></rect>
<filter x="-333.3%" y="-329.7%" width="766.7%" height="759.4%" filterUnits="objectBoundingBox" id="filter-3">
<feGaussianBlur stdDeviation="5.68888889" in="SourceGraphic"></feGaussianBlur>
</filter>
<rect id="path-4" x="0" y="0" width="28.4444444" height="28.7581699"></rect>
<linearGradient x1="104.298352%" y1="-9.86447236%" x2="15.4490675%" y2="100%" id="linearGradient-6">
<stop stop-color="#94B3FF" offset="0%"></stop>
<stop stop-color="#3955FF" offset="100%"></stop>
</linearGradient>
<path d="M8.24888889,14.4509804 C8.24888889,17.1111111 10.3822222,19.2679739 13.0133333,19.2679739 L22.5422222,19.2679739 C25.1733333,19.2679739 27.3066667,17.1111111 27.3066667,14.4509804 L27.3066667,6.57986928 C27.3066667,5.81202614 27.0051556,5.07581699 26.4704,4.5351634 L22.8209778,0.845490196 C22.2862222,0.304836601 21.5580444,0 20.7985778,0 L13.0133333,0 C10.3822222,0 8.24888889,2.15686275 8.24888889,4.81699346 L8.24888889,14.4509804 Z" id="path-7"></path>
<filter x="0.0%" y="0.0%" width="100.0%" height="100.0%" filterUnits="objectBoundingBox" id="filter-8">
<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>
<path d="M17.9797339,2.39555169 L8.29440052,2.39555169 C5.02328941,2.39555169 2.36942274,5.07868895 2.36942274,8.38587849 L2.36942274,20.3694079 C2.36942274,23.6765974 5.02328941,26.3597347 8.29440052,26.3597347 L20.1472005,26.3597347 C23.4183116,26.3597347 26.0721783,23.6765974 26.0721783,20.3694079 L26.0721783,10.577251 C26.0721783,9.62535562 25.6967116,8.71084581 25.0311116,8.03502882 L20.4942227,3.44810071 C19.8257783,2.77515954 18.921245,2.39555169 17.9797339,2.39555169 Z" id="path-9"></path>
<linearGradient x1="50.361848%" y1="2.00025023%" x2="151.318564%" y2="221.000262%" id="linearGradient-10">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="搜索/首次登录弹框" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="登录提示" transform="translate(-714.000000, -281.000000)">
<g id="编组-8备份" transform="translate(500.000000, 120.000000)">
<g id="编组-28" transform="translate(203.063866, 161.492764)">
<g id="待审批" transform="translate(11.000000, 0.000000)">
<g id="Statistics/icon/down" fill-rule="nonzero">
<g id="Frame-4273186251">
<rect x="0" y="0" width="44" height="44"></rect>
<g id="Group-194756" fill="#E9EEFF">
<path d="M48,24 C48,37.2548455 37.2548455,48 24,48 C10.7451553,48 0,37.2548455 0,24 C0,10.7451553 10.7451553,0 24,0 C37.2548455,0 48,10.7451553 48,24 C48,24 48,24 48,24 Z" id="Ellipse-930"></path>
</g>
</g>
</g>
<g id="Group-1" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<g transform="translate(0.888889, 2.666667)">
<path d="M16.7822222,24.1568627 C15.3685333,24.1568627 14.2222222,25.315817 14.2222222,26.745098 C14.2222222,28.1743791 15.3685333,29.3333333 16.7822222,29.3333333 C18.1959111,29.3333333 19.3422222,28.1743791 19.3422222,26.745098 C19.3422222,25.315817 18.1959111,24.1568627 16.7822222,24.1568627 Z" id="路径" fill="#8B9CFF" filter="url(#filter-3)"></path>
<g id="save-disk-floppy-ram-svgrepo-com-1">
<mask id="mask-5" fill="white">
<use xlink:href="#path-4"></use>
</mask>
<g id="路径"></g>
<g id="路径" mask="url(#mask-5)">
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
<use fill="url(#linearGradient-6)" fill-rule="evenodd" xlink:href="#path-7"></use>
</g>
<path id="路径" d="M17.9797339,2.14555169 C18.9871909,2.14555169 19.9557498,2.55126075 20.6719663,3.27229619 L20.6719663,3.27229619 L25.2092296,7.85960364 C25.9214987,8.58280608 26.3221783,9.5605749 26.3221783,10.577251 L26.3221783,10.577251 L26.3221783,20.3694079 C26.3221783,23.8140585 23.5570004,26.6097347 20.1472005,26.6097347 L20.1472005,26.6097347 L8.29440052,26.6097347 C4.88460065,26.6097347 2.11942274,23.8140585 2.11942274,20.3694079 L2.11942274,20.3694079 L2.11942274,8.38587849 C2.11942274,4.94122789 4.88460065,2.14555169 8.29440052,2.14555169 L8.29440052,2.14555169 Z M17.9797339,2.64555169 L8.29440052,2.64555169 C5.16197817,2.64555169 2.61942274,5.21615001 2.61942274,8.38587849 L2.61942274,8.38587849 L2.61942274,20.3694079 C2.61942274,23.5391364 5.16197817,26.1097347 8.29440052,26.1097347 L8.29440052,26.1097347 L20.1472005,26.1097347 C23.2796229,26.1097347 25.8221783,23.5391364 25.8221783,20.3694079 L25.8221783,20.3694079 L25.8221783,10.577251 C25.8221783,9.69186875 25.4731404,8.84012 24.8533681,8.21083334 L24.8533681,8.21083334 L20.3168544,3.62428381 C19.6945858,2.99782912 18.8535856,2.64555169 17.9797339,2.64555169 L17.9797339,2.64555169 Z" fill="#FFFFFF" fill-rule="nonzero"></path>
<g id="编组" mask="url(#mask-5)" fill="url(#linearGradient-10)">
<g transform="translate(7.581848, 8.133875)" id="形状结合">
<path d="M1.27168236,9.74872441 C1.38004731,9.75547612 1.47988044,9.80980048 1.54440156,9.897125 C1.74565156,10.115 3.47552656,11.963 3.65052656,12.158125 L3.65052656,12.158125 L3.65140156,12.158125 C3.74585343,12.2464673 3.79508332,12.3717858 3.78482414,12.4995126 C3.77456496,12.6272394 3.70596377,12.7430936 3.59890156,12.8135 C3.34515156,13.02875 2.94790156,13.44 2.77640156,13.615 C2.60577656,13.789125 2.37215156,13.818875 2.14290156,13.54675 C1.91365156,13.2755 0.373651562,11.55 0.229276562,11.3855 C0.0849015624,11.221 -0.137348438,10.87275 0.113776562,10.66275 C0.276526562,10.527125 0.846151562,9.993375 0.982651562,9.862125 C1.05751317,9.78348476 1.16331742,9.7419727 1.27168236,9.74872441 Z M4.49752656,7.71925 C5.51690156,7.637 8.55052656,7.886375 9.21902656,7.912625 C9.88665156,7.93975 9.97240156,8.647625 9.37827656,8.729875 C8.71852656,8.820875 6.74277656,8.95125 6.57915156,9.004625 C6.41552656,9.058875 6.01302656,9.562875 7.04552656,9.680125 C7.92803767,9.80583465 8.81985007,9.85414359 9.71077656,9.8245 C10.1894016,9.751875 11.5202766,8.3755 11.9630266,8.054375 C12.2491516,7.846125 12.8354016,7.676375 13.0681516,8.103375 C13.1162766,8.190875 12.9509016,8.528625 12.7181516,8.763125 L12.7181516,8.763125 L12.3301924,9.15121508 C11.5222846,9.94975071 9.91449939,11.4733424 9.21552656,11.5955 C8.87707656,11.65465 8.28242656,11.63806 7.66229656,11.604026 L7.19602656,11.5761406 C6.42296406,11.52725 5.70021406,11.473875 5.47840156,11.529875 C5.13154085,11.6420437 4.80287874,11.804164 4.50277656,12.011125 L4.50277656,12.011125 L4.21315156,12.04 L2.03965156,9.71075 L1.98452656,9.449125 C1.98452656,9.449125 3.47815156,7.8015 4.49752656,7.71925 Z M10.8631516,0 C11.4345266,0 11.8982766,0.46375 11.8982766,1.035125 L11.8982766,7.251125 C11.8807766,7.261625 11.8641516,7.273875 11.8475266,7.286125 L9.14815156,7.142625 C8.98540156,7.135625 8.68090156,7.1155 8.29590156,7.090125 C7.35002656,7.028 5.92115156,6.9335 5.02252656,6.9335 C4.81252656,6.9335 4.64015156,6.93875 4.50977656,6.94925 C3.62414273,7.10535297 2.79688788,7.49706736 2.11490156,8.08325 C2.06754065,7.96407046 2.04315156,7.83699514 2.04315156,7.70875 L2.04315156,1.035125 C2.04315156,0.46375 2.50690156,0.000875 3.07827656,0 L10.8631516,0 Z M8.98890156,3.67675 L4.90265156,3.67675 C4.67697421,3.67675 4.49402656,3.85969764 4.49402656,4.085375 C4.49402656,4.31105236 4.67697421,4.494 4.90265156,4.494 L8.98890156,4.494 C9.21457892,4.494 9.39752656,4.31105236 9.39752656,4.085375 C9.39752656,3.85969764 9.21457892,3.67675 8.98890156,3.67675 Z M8.98890156,1.633625 L4.90265156,1.633625 C4.67697421,1.633625 4.49402656,1.81657264 4.49402656,2.04225 C4.49402656,2.26792736 4.67697421,2.450875 4.90265156,2.450875 L8.98890156,2.450875 C9.21457892,2.450875 9.39752656,2.26792736 9.39752656,2.04225 C9.39752656,1.81657264 9.21457892,1.633625 8.98890156,1.633625 Z"></path>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

@ -0,0 +1,128 @@
<script setup lang="ts">
import { ref } from "vue";
const value = ref("");
const showList = ref(false);
const handlerShowList = () => (showList.value = true);
const mock_list = [
{
title: "任务审批管理",
data: [
{
title: "某某企业名称占位-1月拜访计划计划",
},
{
title: "某某企业名称占位符占位占位-12月拜访计划计划",
},
{
title: "某某企业-某某事业部-第四季度拜访计划计划",
},
],
},
{
title: "任务终审管理",
data: [
{
title: "某某企业名称占位-1月拜访计划计划",
},
{
title: "某某企业名称占位符占位占位-12月拜访计划计划",
},
{
title: "某某企业名称占位符占位占位-12月拜访计划计划",
},
],
},
];
</script>
<template>
<div class="input_wrap">
<div class="ip_box">
<img src="../../assets/images/IP.png" alt="">
</div>
<div class="input_box">
<n-input
v-model:value="value"
placeholder="搜索任务ID、任务名称、提报人、拜访终端"
type="text"
@mousedown="handlerShowList"
>
<template #prefix>
<SvgIcon name="magnifying-1" size="18"></SvgIcon>
</template>
</n-input>
</div>
<div class="list_box" v-show="showList">
<div
class="list_classfiy_item"
v-for="(item, index) in mock_list"
:key="index"
:style="(index == mock_list.length-1)?'':'border-bottom:1px solid #e4e4e4'"
>
<div class="list_title">{{ item.title }}</div>
<div class="list_item" v-for="(sitem,sindex) in item.data" :key="sindex">
<SvgIcon name="task-icon" size="16"></SvgIcon>
<a style="margin-left: 5px">{{ sitem.title }}</a>
</div>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.input_wrap {
width: 60%;
position: absolute;
top: 20%;
left: 20%;
.ip_box{
z-index: 0;
position: relative;
left: calc(50% - 40px);
top: 30px;
img{
width: 80px;
height: 80px;
}
}
.input_box {
z-index: 1;
background: #ffffff;
border: 1px solid #507afd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0px 12px 12px 0px rgba(80, 122, 253, 0.15),
0px 0px 0px 0.5px #d4e3fc;
}
.list_box {
background: #fefefe;
border: 1px dashed #f4f4f4;
border-radius: 8px;
box-shadow: 0px 12px 12px 0px rgba(80, 122, 253, 0.15);
margin-top: 15px;
padding: 8px 16px;
.list_classfiy_item {
.list_title {
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
color: #999999;
line-height: 17px;
margin: 10px 0 10px 5px;
}
.list_item {
display: flex;
flex-flow: row nowrap;
align-items: center;
margin-bottom: 10px;
}
}
}
}
:deep(.n-input .n-input-wrapper) {
margin: 8px;
}
</style>

@ -7,6 +7,7 @@ export interface RowData {
fromuptime: string fromuptime: string
updatetime: string updatetime: string
title: string title: string
fromtaskid: string
} }
export interface ColumnEntity { export interface ColumnEntity {

@ -88,6 +88,70 @@ export const workPackageMap: Recordable<PackageEntity> = {
}, },
} }
// 自定义填报信息配置
export const ReportInfoConfig: Recordable<PackageEntity> = {
terminalName: {
label: '拜访终端名称',
isDefault: false,
key: 'upuser',
},
location: {
label: '定位信息',
isDefault: false,
key: 'upuser',
},
visitTime: {
label: '拜访日期',
isDefault: false,
key: 'upuser',
},
distance: {
label: '定位距离',
isDefault: false,
key: 'upuser',
},
visitSum: {
label: '拜访小结',
isDefault: false,
key: 'upuser',
},
projectClassfiy: {
label: '拜访项目类别',
isDefault: false,
key: 'upuser',
},
departName: {
label: '科室名称',
isDefault: false,
key: 'upuser',
},
caseNum: {
label: '病例号',
isDefault: false,
key: 'upuser',
},
level: {
label: '拜访级别',
isDefault: false,
key: 'upuser',
},
isRepeatPic: {
label: '是否为重复图片',
isDefault: false,
key: 'upuser',
},
fileName: {
label: '字段名称',
isDefault: false,
key: 'upuser',
},
fileInfo: {
label: '附件信息',
isDefault: false,
key: 'upuser',
},
}
export const fieldMap = { export const fieldMap = {
field1: '提报人', field1: '提报人',
field2: '拜访客户类型', field2: '拜访客户类型',

@ -144,8 +144,10 @@ function downHandler(event: MouseEvent) {
if (!selectionBox) if (!selectionBox)
return return
selectIds.value.length = 0 const classname = (event.target as any).className
if (!classname.includes('checkbox')) {
selectIds.value.length = 0
start = { x: event.clientX, y: event.clientY } start = { x: event.clientX, y: event.clientY }
selectionBox.style.width = '0' selectionBox.style.width = '0'
selectionBox.style.height = '0' selectionBox.style.height = '0'
@ -154,6 +156,7 @@ function downHandler(event: MouseEvent) {
selectionBox.style.display = 'block' selectionBox.style.display = 'block'
selectionBox.style.zIndex = '9999' selectionBox.style.zIndex = '9999'
} }
}
function imUpdateSelectIds(x: number, y: number, w: number, h: number) { function imUpdateSelectIds(x: number, y: number, w: number, h: number) {
const items = document.querySelectorAll('.grid-item') const items = document.querySelectorAll('.grid-item')
@ -238,6 +241,11 @@ function closeModal(event: MouseEvent) {
defineExpose({ defineExpose({
showModal, showModal,
}) })
const checked = ref(false)
function onCheckChange(val: any, item: any) {
checked.value = val
}
</script> </script>
<template> <template>
@ -295,6 +303,11 @@ defineExpose({
class="wrapper-content-item-img" class="wrapper-content-item-img"
:class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl"
> >
<n-checkbox
v-model:checked="item.checked"
style="position:absolute;left:20px;top:20px" @click.prevent
@update:checked="onCheckChange($event, item)"
/>
</div> </div>
</div> </div>
<!-- </n-scrollbar> --> <!-- </n-scrollbar> -->
@ -421,6 +434,7 @@ defineExpose({
.scroll { .scroll {
overflow-y: scroll; overflow-y: scroll;
height: calc(100vh - 282px); height: calc(100vh - 282px);
background-color: aqua;
} }
} }
} }

@ -0,0 +1,22 @@
<template>
<div>
<n-modal v-model:show="show" :mask="false" transform-origin="center">
<Search />
</n-modal>
</div>
</template>
<script setup>
import Search from "@/components/Search/Search.vue";
import { ref } from "vue";
const show = ref(false);
function showModal() {
show.value = true;
}
defineExpose({
showModal,
});
</script>
<style scoped lang="less">
</style>

@ -19,7 +19,6 @@ function handleSelect(key: string) {
} }
function logIt(e) { function logIt(e) {
// console.log('e:', e)
return false return false
} }

@ -1,17 +1,24 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, reactive, ref, toRefs, unref, watch } from 'vue' import { useUser } from "@/store/modules/user";
import { useRoute, useRouter } from 'vue-router' import { getImgUrl } from "@/utils/urlUtils";
import { useDialog, useMessage } from 'naive-ui' import { useDialog, useMessage } from "naive-ui";
import UserSettings from './UserSettings.vue' import { defineComponent, reactive, ref, toRefs, unref, watch } from "vue";
import QuillModal from './QuillModal.vue' import { useRoute, useRouter } from "vue-router";
import ShortcutModal from './ShortcutModal.vue' import QuillModal from "./QuillModal.vue";
import RecycleModal from './RecycleModal.vue' import RecycleModal from "./RecycleModal.vue";
import { useUser } from '@/store/modules/user' import SearchModal from "./SearchModal.vue";
import { getImgUrl } from '@/utils/urlUtils' import ShortcutModal from "./ShortcutModal.vue";
import UserSettings from "./UserSettings.vue";
export default defineComponent({ export default defineComponent({
name: 'PageHeader', name: "PageHeader",
components: { UserSettings, QuillModal, ShortcutModal, RecycleModal }, components: {
UserSettings,
QuillModal,
ShortcutModal,
RecycleModal,
SearchModal,
},
props: { props: {
collapsed: { collapsed: {
type: Boolean, type: Boolean,
@ -20,102 +27,108 @@ export default defineComponent({
type: Boolean, type: Boolean,
}, },
}, },
emits: ['update:collapsed'], emits: ["update:collapsed"],
setup() { setup() {
const message = useMessage() const message = useMessage();
const dialog = useDialog() const dialog = useDialog();
const userStore = useUser() const userStore = useUser();
const useInfo = userStore.getUserInfo const useInfo = userStore.getUserInfo;
const name = '' const name = "";
const state = reactive({ const state = reactive({
username: name ?? '', username: name ?? "",
fullscreenIcon: 'FullscreenOutlined', fullscreenIcon: "FullscreenOutlined",
}) });
const router = useRouter() const router = useRouter();
const route = useRoute() const route = useRoute();
const routename = ref(route.meta.title) const routename = ref(route.meta.title);
watch( watch(
() => route.fullPath, () => route.fullPath,
() => { () => {
routename.value = route.meta.title routename.value = route.meta.title;
}, }
) );
const dropdownSelect = (key) => { const dropdownSelect = (key) => {
router.push({ name: key }) router.push({ name: key });
} };
// 退 // 退
const doLogout = () => { const doLogout = () => {
dialog.info({ dialog.info({
title: '提示', title: "提示",
content: '您确定要退出登录吗', content: "您确定要退出登录吗",
positiveText: '确定', positiveText: "确定",
negativeText: '取消', negativeText: "取消",
onPositiveClick: () => { onPositiveClick: () => {
userStore.logout().then(() => { userStore.logout().then(() => {
message.success('成功退出登录') message.success("成功退出登录");
router router
.replace({ .replace({
name: 'Login', name: "Login",
query: { query: {
redirect: route.fullPath, redirect: route.fullPath,
}, },
}) })
.finally(() => location.reload()) .finally(() => location.reload());
}) });
}, },
onNegativeClick: () => {}, onNegativeClick: () => {},
}) });
} };
const quillModalRef = ref(null) const quillModalRef = ref(null);
const shortcutModal = ref(null) const shortcutModal = ref(null);
const recycleModalRef = ref(null) const recycleModalRef = ref(null);
const SearchModalRef = ref(null);
function quillHandler() { function quillHandler() {
const modal = unref(quillModalRef)! as any const modal = unref(quillModalRef)! as any;
modal.showModal() modal.showModal();
} }
function shortcutHandler() { function shortcutHandler() {
const modal = unref(shortcutModal)! as any const modal = unref(shortcutModal)! as any;
modal.showModal() modal.showModal();
} }
function recycleHandler() { function recycleHandler() {
const modal = unref(recycleModalRef)! as any const modal = unref(recycleModalRef)! as any;
modal.showModal() modal.showModal();
}
function searchHandler() {
const modal = unref(SearchModalRef)! as any;
modal.showModal();
} }
// //
const iconList = [ const iconList = [
{ {
icon: 'magnifying-1', icon: "magnifying-1",
handle: quillHandler, handle: searchHandler,
}, },
{ {
icon: 'shortcut-keys', icon: "shortcut-keys",
handle: shortcutHandler, handle: shortcutHandler,
}, },
{ {
icon: 'suspicious-folder', icon: "suspicious-folder",
handle: recycleHandler, handle: recycleHandler,
}, },
{ {
icon: 'memo', icon: "memo",
handle: quillHandler, handle: quillHandler,
}, },
{ {
icon: 'newmessage', icon: "newmessage",
handle: shortcutHandler, handle: shortcutHandler,
}, },
] ];
return { return {
...toRefs(state), ...toRefs(state),
@ -126,14 +139,16 @@ export default defineComponent({
quillModalRef, quillModalRef,
shortcutModal, shortcutModal,
recycleModalRef, recycleModalRef,
SearchModalRef,
searchHandler,
quillHandler, quillHandler,
shortcutHandler, shortcutHandler,
recycleHandler, recycleHandler,
useInfo, useInfo,
getImgUrl, getImgUrl,
} };
}, },
}) });
</script> </script>
<template> <template>
@ -151,7 +166,11 @@ export default defineComponent({
<div>当前位置{{ routename }}</div> <div>当前位置{{ routename }}</div>
</div> </div>
<div class="layout-header-right"> <div class="layout-header-right">
<div v-for="item in iconList" :key="item.icon" class="layout-header-trigger layout-header-trigger-min"> <div
v-for="item in iconList"
:key="item.icon"
class="layout-header-trigger layout-header-trigger-min"
>
<div class="back" @click="item.handle"> <div class="back" @click="item.handle">
<SvgIcon :name="item.icon" size="18" /> <SvgIcon :name="item.icon" size="18" />
</div> </div>
@ -167,6 +186,7 @@ export default defineComponent({
<RecycleModal ref="recycleModalRef" /> <RecycleModal ref="recycleModalRef" />
<QuillModal ref="quillModalRef" /> <QuillModal ref="quillModalRef" />
<ShortcutModal ref="shortcutModal" /> <ShortcutModal ref="shortcutModal" />
<SearchModal ref="SearchModalRef" />
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
@ -267,7 +287,9 @@ export default defineComponent({
} }
.layout-header-left { .layout-header-left {
::v-deep(.n-breadcrumb .n-breadcrumb-item:last-child .n-breadcrumb-item__link) { ::v-deep(
.n-breadcrumb .n-breadcrumb-item:last-child .n-breadcrumb-item__link
) {
color: #515a6e; color: #515a6e;
} }
} }

@ -1,6 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { TaskState } from '/#/task' import type { TaskState } from '/#/task'
import { useMessage } from 'naive-ui'
import { getApprovalList } from '@/api/task/task' import { getApprovalList } from '@/api/task/task'
import { store } from '@/store' import { store } from '@/store'
@ -11,6 +10,8 @@ export const useTaskStore = defineStore({
activeId: '', activeId: '',
approvalList: [], approvalList: [],
packageid: '', packageid: '',
refresh: false,
immersion: false,
}), }),
getters: { getters: {
getActiveId: (state: TaskState) => state.activeId, getActiveId: (state: TaskState) => state.activeId,
@ -30,30 +31,33 @@ export const useTaskStore = defineStore({
}, },
forward() { forward() {
const len = this.approvalList.length const len = this.approvalList.length
const message = useMessage()
if (this.currentIndex === len - 1) if (this.currentIndex === len - 1)
message.error('已经到达最后一个') return
this.setActive(++this.currentIndex) this.setActive(++this.currentIndex)
}, },
back() { back() {
const message = useMessage()
if (this.currentIndex === 0) if (this.currentIndex === 0)
message.error('已经到达第一个') return
this.setActive(--this.currentIndex) this.setActive(--this.currentIndex)
}, },
async fetchApprovalList(pagination, id) { async fetchApprovalList(pagination, id, refresh?: boolean) {
const res = await getApprovalList(pagination, id) const res = await getApprovalList(pagination, id)
this.setApprovalList(res.data) this.setApprovalList(res.data)
if (res.data.length > 0) if (res.data.length > 0) {
this.setActive(0) this.setActive(0)
// 审批操作完成后需要刷新为防止activeId在刷新后值不变通过此值刷新
this.refresh = !this.refresh
}
return res.data return res.data
}, },
updateImmersion() {
this.immersion = !this.immersion
},
reset() { reset() {
this.currentIndex = -1 this.currentIndex = -1
this.activeId = '' this.activeId = ''

@ -1,20 +1,21 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { PackageListItem, PackageState } from '/#/workorder' import type { OrderState, PackageListItem } from '/#/workorder'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { getPackageList } from '@/api/work/work' import { getPackageList } from '@/api/work/work'
import { store } from '@/store' import { store } from '@/store'
export const useWorkOrderStore = defineStore({ export const useWorkOrderStore = defineStore({
id: 'work-order', id: 'work-order',
state: (): PackageState => ({ state: (): OrderState => ({
currentIndex: -1, currentIndex: -1,
activeId: '', activeId: '',
packageList: [], packageList: [],
immersion: false,
}), }),
getters: { getters: {
getActiveId: (state: PackageState) => state.activeId, getActiveId: (state: OrderState) => state.activeId,
getCurrentIndex: (state: PackageState) => state.currentIndex, getCurrentIndex: (state: OrderState) => state.currentIndex,
getOrderList: (state: PackageState) => state.packageList, getOrderList: (state: OrderState) => state.packageList,
}, },
actions: { actions: {
setOrderList(list: PackageListItem[]) { setOrderList(list: PackageListItem[]) {
@ -44,12 +45,16 @@ export const useWorkOrderStore = defineStore({
}, },
async fetchOrderList(pagination) { async fetchOrderList(pagination) {
const res = await getPackageList(pagination) const res = await getPackageList(pagination)
this.setOrderList(res.data)
if (res.data.length > 0) if (res.data.length > 0) {
this.setOrderList(res.data)
this.setActive(0) this.setActive(0)
}
return res.data return res
},
updateImmersion() {
this.immersion = !this.immersion
}, },
reset() { reset() {
this.currentIndex = -1 this.currentIndex = -1

@ -201,7 +201,6 @@ const transform: AxiosTransform = {
// eslint-disable-next-line ts/no-use-before-define // eslint-disable-next-line ts/no-use-before-define
const instance = http.getAxios() const instance = http.getAxios()
const config = response.config const config = response.config
const whitelist = ['/api/captcha/captchatoken', '/api/captcha/captchaImage', '/api/backstage/adminlogin', '/api/oauthweb/token'] const whitelist = ['/api/captcha/captchatoken', '/api/captcha/captchaImage', '/api/backstage/adminlogin', '/api/oauthweb/token']
const expirationTime = storage.get(TOKEN_EXPIRATION_TIME) const expirationTime = storage.get(TOKEN_EXPIRATION_TIME)
// console.log('剩余失效时间(分):', (expirationTime - Date.now()) / 1000 / 60, config.url) // console.log('剩余失效时间(分):', (expirationTime - Date.now()) / 1000 / 60, config.url)

@ -0,0 +1,17 @@
import { nextTick, unref } from 'vue'
import { useConfig } from '@/store/modules/asideConfig'
const downloadSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 1024 1024"><path fill="currentColor" d="M505.7 661a8 8 0 0 0 12.6 0l112-141.7c4.1-5.2.4-12.9-6.3-12.9h-74.1V168c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v338.3H400c-6.7 0-10.4 7.7-6.3 12.9l112 141.8zM878 626h-60c-4.4 0-8 3.6-8 8v154H214V634c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v198c0 17.7 14.3 32 32 32h684c17.7 0 32-14.3 32-32V634c0-4.4-3.6-8-8-8z"></path></svg>'
export function hideDownload(e: MouseEvent) {
nextTick(() => {
const configStore = useConfig()
const downloadEle: any = document.querySelector('.n-image-preview-toolbar')?.children[5]
const asideValue = unref(configStore.getAsideValue)
const download = asideValue?.izimgdownload
if (downloadEle && downloadEle.innerHTML === downloadSvg && download === false)
downloadEle.style.display = 'none'
else
downloadEle.style.display = 'block'
})
}

@ -47,7 +47,7 @@ defineExpose({
</div> </div>
<div class="wrapper-header"> <div class="wrapper-header">
<span style="font-weight: bold;">任务小结重复任务</span> <span style="font-weight: bold;">任务小结重复任务</span>
<span><font class="count">18</font></span> <span><span class="count">18</span></span>
</div> </div>
<div class="wrapper-content"> <div class="wrapper-content">
<n-scrollbar style="max-height: 200px;"> <n-scrollbar style="max-height: 200px;">
@ -64,7 +64,7 @@ defineExpose({
<span style="color:#8b8d8f;">任务重复数量</span> <span style="color:#8b8d8f;">任务重复数量</span>
</n-gi> </n-gi>
<n-gi span="8"> <n-gi span="8">
<span><font class="count">18</font></span> <span><span class="count">18</span></span>
</n-gi> </n-gi>
</n-grid> </n-grid>
</div> </div>

@ -13,7 +13,7 @@ const emit = defineEmits<{
(e: 'commit', columns: any[]) (e: 'commit', columns: any[])
}>() }>()
const show = ref(true) const show = ref(false)
function showModal() { function showModal() {
show.value = true show.value = true
@ -184,19 +184,19 @@ function approvalHandler() {
function rejectHandler(idOrDesc: string, isOther: boolean) { function rejectHandler(idOrDesc: string, isOther: boolean) {
// TODO: // TODO:
const param: ApprovalParam = { // const param: ApprovalParam = {
formid: '', // formid: '',
taskId: '', // taskId: '',
approvd: false, // approvd: false,
taskComment: '', // taskComment: '',
} // }
if (isOther) // if (isOther)
param.taskComment = idOrDesc // param.taskComment = idOrDesc
else // else
param.taskComment = idOrDesc // param.taskComment = idOrDesc
audit(param) // audit(param)
} }
query(pagination.page, pagination.pageSize) query(pagination.page, pagination.pageSize)

@ -1,16 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, h, nextTick, onMounted, reactive, ref, unref } from 'vue' import { computed, h, nextTick, onMounted, reactive, ref, unref } from 'vue'
import { NDataTable, useDialog } from 'naive-ui' import { NDataTable, useDialog, useMessage } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui' import type { DataTableColumns, DataTableRowKey, PaginationProps } from 'naive-ui'
import { Action, CustomTabelModal, ImportExcelModal, RejectModal, RepeatModal, RepeatTaskTableModal } from '../comp' import { Action, CustomTabelModal, ImportExcelModal, RepeatModal, RepeatTaskTableModal } from '../comp'
import ConfrimModal from '@/views/task/modal/ConfrimModal.vue'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset } from '@/utils/domUtils' import { getViewportOffset } from '@/utils/domUtils'
import type { RowData } from '@/config/final' import type { RowData } from '@/config/final'
import { findKey, headRules } from '@/config/final' import { findKey, headRules } from '@/config/final'
import { getFinalList } from '@/api/final' import { getFinalList } from '@/api/final'
import { isBoolean } from '@/utils/is' import { isBoolean } from '@/utils/is'
import { useUser } from '@/store/modules/user'
import type { ApprovalParam } from '/#/api' import type { ApprovalParam } from '/#/api'
import { audit } from '@/api/task/task' import { audit } from '@/api/task/task'
import SvgIcon from '@/components/Icon/SvgIcon.vue'
const columns: DataTableColumns<RowData> = [ const columns: DataTableColumns<RowData> = [
{ {
@ -28,7 +31,7 @@ const columns: DataTableColumns<RowData> = [
title: '任务名称', title: '任务名称',
key: 'fromtaskname', key: 'fromtaskname',
fixed: 'left', fixed: 'left',
width: 200, width: 150,
}, },
{ {
title: '审批节点', title: '审批节点',
@ -39,16 +42,43 @@ const columns: DataTableColumns<RowData> = [
title: '审批状态', title: '审批状态',
key: 'states', key: 'states',
width: 100, width: 100,
sorter: 'default',
renderSorterIcon: ({ order }) => {
if (order === false)
return h(SvgIcon, { name: 'sort-2' })
if (order === 'ascend')
return h(SvgIcon, { name: 'sort-1' })
if (order === 'descend')
return h(SvgIcon, { name: 'sort-3' })
},
}, },
{ {
title: '图片相似度', title: '图片相似度',
key: 'similarity', key: 'similarity',
width: 100, width: 150,
sorter: 'default',
renderSorterIcon: ({ order }) => {
if (order === false)
return h(SvgIcon, { name: 'sort-2' })
if (order === 'ascend')
return h(SvgIcon, { name: 'sort-1' })
if (order === 'descend')
return h(SvgIcon, { name: 'sort-3' })
},
}, },
{ {
title: '提报时间', title: '提报时间',
key: 'fromuptime', key: 'fromuptime',
width: 200, width: 200,
sorter: 'default',
renderSorterIcon: ({ order }) => {
if (order === false)
return h(SvgIcon, { name: 'sort-2' })
if (order === 'ascend')
return h(SvgIcon, { name: 'sort-1' })
if (order === 'descend')
return h(SvgIcon, { name: 'sort-3' })
},
}, },
{ {
title: '更新时间', title: '更新时间',
@ -92,9 +122,12 @@ const pagination = reactive({
}) })
const tableData = ref<Array<RowData>>([]) const tableData = ref<Array<RowData>>([])
const selectionIds = ref<DataTableRowKey[]>([]) const selectionIds = ref<DataTableRowKey[]>([])
const userStore = useUser()
const dialog = useDialog()
const message = useMessage()
async function query(page: number, pageSize: number) { async function query(page: number, pageSize: number) {
const result = await getFinalList({ sortorder: 'asc', pageSize: 10, currPage: 1, sortname: '' }) const result = await getFinalList({ sortorder: 'asc', pageSize, currPage: page, sortname: '' })
const { data, pageCount } = result const { data, pageCount } = result
tableData.value = data tableData.value = data
pagination.page = page pagination.page = page
@ -212,7 +245,6 @@ function actionHandler(action: any) {
const { key } = action const { key } = action
switch (key) { switch (key) {
case 'view': case 'view':
break break
case 'reset': case 'reset':
resetHandler() resetHandler()
@ -221,14 +253,35 @@ function actionHandler(action: any) {
approvalHandler() approvalHandler()
break break
case 'reject': case 'reject':
showModal(rejectModalRef) rejectHandler()
break break
default: default:
break break
} }
} }
const dialog = useDialog() // states:1234
function validate(items: any[]) {
if (items.length === 0)
return '至少选中一个任务'
const useInfo = userStore.getUserInfo
const username = useInfo.loginname
for (const item of items) {
const { iztrueorfalse, states, assignee } = item
if (iztrueorfalse === null)
return '未判别真假'
else if (states !== 2)
return '审批状态不合法'
else if (assignee !== username)
return '审批人不一致'
}
return null
}
function resetHandler() { function resetHandler() {
dialog.info({ dialog.info({
@ -244,34 +297,89 @@ function resetHandler() {
}) })
} }
function getSelectItems() {
return tableData.value.filter(item => selectionIds.value.includes(item.id))
}
function approvalHandler() { function approvalHandler() {
const items = getSelectItems()
const msg = validate(items)
if (msg !== null) {
message.error(msg)
return
}
dialog.info({ dialog.info({
title: '确认提示', title: '确认提示',
content: '确认给该任务审批为【通过】吗?', content: '确认给该任务审批为【通过】吗?',
positiveText: '确定', positiveText: '确定',
negativeText: '取消', negativeText: '取消',
onPositiveClick: () => { onPositiveClick: () => {
// TODO approval(items)
}, },
onNegativeClick: () => { }, onNegativeClick: () => { },
}) })
} }
function rejectHandler(idOrDesc: string, isOther: boolean) { function approval(items) {
// TODO: const formIds: string[] = items.map(item => item.id)
const taskIds: string[] = items.map(item => item.taskId)
const tasknames: string[] = items.map(item => item.taskname)
const param: ApprovalParam = { const param: ApprovalParam = {
formid: '', formid: formIds,
taskId: '', taskId: taskIds,
approvd: true,
taskComment: 'approval',
taskname: tasknames,
}
doAudit(param)
}
function rejectHandler() {
const items = getSelectItems()
const msg = validate(items)
if (msg !== null) {
message.error(msg)
return
}
const modal = unref(rejectModalRef)! as any
modal.showModal()
}
function reject(idOrDesc: string, backId: string, isOther: boolean) {
const items = getSelectItems()
const formIds: string[] = items.map(item => item.id)
const taskIds: string[] = items.map(item => item.fromtaskid)
const tasknames: string[] = items.map(item => item.fromtaskname)
const param: ApprovalParam = {
formid: formIds,
taskId: taskIds,
approvd: false, approvd: false,
taskComment: '', taskComment: idOrDesc,
taskname: isOther ? tasknames : ['其他'],
} }
if (isOther) doAudit(param)
param.taskComment = idOrDesc }
else
param.taskComment = idOrDesc function doAudit(param: any) {
audit(param).then((res) => {
const { code } = res
if (code === 'OK')
reload()
else message.error(res.message)
})
}
audit(param) function reload() {
const { page, pageSize } = unref(tableRef.value?.pagination) as PaginationProps
query(page!, pageSize!)
} }
</script> </script>
@ -337,7 +445,7 @@ function rejectHandler(idOrDesc: string, isOther: boolean) {
<CustomTabelModal ref="customTabelRef" @commit="commitHandler" /> <CustomTabelModal ref="customTabelRef" @commit="commitHandler" />
<ImportExcelModal ref="importExcelRef" :on-success="sucessHandler" :header-config="headRules" /> <ImportExcelModal ref="importExcelRef" :on-success="sucessHandler" :header-config="headRules" />
<RejectModal ref="rejectModalRef" @commit="rejectHandler" /> <ConfrimModal ref="rejectModalRef" @commit="reject" />
<RepeatModal ref="repeatModalRef" @reject="showModal(rejectModalRef)" @viewrepeat="showModal(repeatTaskTableModalRef)" /> <RepeatModal ref="repeatModalRef" @reject="showModal(rejectModalRef)" @viewrepeat="showModal(repeatTaskTableModalRef)" />
<RepeatTaskTableModal ref="repeatTaskTableModalRef" /> <RepeatTaskTableModal ref="repeatTaskTableModalRef" />
</div> </div>

@ -5,6 +5,7 @@ import { debounce } from 'lodash-es'
import { asideMap } from '@/config/aside' import { asideMap } from '@/config/aside'
import { favorite, getConditionList, unfavorite } from '@/api/home/filter' import { favorite, getConditionList, unfavorite } from '@/api/home/filter'
import type { Filter, FilterEntity } from '/#/home' import type { Filter, FilterEntity } from '/#/home'
import type { FilterSearchParam } from '/#/api'
defineOptions({ name: 'AdvanceFilter' }) defineOptions({ name: 'AdvanceFilter' })
@ -17,17 +18,17 @@ const emit = defineEmits<{
const data = ref<FilterEntity[]>([]) const data = ref<FilterEntity[]>([])
let loading = false let loading = false
let lastPostion = 0 const canloadMore = true
let canloadMore = true
const el = ref<HTMLDivElement | null>(null) const el = ref<HTMLDivElement | null>(null)
const popover = ref<ComponentRef | null>(null) const popover = ref<ComponentRef | null>(null)
const pagination = reactive({ const pagination = reactive({
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 300,
}) })
const keyword = ref('')
onMounted(() => { onMounted(() => {
data.value = generateDefaultConfig() // data.value = generateDefaultConfig()
}) })
// //
@ -58,30 +59,29 @@ useInfiniteScroll(
() => { () => {
loadMore() loadMore()
}, },
{ distance: 10, interval: 3000, canLoadMore: () => canloadMore }, { distance: 10, interval: 300, canLoadMore: () => false },
) )
async function loadMore() { async function loadMore() {
if (loading || el.value == null) if (loading || el.value == null)
return return
lastPostion = el.value!.scrollTop
const more = await featchList() const more = await featchList()
if (more.length === 0) if (more.length === 0)
return return
data.value.push(...more) data.value.push(...more)
el.value?.scrollTo(0, lastPostion)
} }
async function featchList() { async function featchList() {
loading = true loading = true
try { try {
const result = await getConditionList({ ...pagination }) const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
const { data, pageCount } = result const result = await getConditionList(pagination, searchParam)
pagination.pageNo += 1 const { data } = result
canloadMore = pageCount >= pagination.pageNo // pagination.pageNo += 1
// canloadMore = pageCount >= pagination.pageNo
const entityList = generateFilterEntityList(data) const entityList = generateFilterEntityList(data)
return entityList return entityList
} }
@ -107,9 +107,12 @@ function generateFilterEntityList(data) {
} }
}) })
const reg = new RegExp(keyword.value, 'gi')
const hilightText = searchname.replace(reg, `<span style='color:#FF0000'>${keyword.value}</span>`)
return { return {
id, id,
name: searchname, name: hilightText,
favorite: iztop, favorite: iztop,
isDefaultFilter: false, isDefaultFilter: false,
filterList: list, filterList: list,
@ -124,8 +127,11 @@ function selectHandler(item: FilterEntity) {
emit('select', item.filterList) emit('select', item.filterList)
} }
const inputHandler = debounce((keyword) => { const inputHandler = debounce((word) => {
// keyword.value = word
featchList().then((list) => {
data.value = list
})
}, 300) }, 300)
function favoriteHandler(event: MouseEvent, item: any) { function favoriteHandler(event: MouseEvent, item: any) {
@ -181,7 +187,7 @@ function unFavoriteHandler(event: MouseEvent, item) {
<li v-for="(item, index) in data" :key="index" style="display: flex;align-items: center;" @click="selectHandler(item)"> <li v-for="(item, index) in data" :key="index" style="display: flex;align-items: center;" @click="selectHandler(item)">
<SvgIcon v-if="item.favorite && !item.isDefaultFilter" name="favorite-fill" color="#fd9b0a" size="18" @click="unFavoriteHandler($event, item)" /> <SvgIcon v-if="item.favorite && !item.isDefaultFilter" name="favorite-fill" color="#fd9b0a" size="18" @click="unFavoriteHandler($event, item)" />
<SvgIcon v-else-if="!item.favorite && !item.isDefaultFilter" name="favorite-unfill" size="18" @click="favoriteHandler($event, item)" /> <SvgIcon v-else-if="!item.favorite && !item.isDefaultFilter" name="favorite-unfill" size="18" @click="favoriteHandler($event, item)" />
{{ item.name }} <div v-html="item.name" />
</li> </li>
</ul> </ul>
</div> </div>

@ -15,19 +15,10 @@ const emit = defineEmits<{
const data = ref<SearchEntity[]>([]) const data = ref<SearchEntity[]>([])
const popover = ref<ComponentRef | null>(null) const popover = ref<ComponentRef | null>(null)
const configStore = useConfig() const configStore = useConfig()
let cacheData = [] const searchKeyword = ref('')
const inputHandler = debounce((keyword) => { const inputHandler = debounce((keyword) => {
if (keyword === '') { searchKeyword.value = keyword
data.value = cacheData
return
}
const result = data.value.filter((item) => {
return item.label.includes(keyword)
})
data.value = result
}, 300) }, 300)
configStore.$subscribe(() => { configStore.$subscribe(() => {
@ -48,7 +39,6 @@ configStore.$subscribe(() => {
}) })
data.value = list data.value = list
cacheData = list
}) })
function selectHandler(item: SearchEntity) { function selectHandler(item: SearchEntity) {
@ -72,7 +62,7 @@ function selectHandler(item: SearchEntity) {
</template> </template>
<div class="wrapper-popover"> <div class="wrapper-popover">
<ul class="wrapper-list"> <ul class="wrapper-list">
<li v-for="(item, index) in data" :key="index" @click="selectHandler(item)"> <li v-for="(item, index) in data" v-show="item.label.includes(searchKeyword)" :key="index" @click="selectHandler(item)">
{{ item.label }} {{ item.label }}
</li> </li>
</ul> </ul>

@ -1,12 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { GlobalThemeOverrides, UploadCustomRequestOptions } from 'naive-ui' import type { GlobalThemeOverrides, UploadCustomRequestOptions } from 'naive-ui'
import { computed, ref } from 'vue' import { computed, ref, unref } from 'vue'
import { useElementHover } from '@vueuse/core' import { useElementHover } from '@vueuse/core'
import { useThemeVars } from 'naive-ui' import { useThemeVars } from 'naive-ui'
import { upload } from '@/api/home/main' import { upload } from '@/api/home/main'
import { getImgUrl } from '@/utils/urlUtils' import { getImgUrl } from '@/utils/urlUtils'
import { useConfig } from '@/store/modules/asideConfig'
defineOptions({ name: 'Upload' }) import { hideDownload } from '@/utils/image'
const props = defineProps<{ const props = defineProps<{
value: string value: string
@ -16,6 +16,8 @@ const emit = defineEmits<{
(e: 'update:value', value: string): void (e: 'update:value', value: string): void
}>() }>()
const configStore = useConfig()
const figureUrl = ref(props.value) const figureUrl = ref(props.value)
async function customRequest(data: UploadCustomRequestOptions) { async function customRequest(data: UploadCustomRequestOptions) {
@ -70,7 +72,7 @@ const imageGroupThemeOverrides = computed(() => {
<span class="wrapper-tip2">上传格式为.png .jpg .bmp 20M以内</span> <span class="wrapper-tip2">上传格式为.png .jpg .bmp 20M以内</span>
</div> </div>
<div v-show="showFigure" ref="figureRef" class="wrapper-figure"> <div v-show="showFigure" ref="figureRef" class="wrapper-figure">
<n-image ref="imageRef" :theme-overrides="imageGroupThemeOverrides" width="288" height="116" :src="figureUrl" /> <n-image ref="imageRef" :img-props="{ onClick: hideDownload }" :theme-overrides="imageGroupThemeOverrides" width="288" height="116" :src="figureUrl" />
<div v-show="figureHovered" class="wrapper-figure-tools"> <div v-show="figureHovered" class="wrapper-figure-tools">
<SvgIcon size="28" name="view" @click="previewHandler" /> <SvgIcon size="28" name="view" @click="previewHandler" />
<div class="wrapper-figure-line" /> <div class="wrapper-figure-line" />

@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, defineOptions, ref, watch } from 'vue' import { computed, defineOptions, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus' import { VueDraggable } from 'vue-draggable-plus'
import { difference } from 'lodash-es' import { clone, debounce, difference } from 'lodash-es'
import { setFilter } from '@/api/home/filter' import { setFilter } from '@/api/home/filter'
import { asideMap } from '@/config/aside' import { asideMap } from '@/config/aside'
import { useConfig } from '@/store/modules/asideConfig' import { useConfig } from '@/store/modules/asideConfig'
@ -11,6 +11,7 @@ defineOptions({ name: 'CustomFilterModal' })
const show = ref(false) const show = ref(false)
const configStore = useConfig() const configStore = useConfig()
const checkAll = ref(false) const checkAll = ref(false)
const selectIds = ref<string[]>([])
function showModal() { function showModal() {
show.value = true show.value = true
@ -72,12 +73,16 @@ function generatList(config, customConfig) {
// Y // Y
if (!isDefaultFilter) { if (!isDefaultFilter) {
const isChecked = asideMap[key].isDefaultFilter || showKeys.includes(key)
offList.push({ offList.push({
id: key, id: key,
name: name || '未配置', name: name || '未配置',
fix: isDefaultFilter, fix: isDefaultFilter,
checked: asideMap[key].isDefaultFilter, checked: isChecked,
}) })
isChecked && selectIds.value.push(key)
} }
} }
@ -125,8 +130,6 @@ async function handleSumbit(e: MouseEvent) {
closeModal() closeModal()
} }
const selectIds = ref<string[]>([])
function onCheckAllChange(value) { function onCheckAllChange(value) {
const ids: string[] = [] const ids: string[] = []
@ -228,10 +231,21 @@ function removeHandler(id: string) {
if (index !== -1) if (index !== -1)
onList.value.splice(index, 1) onList.value.splice(index, 1)
} }
const offKeyword = ref('')
const onKeyword = ref('')
const leftInputHandler = debounce((keyword) => {
offKeyword.value = keyword
}, 300)
const rightInputHandler = debounce((keyword) => {
onKeyword.value = keyword
}, 300)
</script> </script>
<template> <template>
<n-modal v-model:show="show" transform-origin="center"> <n-modal v-model:show="show" transform-origin="center" :mask-closable="false">
<n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true"> <n-card class="cardstyle" :bordered="false" size="huge" role="dialog" aria-modal="true">
<div class="wrapper"> <div class="wrapper">
<span class="wrapper-title">自定义筛选</span> <span class="wrapper-title">自定义筛选</span>
@ -241,14 +255,14 @@ function removeHandler(id: string) {
</div> </div>
</div> </div>
<n-grid cols="2" class="mt-4 proCard" responsive="screen" :x-gap="24"> <n-grid cols="24" class="mt-4 proCard" responsive="screen" :x-gap="24">
<n-grid-item> <n-grid-item span="11">
<NCard <NCard
:title="allCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small" :title="allCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:bordered="false" :bordered="false"
> >
<div> <div>
<n-input placeholder="搜索关键字"> <n-input placeholder="搜索关键字" @input="leftInputHandler">
<template #suffix> <template #suffix>
<SvgIcon size="14px" name="magnifying-1" /> <SvgIcon size="14px" name="magnifying-1" />
</template> </template>
@ -259,7 +273,7 @@ function removeHandler(id: string) {
<n-checkbox v-model:checked="checkAll" label="全部" @update:checked="onCheckAllChange" /> <n-checkbox v-model:checked="checkAll" label="全部" @update:checked="onCheckAllChange" />
</div> </div>
<div <div
v-for="item in offList" :key="item.id" :class="{ 'disable-check': item.fix }" v-for="item in offList" v-show="item.name.includes(offKeyword)" :key="item.id" :class="{ 'disable-check': item.fix }"
class="draggable-li" class="draggable-li"
> >
<n-checkbox <n-checkbox
@ -272,7 +286,10 @@ function removeHandler(id: string) {
</div> </div>
</NCard> </NCard>
</n-grid-item> </n-grid-item>
<n-grid-item> <n-grid-item style="display: flex;align-items: center;" span="2">
<SvgIcon size="20" name="switchsvg" />
</n-grid-item>
<n-grid-item span="11">
<NCard <NCard
:title="selectCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small" :title="selectCount" class="dragcardStyle" :segmented="{ content: true, footer: true }" size="small"
:bordered="false" :bordered="false"
@ -281,7 +298,7 @@ function removeHandler(id: string) {
<span class="textbtnStyle" @click="clearDragSource"></span> <span class="textbtnStyle" @click="clearDragSource"></span>
</template> </template>
<div> <div>
<n-input placeholder="搜索关键字"> <n-input placeholder="搜索关键字" @input="rightInputHandler">
<template #suffix> <template #suffix>
<SvgIcon size="14px" name="magnifying-1" /> <SvgIcon size="14px" name="magnifying-1" />
</template> </template>
@ -289,9 +306,10 @@ function removeHandler(id: string) {
<n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll"> <n-scrollbar style="max-height: 500px;border: 1px solid #cad2dd;border-radius: 2px;" class="scroll">
<VueDraggable v-model="onList" class="draggable-ul" :animation="150" group="shared"> <VueDraggable v-model="onList" class="draggable-ul" :animation="150" group="shared">
<div <div
v-for="item in onList" :key="item.id" :class="{ fix: item.fix }" v-for="item in onList" v-show="item.name.includes(onKeyword)" :key="item.id" :class="{ fix: item.fix }"
class="cursor-move draggable-li" class="cursor-move draggable-li"
> >
<SvgIcon name="drag" size="24" />
<span class="ml-2">{{ item.name }}</span> <span class="ml-2">{{ item.name }}</span>
<SvgIcon <SvgIcon
v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;" v-if="!item.fix" size="16px" style="display:block;margin-left: auto;cursor: pointer;"
@ -363,6 +381,7 @@ function removeHandler(id: string) {
.cardstyle { .cardstyle {
width: 620px; width: 620px;
height: 800px;
--n-padding-bottom: 20px; --n-padding-bottom: 20px;
--n-padding-left: 24px; --n-padding-left: 24px;
} }

@ -4,8 +4,10 @@ import { NDataTable } from 'naive-ui'
import type { DataTableColumns, DataTableRowKey } from 'naive-ui' import type { DataTableColumns, DataTableRowKey } from 'naive-ui'
import type { SortableEvent } from 'sortablejs' import type { SortableEvent } from 'sortablejs'
import Sortable from 'sortablejs' import Sortable from 'sortablejs'
import { debounce } from 'lodash-es'
import Action from '../Action.vue' import Action from '../Action.vue'
import { deleteCondition, getConditionList, sort } from '@/api/home/filter' import { deleteCondition, getConditionList, sort } from '@/api/home/filter'
import type { FilterSearchParam } from '/#/api'
defineOptions({ name: 'FilterModal' }) defineOptions({ name: 'FilterModal' })
@ -79,12 +81,14 @@ const loading = ref(true)
const pagination = reactive({ const pagination = reactive({
page: 1, page: 1,
pageCount: 1, pageCount: 1,
pageSize: 10, pageSize: 2,
}) })
const tableData = ref<Array<RowData>>([]) const tableData = ref<Array<RowData>>([])
const keyword = ref('')
async function query(page: number, pageSize: number) { async function query(page: number, pageSize: number) {
const result = await getConditionList({ pageNo: page, pageSize }) const searchParam: FilterSearchParam = { search_searchname: { value: keyword.value, op: 'like', type: 'string' } }
const result = await getConditionList({ pageNo: page, pageSize }, searchParam)
const { data, pageCount } = result const { data, pageCount } = result
tableData.value = data tableData.value = data
pagination.page = page pagination.page = page
@ -232,6 +236,11 @@ function closeModal() {
defineExpose({ defineExpose({
showModal, showModal,
}) })
const inputHandler = debounce((word) => {
keyword.value = word
query(1, 10)
}, 300)
</script> </script>
<template> <template>
@ -249,7 +258,7 @@ defineExpose({
</div> </div>
</div> </div>
<div class="wrapper-form"> <div class="wrapper-form">
<n-input :style="{ width: '360px', border: '1px solid #cad2dd' }" placeholder="请输入过滤条件名称搜索"> <n-input :style="{ width: '360px', border: '1px solid #cad2dd' }" placeholder="请输入过滤条件名称搜索" @input="inputHandler">
<template #suffix> <template #suffix>
<SvgIcon size="14px" name="magnifying-1" /> <SvgIcon size="14px" name="magnifying-1" />
</template> </template>

@ -1,25 +1,26 @@
<script lang="ts" setup> <script lang="ts" setup>
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 } from 'lodash-es'
import imagesloaded from 'imagesloaded'
import { useMessage } from 'naive-ui'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import { timeOptions, viewOptions } from '@/config/home'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset } from '@/utils/domUtils'
import { notEmpty, randomInt } from '@/utils/index'
import { getPictureList, oneClickCheck } from '@/api/home/main' import { getPictureList, oneClickCheck } from '@/api/home/main'
import img1 from '@/assets/images/1.jpg' import img1 from '@/assets/images/1.jpg'
import img2 from '@/assets/images/2.jpg' import img2 from '@/assets/images/2.jpg'
import img3 from '@/assets/images/3.jpg' import img3 from '@/assets/images/3.jpg'
import img4 from '@/assets/images/4.jpg' import img4 from '@/assets/images/4.jpg'
import img5 from '@/assets/images/5.jpg' import img5 from '@/assets/images/5.jpg'
import { timeOptions, viewOptions } from '@/config/home'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { useConfig } from '@/store/modules/asideConfig' import { useConfig } from '@/store/modules/asideConfig'
import { getViewportOffset } from '@/utils/domUtils'
import { hideDownload } from '@/utils/image'
import { randomInt } from '@/utils/index'
import emitter from '@/utils/mitt' import emitter from '@/utils/mitt'
import { getImgUrl } from '@/utils/urlUtils' import { getImgUrl } from '@/utils/urlUtils'
import { useInfiniteScroll } from '@vueuse/core'
import imagesloaded from 'imagesloaded'
import { debounce } from 'lodash-es'
import Masonry from 'masonry-layout'
import { useMessage } from 'naive-ui'
import { computed, nextTick, onBeforeMount, onMounted, onUnmounted, onUpdated, reactive, ref, unref, watch } from 'vue'
import GeneratePackageModal from './modal/GeneratePackageModal.vue'
import PackageSettingsModal from './modal/PackageSettingsModal.vue'
const deviceHeight = ref(600) const deviceHeight = ref(600)
let _masonry: null | Masonry = null let _masonry: null | Masonry = null
@ -34,6 +35,7 @@ const pagination = reactive({
const configStore = useConfig() const configStore = useConfig()
const packageModalRef = ref(null) const packageModalRef = ref(null)
const generateModalRef = ref(null) const generateModalRef = ref(null)
const LoginSuccessModalRef = ref(null)
const loading = ref(false) const loading = ref(false)
const message = useMessage() const message = useMessage()
@ -176,10 +178,8 @@ async function featchList() {
} }
async function loadMore() { async function loadMore() {
if (loading.value || el.value == null) { if (loading.value || el.value == null)
// console.log('....')
return return
}
const more = await featchList() const more = await featchList()
listData.value.push(...more) listData.value.push(...more)
@ -199,6 +199,11 @@ async function oneCheck() {
modal.showModal() modal.showModal()
} }
async function showLoginSuccessModal(){
const modal = LoginSuccessModalRef.value as any
modal.showModal()
}
async function commitHandler(settingParam) { async function commitHandler(settingParam) {
const contentParams = { const contentParams = {
search_month: timeRange.value, search_month: timeRange.value,
@ -226,6 +231,8 @@ onMounted(() => {
nextTick(() => { nextTick(() => {
computeListHeight() computeListHeight()
//
showLoginSuccessModal()
}) })
}) })
@ -300,10 +307,11 @@ async function refreshHandler() {
<div ref="masonryRef" class="grid"> <div ref="masonryRef" class="grid">
<div v-for="(item, index) in listData" :key="index" :style="{ height: gridHeight }" class="grid-item"> <div v-for="(item, index) in listData" :key="index" :style="{ height: gridHeight }" class="grid-item">
<!-- <div :style="{ 'background-color': randomColor(0.2) }" class="wrapper-content-item-img" /> --> <!-- <div :style="{ 'background-color': randomColor(0.2) }" class="wrapper-content-item-img" /> -->
<img <!-- <img
class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" class="wrapper-content-item-img" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }"
:src="item.imgUrl" :src="item.imgUrl"
> > -->
<n-image class="wrapper-content-item-img" :img-props="{ onClick: hideDownload }" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl" />
<div class="wrapper-content-item-info"> <div class="wrapper-content-item-info">
<div class="wrapper-content-item-info-left"> <div class="wrapper-content-item-info-left">
<n-avatar :src="getImgUrl(item.uphead)" class="wrapper-content-item-info-avatar" round /> <n-avatar :src="getImgUrl(item.uphead)" class="wrapper-content-item-info-avatar" round />
@ -322,6 +330,7 @@ async function refreshHandler() {
</div> </div>
<PackageSettingsModal ref="packageModalRef" @commit="commitHandler" /> <PackageSettingsModal ref="packageModalRef" @commit="commitHandler" />
<GeneratePackageModal ref="generateModalRef" /> <GeneratePackageModal ref="generateModalRef" />
<LoginSuccessModal ref="LoginSuccessModalRef" />
</div> </div>
</template> </template>

@ -0,0 +1,191 @@
<script lang="ts" setup>
import { ref } from "vue";
const emit = defineEmits<{
(e: "reject", params: any);
(e: "viewrepeat");
}>();
const show = ref(false);
function showModal() {
show.value = true;
}
function closeModal() {
show.value = false;
}
async function reject() {
emit("reject", { a: "todo" });
closeModal();
}
async function viewRepeat(e: MouseEvent) {
emit("viewrepeat");
e.preventDefault();
closeModal();
}
defineExpose({
showModal,
});
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" class="modal_wrap">
<div class="wrapper">
<div class="wrapper-hearder">
<div class="wrapper-title">欢迎登录智能AI审批工具</div>
<div class="wrapper-mark">某某有限公司-某某事业部-张小凡</div>
</div>
<div class="wrapper-content">
<div class="flex_box" style="height: 100px">
<div class="item">
<SvgIcon name="task_count" width="80" height="96" />
<div class="num_box">6399</div>
<div class="title_box">任务总数</div>
</div>
<div class="item">
<SvgIcon name="task_wait" width="80" height="96" />
<div class="num_box">6290</div>
<div class="title_box">待审批</div>
</div>
<div class="item">
<SvgIcon name="task_over" width="80" height="96" />
<div class="num_box">109</div>
<div class="title_box">已审批</div>
</div>
</div>
<div class="footer">
<SvgIcon
@click="viewRepeat"
style="cursor: pointer"
name="login_r"
width="200"
height="70"
/>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="less" scoped>
.modal_wrap {
background-image: url(../../../../assets/images/approval_modal_bg.png);
background-repeat: no-repeat;
background-size: 100%;
width: 700px;
height: 500px;
box-shadow: none !important;
}
.wrapper {
position: absolute;
left: calc(50% - 350px);
.wrapper-hearder {
margin-top: 110px;
.wrapper-title {
text-align: center;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Semibold;
font-weight: Semibold;
text-align: center;
color: #333333;
line-height: 32px;
}
.wrapper-mark {
text-align: center;
font-size: 13px;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Regular;
font-weight: Regular;
text-align: center;
color: #666666;
line-height: 18px;
}
}
.wrapper-content {
flex: 1;
border-radius: 8px;
margin: 100px 60px 35px 120px;
.flex_box {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: space-between;
.item {
.num_box {
font-size: 32px;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Bold;
font-weight: Bold;
text-align: left;
color: #202020;
text-align: center;
}
.title_box {
opacity: 0.6;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: center;
color: #202020;
text-align: center;
}
}
}
.imgwrapper {
width: 200px;
height: 120px;
margin-right: 20px;
border-radius: 8px;
background-image: url("../../../assets/images/test.png");
background-repeat: no-repeat;
background-size: cover;
}
.content {
.task_id {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
.tag_box {
display: flex;
flex-flow: row nowrap;
margin: 8px 0;
.tag_item {
background: rgba(80, 122, 253, 0.1);
border-radius: 2px;
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #507afd;
line-height: 16px;
margin-right: 10px;
}
}
.time_box {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
}
.footer {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
margin: 20px 30px 0 0;
position: relative;
bottom: -80px;
}
}
}
</style>

@ -1,10 +1,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onBeforeMount, reactive, ref } from 'vue'
import TaskList from './TaskList.vue'
import type { TaskListItem } from '/#/task'
import { useTaskStore } from '@/store/modules/task' import { useTaskStore } from '@/store/modules/task'
import { useUser } from '@/store/modules/user' import { useUser } from '@/store/modules/user'
import emitter from '@/utils/mitt'
import { computed, onBeforeMount, onMounted, onUnmounted, reactive, ref, unref, watch } from 'vue'
import TaskList from './TaskList.vue'
import type { TaskListItem } from '/#/task'
const CustomFieldModalRef = ref(null);
const collapse = ref(false) const collapse = ref(false)
const taskStore = useTaskStore() const taskStore = useTaskStore()
const userStore = useUser() const userStore = useUser()
@ -48,6 +52,31 @@ const asideEnter = ref(false)
const showCollapse = computed(() => { const showCollapse = computed(() => {
return collapse.value ? true : asideEnter.value return collapse.value ? true : asideEnter.value
}) })
onMounted(() => {
emitter.on('refresh', refreshHandler)
})
onUnmounted(() => {
emitter.off('refresh', refreshHandler)
})
async function refreshHandler() {
pagination.pageNo = 1
pagination.pageSize = 10
const id = userStore.getUserInfo.id
const orderList = await taskStore.fetchApprovalList(pagination, id)
data.value = orderList
}
watch(() => taskStore.immersion, () => {
collapse.value = true
})
const showFilterModal = ()=>{
const modal = unref(CustomFieldModalRef)! as any;
modal.showModal();
}
</script> </script>
<template> <template>
@ -64,10 +93,11 @@ const showCollapse = computed(() => {
</div> </div>
<div class="aside-header-right"> <div class="aside-header-right">
<SvgIcon size="18" name="magnifying-1" /> <SvgIcon size="18" name="magnifying-1" />
<SvgIcon style="margin-left: 10px;" size="18" name="filter" /> <SvgIcon style="margin-left: 10px;cursor: pointer;" size="18" name="filter" @click="showFilterModal"/>
</div> </div>
</div> </div>
<TaskList style="height: calc(100vh - 146px);" class="work-sheet-list" :data="data" :active-id="taskStore.getActiveId" /> <TaskList style="height: calc(100vh - 146px);" class="work-sheet-list" :data="data" :active-id="taskStore.getActiveId!" />
<CustomFieldModal ref="CustomFieldModalRef" />
</div> </div>
</template> </template>

@ -1,15 +1,19 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue' import { audit } from '@/api/task/task'
import { useDialog, useMessage } from 'naive-ui' import { getTaskDetailInfo, getTaskDetailPictureList } from '@/api/work/work'
import { useTask } from '@/store/modules/task'
import { useUser } from '@/store/modules/user'
import { hideDownload } from '@/utils/image'
import emitter from '@/utils/mitt'
import { clone } from 'lodash-es' import { clone } from 'lodash-es'
import ConfrimModal from '../modal/ConfrimModal.vue' import { useDialog, useMessage } from 'naive-ui'
import { computed, onUnmounted, reactive, ref, unref, watch } from 'vue'
import BatchModal from '../modal/BatchModal.vue' import BatchModal from '../modal/BatchModal.vue'
import TaskTable from './TaskTable.vue' import ConfrimModal from '../modal/ConfrimModal.vue'
import CustomSettingModal from '../modal/CustomSettingModal.vue'
import PictureTable from './PictureTable.vue' import PictureTable from './PictureTable.vue'
import { useTask } from '@/store/modules/task' import TaskTable from './TaskTable.vue'
import { audit } from '@/api/task/task'
import type { ApprovalParam, PictureSortParam } from '/#/api' import type { ApprovalParam, PictureSortParam } from '/#/api'
import { getTaskDetailInfo, getTaskDetailPictureList } from '@/api/work/work'
const batch = ref(false) const batch = ref(false)
const selectItems = ref<any[]>([]) const selectItems = ref<any[]>([])
@ -18,34 +22,33 @@ const dialog = useDialog()
const confrimModalRef = ref(null) const confrimModalRef = ref(null)
const batchModalRef = ref(null) const batchModalRef = ref(null)
const totalCount = ref(0) const totalCount = ref(0)
const CustomSettingModalRef = ref(null);
const sortBy: PictureSortParam = { const sortBy: PictureSortParam = {
orderbyname: 'asc', orderbyname: "asc",
orderbyvalue: 'fromuptime', orderbyvalue: "fromuptime",
} };
function setBatch(value: boolean) { function setBatch(value: boolean) {
batch.value = value batch.value = value;
if (value === false) { if (value === false) {
selectItems.value.forEach(item => item.checked = false) selectItems.value.forEach((item) => (item.checked = false));
selectItems.value.length = 0 selectItems.value.length = 0;
} }
} }
function onCheckChange(checked: any, item: any) { function onCheckChange(checked: any, item: any) {
const index = selectItems.value.indexOf(item) const index = selectItems.value.indexOf(item);
item.checked = checked item.checked = checked;
if (index === -1 && checked)
selectItems.value.push(item)
else if (index === -1 && checked) selectItems.value.push(item);
selectItems.value.splice(index, 1) else selectItems.value.splice(index, 1);
} }
const showActions = computed(() => { const showActions = computed(() => {
return selectItems.value.length > 0 && batch return selectItems.value.length > 0 && batch;
}) });
const taskpagination = reactive({ const taskpagination = reactive({
pageNo: 1, pageNo: 1,
@ -55,28 +58,34 @@ const taskStore = useTask()
const overTask = ref<any>(null) const overTask = ref<any>(null)
const taskDetailInfo = ref<any>({}) const taskDetailInfo = ref<any>({})
const taskDetailPictureList = ref<any[]>([]) const taskDetailPictureList = ref<any[]>([])
const userStore = useUser()
const imageRef = ref<ComponentElRef | null>()
let processItems: any[] = [] let processItems: any[] = []
// states:1234
function validate(items: any[]) { function validate(items: any[]) {
if (items.length === 0) if (items.length === 0)
return '至少选中一个任务' return '至少选中一个任务'
const useInfo = userStore.getUserInfo
const username = useInfo.loginname
for (const item of items) { for (const item of items) {
// const { iztrueorfalse, history, states } = item const { iztrueorfalse, states, assignee } = item
// if (iztrueorfalse !== null) if (iztrueorfalse === null)
// return '' return '未判别真假'
// else if (history) else if (states !== 2)
// return '' return '审批状态不合法'
// else if (states !== 1 && states !== 2) else if (assignee !== username)
// return '' return '审批人不一致'
} }
return null return null
} }
function approvalHandler() { function approvalHandler(items?: any) {
let cloneItem: any let cloneItem: any
if (batch.value) { processItems = selectItems.value } if (batch.value) { processItems = selectItems.value }
else if (overTask.value) { else if (overTask.value) {
@ -84,6 +93,9 @@ function approvalHandler() {
processItems = [cloneItem] processItems = [cloneItem]
} }
if (items !== undefined && !(items instanceof PointerEvent))
processItems = items
const msg = validate(processItems) const msg = validate(processItems)
if (msg !== null) { if (msg !== null) {
@ -103,13 +115,17 @@ function approvalHandler() {
}) })
} }
function rejectHandler() { function rejectHandler(items?: any) {
let cloneItem: any let cloneItem: any
if (batch.value) { processItems = selectItems.value } if (batch.value) { processItems = selectItems.value }
else if (overTask.value) { else if (overTask.value) {
cloneItem = clone(overTask.value) cloneItem = clone(overTask.value)
processItems = [cloneItem] processItems = [cloneItem]
} }
if (items !== undefined && !(items instanceof PointerEvent))
processItems = items
const msg = validate(processItems) const msg = validate(processItems)
if (msg !== null) { if (msg !== null) {
@ -123,23 +139,33 @@ function rejectHandler() {
function approval() { function approval() {
const formIds: string[] = processItems.map(item => item.id) const formIds: string[] = processItems.map(item => item.id)
const taskIds: string[] = processItems.map(item => item.taskid) const taskIds: string[] = processItems.map(item => item.taskId)
const tasknames: string[] = processItems.map(item => item.taskname) const tasknames: string[] = processItems.map(item => item.taskname)
const param: ApprovalParam = { const param: ApprovalParam = {
formid: formIds, formid: formIds,
taskId: taskIds, taskId: taskIds,
approvd: true, approvd: true,
taskComment: '', taskComment: 'approval',
taskname: tasknames, taskname: tasknames,
} }
audit(param) doAudit(param)
}
function doAudit(param: any) {
audit(param).then((res) => {
const { code } = res
processItems.length = 0
if (code === 'OK')
emitter.emit('refresh')
else message.error(res.message)
})
} }
function reject(idOrDesc: string, backId: string, isOther: boolean) { function reject(idOrDesc: string, backId: string, isOther: boolean) {
const formIds: string[] = processItems.map(item => item.id) const formIds: string[] = processItems.map(item => item.id)
const taskIds: string[] = processItems.map(item => item.taskid) const taskIds: string[] = processItems.map(item => item.taskId)
const tasknames: string[] = processItems.map(item => item.taskname) const tasknames: string[] = processItems.map(item => item.taskname)
const param: ApprovalParam = { const param: ApprovalParam = {
@ -150,25 +176,29 @@ function reject(idOrDesc: string, backId: string, isOther: boolean) {
taskname: isOther ? tasknames : ['其他'], taskname: isOther ? tasknames : ['其他'],
} }
audit(param) doAudit(param)
} }
function showModal(modalRef: any) { function showModal(modalRef: any) {
const modal = unref(modalRef)! as any const modal = unref(modalRef)! as any;
modal.showModal() modal.showModal();
} }
function forwardHandler() { function forwardHandler() {
taskStore.forward() taskStore.forward();
} }
function backHandler() { function backHandler() {
taskStore.back() taskStore.back();
} }
watch(() => taskStore.activeId, async (newValue, oldValue) => { watch(() => [taskStore.activeId, taskStore.refresh], async (newValue, oldValue) => {
const packageid = taskStore.getPackageid const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId const taskId = taskStore.getActiveId
if (taskId === '' || packageid === '')
return
taskDetailInfo.value = await getTaskDetailInfo(taskId, packageid) taskDetailInfo.value = await getTaskDetailInfo(taskId, packageid)
const { data, total } = await getTaskDetailPictureList(packageid, taskId, { ...taskpagination, ...sortBy }) const { data, total } = await getTaskDetailPictureList(packageid, taskId, { ...taskpagination, ...sortBy })
@ -177,9 +207,9 @@ watch(() => taskStore.activeId, async (newValue, oldValue) => {
}) })
const currentTaskId = computed(() => { const currentTaskId = computed(() => {
const index = taskStore.getCurrentIndex const index = taskStore.getCurrentIndex;
return taskStore.getApprovalList[index]?.formid || '' return taskStore.getApprovalList[index]?.formid || "";
}) });
function overTaskHandle() { function overTaskHandle() {
const item = taskDetailInfo.value const item = taskDetailInfo.value
@ -189,7 +219,12 @@ function overTaskHandle() {
} }
function leaveTaskHandler() { function leaveTaskHandler() {
overTask.value = null overTask.value = null;
}
function showActionsModal(){
const modal = unref(CustomSettingModalRef)! as any;
modal.showModal();
} }
onUnmounted(() => { onUnmounted(() => {
@ -199,6 +234,18 @@ onUnmounted(() => {
const mark = computed(() => { const mark = computed(() => {
return taskDetailInfo.value.iztrueorfalse === null ? '未标记' : '已标记' return taskDetailInfo.value.iztrueorfalse === null ? '未标记' : '已标记'
}) })
function immersionHandler() {
taskStore.updateImmersion()
}
function previewHandler(event: MouseEvent) {
event.stopImmediatePropagation()
event.stopPropagation()
if (imageRef.value)
(imageRef.value as any).mergedOnClick()
}
</script> </script>
<template> <template>
@ -206,14 +253,27 @@ const mark = computed(() => {
<div class="wrapper-header"> <div class="wrapper-header">
<div class="left"> <div class="left">
<span class="font">任务ID{{ currentTaskId }}</span> <span class="font">任务ID{{ currentTaskId }}</span>
<SvgIcon size="22" class="forward" name="arrow-left" @click="backHandler" /> <SvgIcon
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" /> size="22"
class="forward"
name="arrow-left"
@click="backHandler"
/>
<SvgIcon
size="22"
class="back"
name="arrow-right"
@click="forwardHandler"
/>
</div> </div>
<div class="right"> <div class="right">
<div v-show="!showActions" class="btn" @click="setBatch(true)"> <div v-show="!showActions" style="display: flex;align-items: center;" @click="setBatch(true)">
<div class="btn">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" /> <SvgIcon style="margin-right: 6px;" size="14" name="tf" />
批量审批 批量审批
</div> </div>
<SvgIcon style="cursor: pointer;" size="20" name="immersion-model" @click="immersionHandler" />
</div>
<div v-show="showActions" class="batch"> <div v-show="showActions" class="batch">
<n-button text @click="setBatch(false)"> <n-button text @click="setBatch(false)">
<template #icon> <template #icon>
@ -221,27 +281,26 @@ const mark = computed(() => {
</template> </template>
返回 返回
</n-button> </n-button>
<div style="cursor: pointer;margin-left: 16px;" @click="rejectHandler"> <div style="cursor: pointer;margin-left: 16px;" @click.stop="rejectHandler">
<SvgIcon width="64" height="28" name="a1" /> <SvgIcon width="64" height="28" name="a1" />
</div> </div>
<SvgIcon size="24" name="vs" /> <SvgIcon size="24" name="vs" />
<div style="cursor: pointer;" @click="approvalHandler"> <div style="cursor: pointer;" @click.stop="approvalHandler">
<SvgIcon width="64" height="28" name="a2" /> <SvgIcon width="64" height="28" name="a2" />
</div> </div>
</div> </div>
<SvgIcon name="floder" size="30" />
</div> </div>
</div> </div>
<div class="wrapper-detail"> <div class="wrapper-detail">
<div <div
class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }" class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }"
@mouseover="overTaskHandle" @mouseleave="leaveTaskHandler" @mouseover="overTaskHandle" @mouseleave="leaveTaskHandler" @click="previewHandler"
> >
<div v-show="overTask" class="action"> <div v-show="overTask" class="action">
<SvgIcon style="cursor: pointer;" width="168" height="48" name="r6" @click.stop @click="approvalHandler" /> <SvgIcon style="cursor: pointer;" width="168" height="48" name="r6" @click.stop="approvalHandler" />
<SvgIcon <SvgIcon
style="cursor: pointer;margin-left: 30px;" width="168" height="48" name="r7" @click.stop style="cursor: pointer;margin-left: 30px;" width="168" height="48" name="r7"
@click="rejectHandler" @click.stop="rejectHandler"
/> />
</div> </div>
<div class="mark"> <div class="mark">
@ -276,9 +335,12 @@ const mark = computed(() => {
<SvgIcon color="#FFF" size="16" name="time" /> <SvgIcon color="#FFF" size="16" name="time" />
<span>2023-09-17 13:09:10</span> <span>2023-09-17 13:09:10</span>
</div> </div>
<div style="display: none;">
<n-image ref="imageRef" :img-props="{ onClick: hideDownload }" :src="taskDetailInfo?.ocrPicture?.imgurl" />
</div>
</div> </div>
<div class="right"> <div class="right">
<n-scrollbar style="max-height: 100%;"> <n-scrollbar style="max-height: 100%">
<div class="header"> <div class="header">
<span>相似图片(9)</span> <span>相似图片(9)</span>
<SvgIcon <SvgIcon
@ -291,24 +353,29 @@ const mark = computed(() => {
<div class="img-wrapper" :style="{ 'background-image': `url(${item.imgurl})` }" /> <div class="img-wrapper" :style="{ 'background-image': `url(${item.imgurl})` }" />
<div class="check"> <div class="check">
<n-checkbox <n-checkbox
v-show="batch" v-model:checked="item.checked" @click.stop v-show="batch"
v-model:checked="item.checked"
@click.stop
@update:checked="onCheckChange($event, item)" @update:checked="onCheckChange($event, item)"
/> />
</div> </div>
<div class="percent"> <div class="percent">96%</div>
96%
</div>
</div> </div>
</div> </div>
</n-scrollbar> </n-scrollbar>
</div> </div>
</div> </div>
<div class="info-header"> <div class="info-header">
<div class="title"> <div class="left_box">
填报信息 <div class="title">填报信息</div>
</div>
<SvgIcon size="12" name="collapse" /> <SvgIcon size="12" name="collapse" />
</div> </div>
<div class="right_box" @click="showActionsModal">
自定义设置
<SvgIcon size="16" name="pencil" />
</div>
</div>
<n-tabs type="line" animated> <n-tabs type="line" animated>
<n-tab-pane name="task-info" tab="任务信息"> <n-tab-pane name="task-info" tab="任务信息">
<TaskTable :data="taskDetailInfo" /> <TaskTable :data="taskDetailInfo" />
@ -319,7 +386,8 @@ const mark = computed(() => {
<n-tab-pane name="history" tab="历史审查" /> <n-tab-pane name="history" tab="历史审查" />
</n-tabs> </n-tabs>
<ConfrimModal ref="confrimModalRef" @commit="reject" /> <ConfrimModal ref="confrimModalRef" @commit="reject" />
<BatchModal ref="batchModalRef" /> <BatchModal ref="batchModalRef" @reject="rejectHandler" @approval="approvalHandler" />
<CustomSettingModal ref="CustomSettingModalRef" />
</div> </div>
</template> </template>
@ -331,7 +399,7 @@ const mark = computed(() => {
box-sizing: border-box; box-sizing: border-box;
margin-left: 16px; margin-left: 16px;
padding: 16px 16px 0px 16px; padding: 16px 16px 0px 16px;
background: #FFF; background: #fff;
border-radius: 3px; border-radius: 3px;
border: 1px solid rgb(239, 239, 245); border: 1px solid rgb(239, 239, 245);
height: calc(100vh - 88px); height: calc(100vh - 88px);
@ -341,7 +409,7 @@ const mark = computed(() => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
background: #FFF; background: #fff;
box-sizing: border-box; box-sizing: border-box;
border-radius: 3px; border-radius: 3px;
margin-bottom: 16px; margin-bottom: 16px;
@ -372,12 +440,17 @@ const mark = computed(() => {
height: 36px; height: 36px;
background: linear-gradient(135deg, #5b85f8, #3c6cf0); background: linear-gradient(135deg, #5b85f8, #3c6cf0);
border-radius: 17px; border-radius: 17px;
box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.30); box-shadow: 0px 2px 6px 0px rgba(116, 153, 253, 0.3);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
<<<<<<< HEAD
color: #FFF; color: #FFF;
margin-right: 10px;
=======
color: #fff;
margin-right: 6px; margin-right: 6px;
>>>>>>> al
cursor: pointer; cursor: pointer;
} }
@ -533,7 +606,7 @@ const mark = computed(() => {
z-index: 5; z-index: 5;
right: 12px; right: 12px;
top: 2px; top: 2px;
color: #FFF; color: #fff;
} }
} }
} }
@ -542,14 +615,17 @@ const mark = computed(() => {
display: flex; display: flex;
padding: 16px 0px; padding: 16px 0px;
align-items: center; align-items: center;
justify-content: space-between;
.left_box {
display: flex;
align-items: center;
.title { .title {
display: flex; display: flex;
align-items: center; align-items: center;
margin-right: 8px; margin-right: 8px;
&:before { &:before {
content: ''; content: "";
width: 4px; width: 4px;
height: 18px; height: 18px;
background: #507afd; background: #507afd;
@ -559,5 +635,11 @@ const mark = computed(() => {
} }
} }
} }
.right_box {
display: flex;
align-items: center;
cursor: pointer;
}
}
} }
</style> </style>

@ -73,7 +73,7 @@ td {
th, th,
td { td {
border: 1px solid #ebebeb; border: 1px solid #ebebeb;
padding: 12px 24px; padding: 10px 24px;
text-align: left; text-align: left;
} }

@ -7,8 +7,14 @@ import imagesloaded from 'imagesloaded'
import { timeOptions, viewOptions } from '@/config/home' import { timeOptions, viewOptions } from '@/config/home'
import { off, on } from '@/utils/domUtils' import { off, on } from '@/utils/domUtils'
import { useTask } from '@/store/modules/task' import { useTask } from '@/store/modules/task'
import { getTaskDetailPictureList } from '@/api/work/work' import { getTaskDetailInfo, getTaskDetailPictureList } from '@/api/work/work'
import type { PictureSortParam } from '/#/api' import type { PictureSortParam } from '/#/api'
import emitter from '@/utils/mitt'
const emit = defineEmits<{
(e: 'reject', params: any)
(e: 'approval', params: any)
}>()
const cardStyle = { const cardStyle = {
'--n-padding-bottom': '40px', '--n-padding-bottom': '40px',
@ -38,6 +44,7 @@ const taskStore = useTask()
const masonryRef = ref<ComponentRef>(null) const masonryRef = ref<ComponentRef>(null)
const el = ref<HTMLDivElement | null>(null) const el = ref<HTMLDivElement | null>(null)
const listData = ref<any[]>([]) const listData = ref<any[]>([])
const taskDetailInfo = ref<any>({})
const pagination = reactive({ const pagination = reactive({
pageNo: 1, pageNo: 1,
pageSize: 30, pageSize: 30,
@ -49,6 +56,7 @@ const sortBy: PictureSortParam = {
orderbyname: 'asc', orderbyname: 'asc',
orderbyvalue: 'fromuptime', orderbyvalue: 'fromuptime',
} }
const batch = ref(false)
const layout = debounce(() => { const layout = debounce(() => {
if (!show.value) if (!show.value)
@ -100,13 +108,7 @@ async function featchList() {
pagination.pageNo += 1 pagination.pageNo += 1
canloadMore = pageCount >= pagination.pageNo canloadMore = pageCount >= pagination.pageNo
const list = data.map((item) => { return data
return {
imgUrl: item.imgurl,
}
})
return list
} }
catch (error) { catch (error) {
return [] return []
@ -136,11 +138,15 @@ let selectionBox: HTMLDivElement | null
const selectIds = ref<string[]>([]) const selectIds = ref<string[]>([])
function downHandler(event: MouseEvent) { function downHandler(event: MouseEvent) {
if (!selectionBox) event.stopPropagation()
if (!selectionBox || batch.value === false)
return return
selectIds.value.length = 0 const classname = (event.target as any).className
if (!classname.includes('checkbox')) {
selectIds.value.length = 0
start = { x: event.clientX, y: event.clientY } start = { x: event.clientX, y: event.clientY }
selectionBox.style.width = '0' selectionBox.style.width = '0'
selectionBox.style.height = '0' selectionBox.style.height = '0'
@ -149,6 +155,7 @@ function downHandler(event: MouseEvent) {
selectionBox.style.display = 'block' selectionBox.style.display = 'block'
selectionBox.style.zIndex = '9999' selectionBox.style.zIndex = '9999'
} }
}
function imUpdateSelectIds(x: number, y: number, w: number, h: number) { function imUpdateSelectIds(x: number, y: number, w: number, h: number) {
const items = document.querySelectorAll('.grid-item') const items = document.querySelectorAll('.grid-item')
@ -163,12 +170,8 @@ function imUpdateSelectIds(x: number, y: number, w: number, h: number) {
}) })
} }
function isSelected(id: number) {
return selectIds.value.includes(String(id))
}
function moveHandler(e: MouseEvent) { function moveHandler(e: MouseEvent) {
if (!selectionBox || !start) if (!selectionBox || !start || batch.value === false)
return return
const x = Math.min(e.clientX, start.x) const x = Math.min(e.clientX, start.x)
@ -202,26 +205,25 @@ function addListeners() {
on(el.value!, 'mousedown', downHandler) on(el.value!, 'mousedown', downHandler)
on(el.value!, 'mousemove', moveHandler) on(el.value!, 'mousemove', moveHandler)
on(document, 'mouseup', upHandler) on(document, 'mouseup', upHandler)
emitter.on('refresh', refreshHandler)
} }
function removeListeners() { function removeListeners() {
off(el.value!, 'mousedown', downHandler) off(el.value!, 'mousedown', downHandler)
on(el.value!, 'mousemove', moveHandler) on(el.value!, 'mousemove', moveHandler)
on(document, 'mouseup', upHandler) on(document, 'mouseup', upHandler)
emitter.off('refresh', refreshHandler)
} }
async function afterEnter() { async function afterEnter() {
addListeners() addListeners()
refreshHandler()
const list = await featchList()
listData.value = list
} }
function afterLeave() { function afterLeave() {
removeListeners() removeListeners()
pagination.pageNo = 1
pagination.pageSize = 30
} }
onMounted(() => { onMounted(() => {
@ -248,18 +250,65 @@ function backHandler() {
taskStore.back() taskStore.back()
} }
const selectItems = ref<any[]>([])
function onCheckChange(checked: any, item: any) { function onCheckChange(checked: any, item: any) {
const index = selectItems.value.indexOf(item) const index = selectIds.value.indexOf(item.id)
item.checked = checked
if (index === -1 && checked) if (index === -1 && checked)
selectItems.value.push(item) selectIds.value.push(item.id)
else
selectIds.value.splice(index, 1)
}
watch(() => selectIds.value.length, () => {
const list = listData.value
for (const item of list) {
if (selectIds.value.includes(item.id))
item.checked = true
else else
selectItems.value.splice(index, 1) item.checked = false
}
})
const showActions = computed(() => {
return selectIds.value.length > 0 && batch
})
function setBatch(value: boolean) {
batch.value = value
if (value === false)
selectIds.value.length = 0
} }
function reject() {
emit('reject', getSelectItems())
}
function approval() {
emit('approval', getSelectItems())
}
function getSelectItems() {
return listData.value.filter(item => selectIds.value.includes(item.id))
}
async function refreshHandler() {
const packageid = taskStore.getPackageid
const taskId = taskStore.getActiveId
taskDetailInfo.value = await getTaskDetailInfo(taskId, packageid)
pagination.pageNo = 1
pagination.pageSize = 30
listData.value.length = 0
const list = await featchList()
listData.value = list
layout()
}
watch(() => taskStore.activeId, async (newValue, oldValue) => {
refreshHandler()
})
</script> </script>
<template> <template>
@ -306,12 +355,12 @@ function onCheckChange(checked: any, item: any) {
<tbody> <tbody>
<tr> <tr>
<td> <td>
张三丰 {{ taskDetailInfo?.createusername }}
</td> </td>
<td>待审批</td> <td>{{ taskDetailInfo?.states }}</td>
<td>2023-12-02 14:20:11</td> <td>{{ taskDetailInfo?.ocrPicture?.createTime }}</td>
<td>网络截图</td> <td>{{ taskDetailInfo?.fromsourceid }}</td>
<td>15</td> <td>{{ taskDetailInfo?.ocpictureid.split(',').length }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -334,11 +383,25 @@ function onCheckChange(checked: any, item: any) {
</n-popselect> </n-popselect>
</div> </div>
<div> <div>
<div>移除可疑文件夹</div> <div v-show="!showActions" class="wrapper-content-form-button" @click="setBatch(true)">
<div class="wrapper-content-form-button">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" /> <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>
<SvgIcon name="revoke" />
</template>
返回
</n-button>
<div style="cursor: pointer;margin-left: 16px;" @click="reject">
<SvgIcon width="64" height="28" name="a1" />
</div>
<SvgIcon size="24" name="vs" />
<div style="cursor: pointer;" @click="approval">
<SvgIcon width="64" height="28" name="a2" />
</div>
</div>
</div> </div>
</div> </div>
@ -346,16 +409,18 @@ function onCheckChange(checked: any, item: any) {
<!-- <n-scrollbar :on-scroll="scrollHandler"> --> <!-- <n-scrollbar :on-scroll="scrollHandler"> -->
<div ref="masonryRef" class="grid"> <div ref="masonryRef" class="grid">
<div <div
v-for="(item, index) in listData" :key="index" :data-id="index" v-for="(item, index) in listData" :key="index" :data-id="item.id" :style="{ height: gridHeight }"
:class="{ 'grid-item-selected': isSelected(index) }" :style="{ height: gridHeight }"
class="grid-item" class="grid-item"
> >
<img <img
class="wrapper-content-item-img" class="wrapper-content-item-img"
:class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgUrl" :class="{ 'wrapper-content-item-img-fit': viewMode !== 'masonry' }" :src="item.imgurl"
> >
<div class="top"> <div class="top">
<n-checkbox v-model:checked="item.checked" @click.stop @update:checked="onCheckChange($event, item)" /> <n-checkbox
v-show="batch" v-model:checked="item.checked" @click.prevent
@update:checked="onCheckChange($event, item)"
/>
<div class="percent"> <div class="percent">
30% 30%
</div> </div>
@ -460,6 +525,11 @@ function onCheckChange(checked: any, item: any) {
&-form { &-form {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center;
background: #FFF;
box-sizing: border-box;
border-radius: 3px;
height: 36px;
&-dropdown { &-dropdown {
display: flex; display: flex;
@ -483,6 +553,7 @@ function onCheckChange(checked: any, item: any) {
justify-content: center; justify-content: center;
color: #FFF; color: #FFF;
margin-left: 18px; margin-left: 18px;
cursor: pointer;
} }
div { div {
@ -539,7 +610,7 @@ function onCheckChange(checked: any, item: any) {
.scroll { .scroll {
overflow-y: scroll; overflow-y: scroll;
height: calc(100vh - 282px); height: calc(100vh - 320px);
} }
} }
} }

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onBeforeMount, ref } from 'vue' import { computed, onBeforeMount, ref, unref } from 'vue'
import { useDictionary } from '@/store/modules/dictonary' import { useDictionary } from '@/store/modules/dictonary'
const emit = defineEmits<{ const emit = defineEmits<{
@ -43,7 +43,7 @@ const comomitValue = computed(() => {
async function handleSumbit(e: MouseEvent) { async function handleSumbit(e: MouseEvent) {
e.preventDefault() e.preventDefault()
closeModal() closeModal()
emit('commit', comomitValue, selectBackId, selectRejectId.value === 'other') emit('commit', unref(comomitValue), unref(selectBackId), selectRejectId.value === 'other')
} }
onBeforeMount(async () => { onBeforeMount(async () => {

@ -0,0 +1,258 @@
<script lang="ts" setup>
import { ReportInfoConfig } from "@/config/workorder";
import { ref } from "vue";
const offList = ref<any[]>([]);
function generatList() {
const keys = Object.keys(ReportInfoConfig);
const hideList: object[] = [];
for (const key of keys) {
const name = ReportInfoConfig[key]?.label;
const isDefault = ReportInfoConfig[key]?.isDefault;
// Y
if (!isDefault) {
hideList.push({
id: key,
name: name || "未配置",
fix: isDefault,
checked: ReportInfoConfig[key].isDefault,
});
}
}
const fixedList = generateDefaultList();
hideList.unshift(...fixedList);
offList.value = hideList;
return { hideList };
}
function generateDefaultList() {
return Object.keys(ReportInfoConfig).reduce((acc, key) => {
const { label, isDefault } = ReportInfoConfig[key];
if (isDefault) {
const config = {
id: key,
name: label || "未配置",
fix: true,
checked: true,
};
return [...acc, config];
} else {
return acc;
}
}, []);
}
const show = ref(false);
const checkAll = ref(false);
function showModal() {
show.value = true;
}
function closeModal() {
show.value = false;
}
async function handleSumbit(e: MouseEvent) {
e.preventDefault();
closeModal();
}
defineExpose({
showModal,
});
generatList();
const selectIds = ref<string[]>([]);
function onCheckAllChange(value) {
const ids: string[] = [];
for (const item of offList.value) {
if (!item.fix) {
item.checked = value;
ids.push(item.id);
}
}
selectIds.value = value ? ids : [];
}
function onCheckChange(checked: any, item: any) {
const index = selectIds.value.indexOf(item.id);
item.checked = checked;
if (index === -1 && checked) selectIds.value.push(item.id);
else selectIds.value.splice(index, 1);
}
</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>
<n-grid cols="4" class="mt-4 proCard" responsive="screen" :x-gap="24">
<n-grid-item span="4">
<NCard
title=""
class="dragcardStyle"
:segmented="{ content: true, footer: true }"
size="small"
:bordered="false"
>
<div>
<div class="draggable-ul">
<div class="draggable-li" style="background: #f8f8f8;">
<n-checkbox
v-model:checked="checkAll"
label="全部"
@update:checked="onCheckAllChange"
/>
</div>
<div class="content">
<div
v-for="item in offList"
:key="item.id"
style="width: 170px"
:class="{ 'disable-check': item.fix }"
class="draggable-li"
>
<n-checkbox
v-model:checked="item.checked"
:label="item.name"
:disabled="item.fix"
@update:checked="onCheckChange($event, item)"
/>
</div>
</div>
</div>
</div>
</NCard>
</n-grid-item>
</n-grid>
</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 {
display: flex;
flex-direction: column;
&-title {
font-weight: bold;
font-size: 16px;
}
&-bar {
background-color: #e8e8e8;
width: 100%;
margin-top: 20px;
}
&-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;
}
}
}
.dragcardStyle {
--n-padding-bottom: 0px !important;
--n-padding-left: 0px !important;
}
.cardstyle {
width: 820px;
--n-padding-bottom: 20px;
--n-padding-left: 24px;
}
.textbtnStyle {
cursor: pointer;
color: #1980ff;
}
.draggable-ul {
width: 100%;
overflow: hidden;
border: 1px solid #cad2dd;
border-radius: 2px;
display: block;
.content {
display: flex;
flex-wrap: wrap;
}
.draggable-li {
padding: 10px 16px;
color: #333;
}
.draggable-item {
padding: 10px 16px;
color: #333;
display: flex;
align-items: center;
}
.disable-check {
color: gainsboro;
}
}
::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;
}
</style>

@ -1,10 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, defineOptions, nextTick, onBeforeMount, onMounted, reactive, ref, unref } from 'vue' import { computed, defineOptions, nextTick, onBeforeMount, onMounted, reactive, ref, unref, watch } from 'vue'
import { debounce } from 'lodash-es'
import CustomFieldModalVue from '../modal/CustomFieldModal.vue' import CustomFieldModalVue from '../modal/CustomFieldModal.vue'
import WorkSheetList from './WorkSheetList.vue' import WorkSheetList from './WorkSheetList.vue'
import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn' import { useWindowSizeFn } from '@/hooks/event/useWindowSizeFn'
import { getViewportOffset } from '@/utils/domUtils' import { getViewportOffset } from '@/utils/domUtils'
import type { PackageListItem } from '/#/workorder'
import { useWorkOrder } from '@/store/modules/workOrder' import { useWorkOrder } from '@/store/modules/workOrder'
defineOptions({ name: 'AsideContent' }) defineOptions({ name: 'AsideContent' })
@ -12,6 +12,7 @@ defineOptions({ name: 'AsideContent' })
const collapse = ref(false) const collapse = ref(false)
const workStore = useWorkOrder() const workStore = useWorkOrder()
const filterModalRef = ref(null) const filterModalRef = ref(null)
const packageListRef = ref<HTMLDivElement | null>(null)
function collapseHandler() { function collapseHandler() {
collapse.value = !collapse.value collapse.value = !collapse.value
@ -54,18 +55,6 @@ onMounted(() => {
}) })
}) })
const data = ref<PackageListItem[]>([])
const pagination = reactive({
pageNo: 1,
pageSize: 10,
})
onBeforeMount(async () => {
const orderList = await workStore.fetchOrderList(pagination)
data.value = orderList
})
const asideEnter = ref(false) const asideEnter = ref(false)
const showCollapse = computed(() => { const showCollapse = computed(() => {
@ -76,6 +65,20 @@ function showFilter() {
const modal = unref(filterModalRef)! as any const modal = unref(filterModalRef)! as any
modal.showModal() modal.showModal()
} }
watch(() => workStore.immersion, () => {
collapse.value = true
})
const showSearch = ref(false)
function setShowSearch(value: boolean) {
showSearch.value = value
}
const inputHandler = debounce((word) => {
(packageListRef.value as any).search(word)
}, 500)
</script> </script>
<template> <template>
@ -86,16 +89,29 @@ function showFilter() {
</div> </div>
</div> </div>
<div class="aside-header"> <div class="aside-header">
<div class="aside-header-left"> <div v-show="!showSearch" class="warpper">
<div class="left">
<svg-icon name="all-worksheet" size="32" /> <svg-icon name="all-worksheet" size="32" />
<span style="margin-left: 8px;">所有工单</span> <span style="margin-left: 8px;">所有工单</span>
</div> </div>
<div class="aside-header-right"> <div class="right">
<SvgIcon style="cursor: pointer;margin-left: 10px;" size="18" name="magnifying-1" /> <SvgIcon
style="cursor: pointer;margin-left: 10px;" size="18" name="magnifying-1"
@click="setShowSearch(true)"
/>
<SvgIcon style="cursor: pointer;margin-left: 10px;" size="18" name="filter" @click="showFilter" /> <SvgIcon style="cursor: pointer;margin-left: 10px;" size="18" name="filter" @click="showFilter" />
</div> </div>
</div> </div>
<WorkSheetList :style="listStyle" class="work-sheet-list" :data="data" :active-id="workStore.getActiveId" /> <div v-show="showSearch" class="warpper">
<n-input style="flex: 1;height: 32px;" placeholder="请输入你需要搜索的内容" @input="inputHandler">
<template #suffix>
<SvgIcon size="14px" name="magnifying-1" />
</template>
</n-input>
<SvgIcon size="16px" style="margin-left: 6px;cursor: pointer;" name="clear" @click="setShowSearch(false)" />
</div>
</div>
<WorkSheetList ref="packageListRef" :style="listStyle" class="work-sheet-list" />
<CustomFieldModalVue ref="filterModalRef" /> <CustomFieldModalVue ref="filterModalRef" />
</div> </div>
</template> </template>
@ -111,20 +127,23 @@ function showFilter() {
box-sizing: border-box; box-sizing: border-box;
&-header { &-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px; padding: 12px 16px;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
&-left { .warpper {
display: flex;
justify-content: space-between;
align-items: center;
}
.left {
display: flex; display: flex;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
} }
&-right { .right {
display: flex; display: flex;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
@ -143,7 +162,7 @@ function showFilter() {
height: 100%; height: 100%;
background: #507afd; background: #507afd;
position: absolute; position: absolute;
right: 0; right: -2px;
top: 0; top: 0;
} }

@ -36,14 +36,14 @@ const svgName = computed(() => {
<li>筛选时间{{ listItem.createTime }}</li> <li>筛选时间{{ listItem.createTime }}</li>
<li>执行人{{ listItem.createBy }}</li> <li>执行人{{ listItem.createBy }}</li>
</ul> </ul>
<div class="list-item-divider" />
</div> </div>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
.list-item { .list-item {
padding: 12px 0px 12px 16px; padding: 10px 0px 10px 8px;
position: relative; position: relative;
border-bottom: 1px solid #e8e8e8;
&-header { &-header {
display: flex; display: flex;
@ -78,7 +78,7 @@ const svgName = computed(() => {
} }
&-divider { &-divider {
width: 100%; width: 280px;
height: 1px; height: 1px;
background-color: #e8e8e8; background-color: #e8e8e8;
position: absolute; position: absolute;

@ -2,36 +2,98 @@
import type { PackageListItem } from '/#/workorder' import type { PackageListItem } from '/#/workorder'
import ListItem from './ListItem.vue' import ListItem from './ListItem.vue'
import { useWorkOrder } from '@/store/modules/workOrder' import { useWorkOrder } from '@/store/modules/workOrder'
import { onUnmounted, reactive, ref, watch } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
defineOptions({ name: 'WorkSheetList' }) const workStore = useWorkOrder()
const data = ref<PackageListItem[]>([])
const activeId = ref('')
const el = ref<HTMLDivElement | null>(null)
const keyword = ref('')
const canloadMore = ref(true)
defineProps({ const pagination = reactive({
activeId: { pageNo: 0,
type: String, pageSize: 10,
required: true,
},
data: {
type: Object as PropType<PackageListItem[]>,
required: true,
},
}) })
const workStore = useWorkOrder()
function selectHandler(id: string, index: number) { function selectHandler(id: string, index: number) {
workStore.setActive(index) workStore.setActive(index)
} }
const { isLoading } = useInfiniteScroll(
el as any,
() => {
loadMore()
},
{ distance: 10, interval: 300, canLoadMore: () => {
console.log('canloadmore excuted!')
return canloadMore.value
} },
)
async function loadMore() {
if (isLoading.value || el.value == null)
return
console.log('loadmore')
const more = await fetchList()
data.value.push(...more)
}
async function fetchList() {
try {
pagination.pageNo += 1
const result = await workStore.fetchOrderList(pagination)
const { data, pageCount } = result
canloadMore.value = pageCount >= pagination.pageNo
return data
}
catch (error) {
return []
}
}
watch(() => workStore.activeId, (newVal) => {
activeId.value = newVal
})
function reset() {
pagination.pageNo = 0
pagination.pageSize = 10
canloadMore.value = true
data.value.length = 0
}
async function search(word: string) {
keyword.value = word
reset()
useInfiniteScroll(
el as any,
() => {
loadMore()
},
{ distance: 10, canLoadMore: () => canloadMore.value },
)
}
defineExpose({
search,
})
</script> </script>
<template> <template>
<n-scrollbar> <n-scrollbar>
<n-spin :show="isLoading">
<div ref="el">
<ListItem <ListItem
v-for="(item, index) in data" :key="item.id" :selected="activeId === item.id" :list-item="item" v-for="(item, index) in data" :key="item.id" :selected="activeId === item.id" :list-item="item"
@click="selectHandler(item.id, index)" @click="selectHandler(item.id, index)"
/> />
</div>
</n-spin>
</n-scrollbar> </n-scrollbar>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
</style> </style>
../types

@ -7,6 +7,7 @@ import type { PictureSortParam, SetTFParam } from '/#/api'
import { useWorkOrder } from '@/store/modules/workOrder' import { useWorkOrder } from '@/store/modules/workOrder'
import { clearTF, getPackageTaskList, getTaskDetailInfo, getTaskDetailPictureList, setTF } from '@/api/work/work' import { clearTF, getPackageTaskList, getTaskDetailInfo, getTaskDetailPictureList, setTF } from '@/api/work/work'
import { fieldMap } from '@/config/workorder' import { fieldMap } from '@/config/workorder'
import { hideDownload } from '@/utils/image'
const batch = ref(false) const batch = ref(false)
const selectItems = ref<any[]>([]) const selectItems = ref<any[]>([])
@ -55,8 +56,9 @@ const overTask = ref<any>(null)
const taskList = ref<any[]>([]) const taskList = ref<any[]>([])
const taskDetailInfo = ref<any>({}) const taskDetailInfo = ref<any>({})
const taskDetailPictureList = ref<any[]>([]) const taskDetailPictureList = ref<any[]>([])
const confrimModalRef = ref(null) const confrimModalRef = ref(null)
const imageRef = ref<ComponentElRef | null>()
let processItems: any[] = [] let processItems: any[] = []
function validate(items: any[]) { function validate(items: any[]) {
@ -272,6 +274,18 @@ function getPercent(pictureid: string) {
const mark = computed(() => { const mark = computed(() => {
return taskDetailInfo.value.iztrueorfalse === null ? '未标记' : '已标记' return taskDetailInfo.value.iztrueorfalse === null ? '未标记' : '已标记'
}) })
function immersionHandler() {
workStore.updateImmersion()
}
function previewHandler(event: MouseEvent) {
event.stopImmediatePropagation()
event.stopPropagation()
if (imageRef.value)
(imageRef.value as any).mergedOnClick()
}
</script> </script>
<template> <template>
@ -283,15 +297,16 @@ const mark = computed(() => {
<SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" /> <SvgIcon size="22" class="back" name="arrow-right" @click="forwardHandler" />
</div> </div>
<div class="right"> <div class="right">
<div v-show="!showActions" style="display: flex;"> <div v-show="!showActions" style="display: flex;align-items: center;">
<n-button text @click="clearHandler"> <n-button text @click="clearHandler">
<SvgIcon size="12" name="delete" /> <SvgIcon size="12" name="delete" />
清除标记 清除标记
</n-button> </n-button>
<div class="btn" style="margin-left: 20px;" @click="setBatch(true)"> <div class="btn" style="margin: 0px 10px;" @click="setBatch(true)">
<SvgIcon style="margin-right: 6px;" size="14" name="tf" /> <SvgIcon style="margin-right: 6px;" size="14" name="tf" />
辨别真假 辨别真假
</div> </div>
<SvgIcon style="cursor: pointer;" size="20" name="immersion-model" @click="immersionHandler" />
</div> </div>
<div v-show="showActions" class="batch"> <div v-show="showActions" class="batch">
@ -312,7 +327,10 @@ const mark = computed(() => {
</div> </div>
</div> </div>
<div class="wrapper-detail"> <div class="wrapper-detail">
<div class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }"> <div
class="left" :style="{ 'background-image': `url(${taskDetailInfo?.ocrPicture?.imgurl})` }"
@click="previewHandler"
>
<div class="mark"> <div class="mark">
<SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" /> <SvgIcon v-show="taskDetailInfo?.iztrueorfalse === 0" size="128" name="jia" />
</div> </div>
@ -322,14 +340,18 @@ const mark = computed(() => {
<div class="info"> <div class="info">
<n-grid x-gap="16" y-gap="0" :cols="12"> <n-grid x-gap="16" y-gap="0" :cols="12">
<n-gi span="4"> <n-gi span="4">
<span style="color:#8b8d8f;"><SvgIcon name="m1" /></span> <span style="color:#8b8d8f;">
<SvgIcon name="m1" />
</span>
</n-gi> </n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;"> <n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ mark }}</span> <span>{{ mark }}</span>
<span>图片标记</span> <span>图片标记</span>
</n-gi> </n-gi>
<n-gi span="4"> <n-gi span="4">
<span style="color:#8b8d8f;"><SvgIcon name="m2" /></span> <span style="color:#8b8d8f;">
<SvgIcon name="m2" />
</span>
</n-gi> </n-gi>
<n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;"> <n-gi span="8" style="display: flex;align-items: left;flex-direction: column;justify-content: center;">
<span>{{ totalCount }}</span> <span>{{ totalCount }}</span>
@ -337,6 +359,9 @@ const mark = computed(() => {
</n-gi> </n-gi>
</n-grid> </n-grid>
</div> </div>
<div style="display: none;">
<n-image ref="imageRef" :img-props="{ onClick: hideDownload }" :src="taskDetailInfo?.ocrPicture?.imgurl" />
</div>
</div> </div>
<div class="right"> <div class="right">
<n-scrollbar style="max-height: 100%;"> <n-scrollbar style="max-height: 100%;">
@ -400,8 +425,8 @@ const mark = computed(() => {
<SvgIcon v-show="item.iztrueorfalse === 1" name="zhen" /> <SvgIcon v-show="item.iztrueorfalse === 1" name="zhen" />
</div> </div>
<div v-show="overTask && overTask.id === item.id" class="action"> <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="t1" @click.stop="trueHandler" />
<SvgIcon style="cursor: pointer;" name="t2" @click.stop @click="falseHandler" /> <SvgIcon style="cursor: pointer;" name="t2" @click.stop="falseHandler" />
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,207 @@
<script lang="ts" setup>
import { ref } from "vue";
const emit = defineEmits<{
(e: "reject", params: any);
(e: "viewrepeat");
}>();
const cardStyle = {
width: "450px",
"--n-padding-bottom": "10px",
"--n-padding-left": "0px",
};
const show = ref(false);
function showModal() {
show.value = true;
}
function closeModal() {
show.value = false;
}
async function reject() {
emit("reject", { a: "todo" });
closeModal();
}
async function viewRepeat(e: MouseEvent) {
emit("viewrepeat");
e.preventDefault();
closeModal();
}
defineExpose({
showModal,
});
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" class="modal_wrap">
<div class="wrapper">
<div class="closed">
<SvgIcon
style="cursor: pointer"
name="cut-down"
width="32"
@click="closeModal"
/>
</div>
<div class="wrapper-hearder">
<div class="wrapper-title">智能AI审批工具</div>
<div class="wrapper-mark">某某有限公司-某某事业部-张小凡</div>
</div>
<div class="wrapper-content">
<n-scrollbar style="height: 200px">
<div v-for="i in 1" :key="i" class="item">
<div class="imgwrapper" />
<div class="content">
<div class="task_id">任务IDYPW34567890-2995</div>
<div class="tag_box">
<div class="tag_item">基线任务</div>
<div class="tag_item error">相似图片(16)</div>
</div>
<div class="time_box">2023-09-17 13:09:10</div>
</div>
</div>
</n-scrollbar>
<div class="mark_text">
智能识别12张图片来源于网络建议将图片标记为假 快速审批不通过
</div>
<div class="footer">
<SvgIcon
style="cursor: pointer"
name="r3"
width="162"
height="54"
@click="reject"
/>
<SvgIcon
style="cursor: pointer"
name="r2"
width="162"
height="54"
@click="viewRepeat"
/>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="less" scoped>
.modal_wrap {
background-image: url(../../../assets/images/approval_modal_bg.png);
background-repeat: no-repeat;
background-size: 100%;
width: 700px;
height: 500px;
box-shadow: none !important;
}
.wrapper {
position: absolute;
left: calc(50% - 350px);
.closed {
position: relative;
top: 0px;
left: 90%;
}
.wrapper-hearder {
margin-top: 40px;
.wrapper-title {
text-align: center;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Semibold;
font-weight: Semibold;
text-align: center;
color: #333333;
line-height: 32px;
}
.wrapper-mark {
text-align: center;
font-size: 13px;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Regular;
font-weight: Regular;
text-align: center;
color: #666666;
line-height: 18px;
}
}
.wrapper-content {
flex: 1;
border-radius: 8px;
margin: 35px 60px 35px 120px;
.item {
display: flex;
flex-flow: row nowrap;
align-items: center;
margin: 20px 0;
}
.imgwrapper {
width: 200px;
height: 120px;
margin-right: 20px;
border-radius: 8px;
background-image: url("../../../assets/images/test.png");
background-repeat: no-repeat;
background-size: cover;
}
.content {
.task_id {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
.tag_box {
display: flex;
flex-flow: row nowrap;
margin: 8px 0;
.tag_item {
background: rgba(80, 122, 253, 0.1);
border-radius: 2px;
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #507afd;
line-height: 16px;
margin-right: 10px;
}
.error {
background: rgba(255, 78, 79, 0.1);
color: #ff4e4f;
}
}
.time_box {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
}
.mark_text {
font-size: 13px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #666666;
line-height: 16px;
}
.footer {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
margin: 20px 30px 0 0;
}
}
}
</style>

@ -0,0 +1,203 @@
<script lang="ts" setup>
import { ref } from "vue";
const emit = defineEmits<{
(e: "reject", params: any);
(e: "viewrepeat");
}>();
const cardStyle = {
width: "450px",
"--n-padding-bottom": "10px",
"--n-padding-left": "0px",
};
const show = ref(false);
function showModal() {
show.value = true;
}
function closeModal() {
show.value = false;
}
async function reject() {
emit("reject", { a: "todo" });
closeModal();
}
async function viewRepeat(e: MouseEvent) {
emit("viewrepeat");
e.preventDefault();
closeModal();
}
defineExpose({
showModal,
});
</script>
<template>
<n-modal v-model:show="show" transform-origin="center" class="modal_wrap">
<div class="wrapper">
<div class="closed">
<SvgIcon style="cursor: pointer" name="cut-down" width="32" @click="closeModal"/>
</div>
<div class="wrapper-hearder">
<div class="wrapper-title">智能AI审批工具</div>
<div class="wrapper-mark">某某有限公司-某某事业部-张小凡</div>
</div>
<div class="wrapper-content">
<n-scrollbar style="height: 200px">
<div v-for="i in 1" :key="i" class="item">
<div class="imgwrapper" />
<div class="content">
<div class="task_id">任务IDYPW34567890-2995</div>
<div class="tag_box">
<div class="tag_item">基线任务</div>
<div class="tag_item error">中日友好医院</div>
</div>
<div class="time_box">2023-09-17 13:09:10</div>
</div>
</div>
</n-scrollbar>
<div class="mark_text">
智能识别图片与拜访终端名称不相符建议审批不通过
移至可疑收藏夹
</div>
<div class="footer">
<SvgIcon
style="cursor: pointer"
name="r1"
width="162"
height="54"
@click="reject"
/>
<SvgIcon
style="cursor: pointer"
name="r5"
width="162"
height="54"
@click="viewRepeat"
/>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="less" scoped>
.modal_wrap {
background-image: url(../../../assets/images/approval_modal_bg.png);
background-repeat: no-repeat;
background-size: 100%;
width: 700px;
height: 500px;
box-shadow: none !important;
}
.wrapper {
position: absolute;
left: calc(50% - 350px);
.closed{
position: relative;
top: 0px;
left: 90%;
}
.wrapper-hearder {
margin-top: 40px;
.wrapper-title {
text-align: center;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Semibold;
font-weight: Semibold;
text-align: center;
color: #333333;
line-height: 32px;
}
.wrapper-mark {
text-align: center;
font-size: 13px;
font-family: HarmonyOS Sans SC, HarmonyOS Sans SC-Regular;
font-weight: Regular;
text-align: center;
color: #666666;
line-height: 18px;
}
}
.wrapper-content {
flex: 1;
border-radius: 8px;
margin: 35px 60px 35px 120px;
.item{
display: flex;
flex-flow: row nowrap;
align-items: center;
margin: 20px 0;
}
.imgwrapper {
width: 200px;
height: 120px;
margin-right: 20px;
border-radius: 8px;
background-image: url("../../../assets/images/test.png");
background-repeat: no-repeat;
background-size: cover;
}
.content {
.task_id {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
.tag_box {
display: flex;
flex-flow: row nowrap;
margin: 8px 0;
.tag_item {
background: rgba(80, 122, 253, 0.1);
border-radius: 2px;
font-size: 12px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #507afd;
line-height: 16px;
margin-right: 10px;
}
.error {
background: rgba(255, 78, 79, 0.1);
color: #ff4e4f;
}
}
.time_box {
font-size: 14px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #333333;
line-height: 20px;
}
}
.mark_text {
font-size: 13px;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: Regular;
text-align: left;
color: #666666;
line-height: 16px;
}
.footer{
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
margin: 20px 30px 0 0;
}
}
}
</style>

1
types/api.d.ts vendored

@ -12,6 +12,7 @@ export interface FilterSearchParam {
search_searchname?: { search_searchname?: {
value: string value: string
op: 'equal' | 'like' op: 'equal' | 'like'
type: 'string'
} }
} }

2
types/task.d.ts vendored

@ -10,6 +10,8 @@ export interface TaskState {
packageid: string packageid: string
currentIndex: number currentIndex: number
approvalList: any[] approvalList: any[]
refresh: boolean
immersion: boolean
} }
export interface TaskEntity { export interface TaskEntity {

@ -10,10 +10,11 @@ export interface PackageListItem {
} }
// 任务包状态 // 任务包状态
export interface PackageState { export interface OrderState {
activeId: string activeId: string
currentIndex: number currentIndex: number
packageList: PackageListItem[] packageList: PackageListItem[]
immersion: boolean
} }
// 任务实体 // 任务实体

Loading…
Cancel
Save