From b1bdaa3be6bc37ec2dea407eebf15a764172fdee Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期一, 14 七月 2025 09:55:23 +0800 Subject: [PATCH] 修改 --- public/scenarioExample.docx | 0 src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue | 55 src/api/supplier/satisaied.js | 36 src/api/selfProblems/plan.js | 36 src/views/work/selfProblems/scenario/index.vue | 222 +++ src/api/supplier/supplierList.js | 36 src/views/work/selfProblems/plan/index.vue | 265 ++++ src/api/selfProblems/nameList.js | 36 src/api/selfProblems/tableList.js | 36 src/views/certificatePdf.vue | 11 src/api/selfProblems/scenario.js | 36 public/planExample.docx | 0 src/components/Tinymce/Tinymce.vue | 6 src/views/work/qualityInfo/supplierQuality/satisfied/components/editDialog.vue | 275 ++++ src/views/work/selfProblems/internalAudit/auditorManage/nameList/components/nameListDialog.vue | 198 +++ src/views/work/selfProblems/internalAudit/auditorManage/tableList/components/editDialog.vue | 253 ++++ src/views/work/selfProblems/plan/components/planDialog.vue | 561 +++++++++ src/views/work/selfProblems/scenario/components/scenarioDialog.vue | 364 +++++ src/views/work/qualityInfo/supplierQuality/supplierList/components/supplierDialog.vue | 219 +++ src/views/work/selfProblems/internalAudit/auditorManage/tableList/index.vue | 228 +++ src/views/work/qualityInfo/supplierQuality/satisfied/index.vue | 316 +++++ public/tinymce/plugins/formatpainter/plugin.min.js | 1 src/views/work/selfProblems/internalAudit/auditorManage/nameList/index.vue | 215 +++ src/views/work/qualityInfo/supplierQuality/supplierList/index.vue | 201 +++ 24 files changed, 3,601 insertions(+), 5 deletions(-) diff --git a/public/planExample.docx b/public/planExample.docx new file mode 100644 index 0000000..8ee28f6 --- /dev/null +++ b/public/planExample.docx Binary files differ diff --git a/public/scenarioExample.docx b/public/scenarioExample.docx new file mode 100644 index 0000000..0e2f578 --- /dev/null +++ b/public/scenarioExample.docx Binary files differ diff --git a/public/tinymce/plugins/formatpainter/plugin.min.js b/public/tinymce/plugins/formatpainter/plugin.min.js new file mode 100644 index 0000000..055e9c7 --- /dev/null +++ b/public/tinymce/plugins/formatpainter/plugin.min.js @@ -0,0 +1 @@ +!function(l){"use strict";var e,r,n,t,o,i,m,a,d,u,c,s,v,f,p=function(e){var r=e,n=function(){return r};return{get:n,set:function(e){r=e},clone:function(){return p(n())}}},g=function(e){return parseInt(e,10)},h=function(e,r,n){return{major:e,minor:r,patch:n}},b=function(e){var r=/([0-9]+)\.([0-9]+)\.([0-9]+)(?:(\-.+)?)/.exec(e);return r?h(g(r[1]),g(r[2]),g(r[3])):h(0,0,0)},y=function(e,r){var n=e-r;return 0===n?0:0<n?1:-1},S=function(e,r){return!!e&&-1===function(e,r){var n=y(e.major,r.major);if(0!==n)return n;var t=y(e.minor,r.minor);if(0!==t)return t;var o=y(e.patch,r.patch);return 0!==o?o:0}(b([(n=e).majorVersion,n.minorVersion].join(".").split(".").slice(0,3).join(".")),b(r));var n},O=function(e){return function(){return e}},w=O(!1),N=O(!0),T=w,x=N,E=function(){return k},k=(t={fold:function(e,r){return e()},is:T,isSome:T,isNone:x,getOr:n=function(e){return e},getOrThunk:r=function(e){return e()},getOrDie:function(e){throw new Error(e||"error: getOrDie called on none.")},getOrNull:function(){return null},getOrUndefined:function(){},or:n,orThunk:r,map:E,ap:E,each:function(){},bind:E,flatten:E,exists:T,forall:x,filter:E,equals:e=function(e){return e.isNone()},equals_:e,toArray:function(){return[]},toString:O("none()")},Object.freeze&&Object.freeze(t),t),A=function(n){var e=function(){return n},r=function(){return o},t=function(e){return e(n)},o={fold:function(e,r){return r(n)},is:function(e){return n===e},isSome:x,isNone:T,getOr:e,getOrThunk:e,getOrDie:e,getOrNull:e,getOrUndefined:e,or:r,orThunk:r,map:function(e){return A(e(n))},ap:function(e){return e.fold(E,function(e){return A(e(n))})},each:function(e){e(n)},bind:t,flatten:e,exists:t,forall:t,filter:function(e){return e(n)?o:k},equals:function(e){return e.is(n)},equals_:function(e,r){return e.fold(T,function(e){return r(n,e)})},toArray:function(){return[n]},toString:function(){return"some("+n+")"}};return o},_={some:A,none:E,from:function(e){return null==e?k:A(e)}},D=function(r){return function(e){return function(e){if(null===e)return"null";var r=typeof e;return"object"===r&&Array.prototype.isPrototypeOf(e)?"array":"object"===r&&String.prototype.isPrototypeOf(e)?"string":r}(e)===r}},C=D("string"),L=D("boolean"),R=D("function"),P=D("number"),F=void 0===(o=Array.prototype.indexOf)?function(e,r){return q(e,r)}:function(e,r){return o.call(e,r)},I=function(e,r){return-1<F(e,r)},j=function(e,r){return V(e,r).isSome()},M=function(e,r){for(var n=e.length,t=new Array(n),o=0;o<n;o++){var i=e[o];t[o]=r(i,o,e)}return t},B=function(e,r){for(var n=[],t=0,o=e.length;t<o;t++){var i=e[t];r(i,t,e)&&n.push(i)}return n},U=function(e,r){for(var n=0,t=e.length;n<t;n++){var o=e[n];if(r(o,n,e))return _.some(o)}return _.none()},V=function(e,r){for(var n=0,t=e.length;n<t;n++)if(r(e[n],n,e))return _.some(n);return _.none()},q=function(e,r){for(var n=0,t=e.length;n<t;++n)if(e[n]===r)return n;return-1},X=Array.prototype.push,z=function(e,r){return function(e){for(var r=[],n=0,t=e.length;n<t;++n){if(!Array.prototype.isPrototypeOf(e[n]))throw new Error("Arr.flatten item "+n+" was not an array, input: "+e);X.apply(r,e[n])}return r}(M(e,r))},H=(Array.prototype.slice,R(Array.from)&&Array.from,Object.keys),W=Object.hasOwnProperty,Y=function(e,r){for(var n=H(e),t=0,o=n.length;t<o;t++){var i=n[t];r(e[i],i,e)}},G=function(t,o){var i={};return Y(t,function(e,r){var n=o(e,r,t);i[n.k]=n.v}),i},$=function(e){return n=function(e){return e},t=[],Y(e,function(e,r){t.push(n(e,r))}),t;var n,t},K=function(e,r){return Z(e,r)?_.from(e[r]):_.none()},Z=function(e,r){return W.call(e,r)},J=(l.Node.ATTRIBUTE_NODE,l.Node.CDATA_SECTION_NODE,l.Node.COMMENT_NODE,l.Node.DOCUMENT_NODE,l.Node.DOCUMENT_TYPE_NODE,l.Node.DOCUMENT_FRAGMENT_NODE,l.Node.ELEMENT_NODE),Q=l.Node.TEXT_NODE,ee=(l.Node.PROCESSING_INSTRUCTION_NODE,l.Node.ENTITY_REFERENCE_NODE,l.Node.ENTITY_NODE,l.Node.NOTATION_NODE,i=Q,function(e){return e.dom().nodeType===i}),re=function(e,r,n){!function(e,r,n){if(!(C(n)||L(n)||P(n)))throw l.console.error("Invalid call to Attr.set. Key ",r,":: Value ",n,":: Element ",e),new Error("Attribute value was not simple");e.setAttribute(r,n+"")}(e.dom(),r,n)},ne=function(e,r){var n=e.dom().getAttribute(r);return null===n?void 0:n},te=function(e,r){e.dom().removeAttribute(r)},oe=function(e,r){var n=ne(e,r);return void 0===n||""===n?[]:n.split(" ")},ie=function(e){return void 0!==e.dom().classList},ae=function(e){return oe(e,"class")},ue=function(e,r){return o=r,i=oe(n=e,t="class").concat([o]),re(n,t,i.join(" ")),!0;var n,t,o,i},ce=function(e,r){return o=r,0<(i=B(oe(n=e,t="class"),function(e){return e!==o})).length?re(n,t,i.join(" ")):te(n,t),!1;var n,t,o,i},se=function(e,r){var n;ie(e)?e.dom().classList.remove(r):ce(e,r),0===(ie(n=e)?n.dom().classList:ae(n)).length&&te(n,"class")},fe=function(e){if(null==e)throw new Error("Node cannot be null or undefined");return{dom:O(e)}},le={fromHtml:function(e,r){var n=(r||l.document).createElement("div");if(n.innerHTML=e,!n.hasChildNodes()||1<n.childNodes.length)throw l.console.error("HTML does not have a single root node",e),new Error("HTML must have a single root node");return fe(n.childNodes[0])},fromTag:function(e,r){var n=(r||l.document).createElement(e);return fe(n)},fromText:function(e,r){var n=(r||l.document).createTextNode(e);return fe(n)},fromDom:fe,fromPoint:function(e,r,n){var t=e.dom();return _.from(t.elementFromPoint(r,n)).map(fe)}},me=function(e,r){e.fire("FormatPainterToggle",{state:r})};(a=m||(m={})).Retrival="Retrieval",a.Application="Application",(u=d||(d={})).ListSchema="ListSchema",u.SubstitutionSchema="SubstitionSchema",(s=c||(c={})).InsertUnorderedList="InsertUnorderedList",s.InsertOrderedList="InsertOrderedList",s.InsertDefinitionList="InsertDefinitionList",(f=v||(v={})).Table="Table",f.Unspecified="Unspecified";var de,ve,pe,ge=function(e){var r,n;r=le.fromDom(e.getBody()),n="tox-cursor-format-painter",ie(r)?r.dom().classList.add(n):ue(r,n)},he=function(e,r){var n;n=e,se(le.fromDom(n.getBody()),"tox-cursor-format-painter"),r.set(m.Retrival),me(e,!1)},be=function(e,r){r.get()===m.Application?he(e,r):function(r,n){ge(r),n.set(m.Application),me(r,!0),r.execCommand("mceRetrieveFormats");var e=function(){n.get()===m.Application&&(r.execCommand("mcePaintFormats"),he(r,n)),o()},t=function(e){27===e.keyCode&&(he(r,n),o())};r.on("click",e),r.on("keydown",t);var o=function(){r.off("click",e),r.off("keydown",t)}}(e,r)},ye=(void 0!==l.window?l.window:Function("return this;")(),function(){return Se(0,0)}),Se=function(e,r){return{major:e,minor:r}},Oe={nu:Se,detect:function(e,r){var n=String(r).toLowerCase();return 0===e.length?ye():function(e,r){var n=function(e,r){for(var n=0;n<e.length;n++){var t=e[n];if(t.test(r))return t}}(e,r);if(!n)return{major:0,minor:0};var t=function(e){return Number(r.replace(n,"$"+e))};return Se(t(1),t(2))}(e,n)},unknown:ye},we="Firefox",Ne=function(e,r){return function(){return r===e}},Te=function(e){var r=e.current;return{current:r,version:e.version,isEdge:Ne("Edge",r),isChrome:Ne("Chrome",r),isIE:Ne("IE",r),isOpera:Ne("Opera",r),isFirefox:Ne(we,r),isSafari:Ne("Safari",r)}},xe={unknown:function(){return Te({current:void 0,version:Oe.unknown()})},nu:Te,edge:O("Edge"),chrome:O("Chrome"),ie:O("IE"),opera:O("Opera"),firefox:O(we),safari:O("Safari")},Ee="Windows",ke="Android",Ae="Solaris",_e="FreeBSD",De=function(e,r){return function(){return r===e}},Ce=function(e){var r=e.current;return{current:r,version:e.version,isWindows:De(Ee,r),isiOS:De("iOS",r),isAndroid:De(ke,r),isOSX:De("OSX",r),isLinux:De("Linux",r),isSolaris:De(Ae,r),isFreeBSD:De(_e,r)}},Le={unknown:function(){return Ce({current:void 0,version:Oe.unknown()})},nu:Ce,windows:O(Ee),ios:O("iOS"),android:O(ke),linux:O("Linux"),osx:O("OSX"),solaris:O(Ae),freebsd:O(_e)},Re=function(e,r){var n=String(r).toLowerCase();return U(e,function(e){return e.search(n)})},Pe=function(e,n){return Re(e,n).map(function(e){var r=Oe.detect(e.versionRegexes,n);return{current:e.name,version:r}})},Fe=function(e,n){return Re(e,n).map(function(e){var r=Oe.detect(e.versionRegexes,n);return{current:e.name,version:r}})},Ie=function(e,r){return-1!==e.indexOf(r)},je=/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,Me=function(r){return function(e){return Ie(e,r)}},Be=[{name:"Edge",versionRegexes:[/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],search:function(e){return Ie(e,"edge/")&&Ie(e,"chrome")&&Ie(e,"safari")&&Ie(e,"applewebkit")}},{name:"Chrome",versionRegexes:[/.*?chrome\/([0-9]+)\.([0-9]+).*/,je],search:function(e){return Ie(e,"chrome")&&!Ie(e,"chromeframe")}},{name:"IE",versionRegexes:[/.*?msie\ ?([0-9]+)\.([0-9]+).*/,/.*?rv:([0-9]+)\.([0-9]+).*/],search:function(e){return Ie(e,"msie")||Ie(e,"trident")}},{name:"Opera",versionRegexes:[je,/.*?opera\/([0-9]+)\.([0-9]+).*/],search:Me("opera")},{name:"Firefox",versionRegexes:[/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],search:Me("firefox")},{name:"Safari",versionRegexes:[je,/.*?cpu os ([0-9]+)_([0-9]+).*/],search:function(e){return(Ie(e,"safari")||Ie(e,"mobile/"))&&Ie(e,"applewebkit")}}],Ue=[{name:"Windows",search:Me("win"),versionRegexes:[/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]},{name:"iOS",search:function(e){return Ie(e,"iphone")||Ie(e,"ipad")},versionRegexes:[/.*?version\/\ ?([0-9]+)\.([0-9]+).*/,/.*cpu os ([0-9]+)_([0-9]+).*/,/.*cpu iphone os ([0-9]+)_([0-9]+).*/]},{name:"Android",search:Me("android"),versionRegexes:[/.*?android\ ?([0-9]+)\.([0-9]+).*/]},{name:"OSX",search:Me("os x"),versionRegexes:[/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]},{name:"Linux",search:Me("linux"),versionRegexes:[]},{name:"Solaris",search:Me("sunos"),versionRegexes:[]},{name:"FreeBSD",search:Me("freebsd"),versionRegexes:[]}],Ve={browsers:O(Be),oses:O(Ue)},qe=function(e){var r,n,t,o,i,a,u,c,s,f,l,m=Ve.browsers(),d=Ve.oses(),v=Pe(m,e).fold(xe.unknown,xe.nu),p=Fe(d,e).fold(Le.unknown,Le.nu);return{browser:v,os:p,deviceType:(n=v,t=e,o=(r=p).isiOS()&&!0===/ipad/i.test(t),i=r.isiOS()&&!o,a=r.isAndroid()&&3===r.version.major,u=r.isAndroid()&&4===r.version.major,c=o||a||u&&!0===/mobile/i.test(t),s=r.isiOS()||r.isAndroid(),f=s&&!c,l=n.isSafari()&&r.isiOS()&&!1===/safari/i.test(t),{isiPad:O(o),isiPhone:O(i),isTablet:O(c),isPhone:O(f),isTouch:O(s),isAndroid:r.isAndroid,isiOS:r.isiOS,isWebView:O(l)})}},Xe=(pe=!(de=function(){var e=l.navigator.userAgent;return qe(e)}),function(){for(var e=[],r=0;r<arguments.length;r++)e[r]=arguments[r];return pe||(pe=!0,ve=de.apply(null,e)),ve}),ze=J,He=(Xe().browser.isIE(),function(e,r){var n=e.dom();if(n.nodeType!==ze)return!1;if(void 0!==n.matches)return n.matches(r);if(void 0!==n.msMatchesSelector)return n.msMatchesSelector(r);if(void 0!==n.webkitMatchesSelector)return n.webkitMatchesSelector(r);if(void 0!==n.mozMatchesSelector)return n.mozMatchesSelector(r);throw new Error("Browser lacks native selectors")}),We=function(e,r,n){for(var t=e.dom(),o=R(n)?n:O(!1);t.parentNode;){t=t.parentNode;var i=le.fromDom(t);if(r(i))return _.some(i);if(o(i))break}return _.none()},Ye=function(e,r,n){var t,o,i,a,u;return t=We,a=n,u=o=e,(i=r)(u)?_.some(o):R(a)&&a(o)?_.none():t(o,i,a)},Ge={formatpainter_checklist:{selector:"ul",classes:"tox-checklist"},formatpainter_liststyletype:{selector:"ul,ol",styles:{listStyleType:"%value"}},formatpainter_borderstyle:{selector:"td,th",styles:{borderTopStyle:"%valueTop",borderRightStyle:"%valueRight",borderBottomStyle:"%valueBottom",borderLeftStyle:"%valueLeft"},remove_similar:!0},formatpainter_bordercolor:{selector:"td,th",styles:{borderTopColor:"%valueTop",borderRightColor:"%valueRight",borderBottomColor:"%valueBottom",borderLeftColor:"%valueLeft"},remove_similar:!0},formatpainter_backgroundcolor:{selector:"td,th",styles:{backgroundColor:"%value"},remove_similar:!0},formatpainter_removeformat:[{selector:"b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins",remove:"all",split:!0,expand:!1,block_expand:!0,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*:not(tr,td,th,table)",attributes:["style","class"],split:!1,expand:!1,deep:!0}]},$e=function(i,e){return K(e,"selector").exists(function(e){var r=i.getBody(),n=i.selection.getStart(),t=i.dom.getParents(n,O(!0),r),o=i.selection.getSelectedBlocks();return i.dom.is(t.concat(o),e)})},Ke=function(t,e){return j(t.formatter.get(e),function(e){return r=t,Z(n=e,"inline")&&!$e(r,n);var r,n})},Ze=function(t,e,r){return j(e.get(r),function(e){return r=t,Z(n=e,"block")||$e(r,n);var r,n})},Je=function(e){return 1<e.length&&"%"===e.charAt(0)},Qe=function(e,r){return j(e.formatter.get(r),function(e){return n=K(r=e,"styles").exists(function(e){return j($(e),Je)}),t=K(r,"attributes").exists(function(e){return j($(e),Je)}),n||t;var r,n,t})},er=function(e){return He(e,"OL,UL,DL")},rr=function(e){return He(e,"LI,DT,DD")},nr=function(e,r,n){var t,o=e.formatter,i=Ke(e,n.formatName),a=Ze(e,o,n.formatName),u=(t=n.formatName,I(["formatpainter_borderstyle","formatpainter_bordercolor","formatpainter_backgroundcolor"],t));(r.table&&u||r.inline&&i||r.block&&a&&!u)&&o.apply(n.formatName,n.substitutedVariables)},tr=function(e,r){return function(e,r){for(var n=[],t=0;t<e.length;t++){var o=e[t];if(!o.isSome())return _.none();n.push(o.getOrDie())}return _.some(r.apply(null,n))}([Ye(le.fromDom(e.getStart()),er,r),Ye(le.fromDom(e.getEnd()),er,r)],function(e,r){return n=r,e.dom()===n.dom();var n}).getOr(!1)},or=function(e){var r=e.selection,n=r.getRng(),t=le.fromDom(e.getBody()),o=B(e.selection.getSelectedBlocks().map(le.fromDom),rr),i=n.collapsed&&o.length,a=o.length&&!tr(r,t);return 1<o.length||i||a},ir=function(t,e){var r,n;r=t,n=e.context,r.formatter.remove("formatpainter_removeformat"),n===v.Table&&function(e,r){for(var n=0,t=e.length;n<t;n++)r(e[n],n,e)}(["formatpainter_borderstyle","formatpainter_bordercolor","formatpainter_backgroundcolor"],function(e){r.formatter.remove(e)}),or(r)&&r.execCommand("RemoveList");var o,i,a,u,c,s,f=(a=(o=t).selection.getStart(),u=o.selection.getRng().collapsed,c=0<o.dom.select("td[data-mce-selected]").length,s=!!o.dom.getParent(a,"TABLE"),{inline:!0,table:u&&s||c,block:u||(i=o.selection,1<i.getSelectedBlocks().length)||c});e.schemas.forEach(function(e){switch(e.kind){case d.ListSchema:r=t,n=e,f.block&&r.execCommand(n.command);break;case d.SubstitutionSchema:nr(t,f,e)}var r,n})},ar=function(e){return ie(e)?function(e){for(var r=e.dom().classList,n=new Array(r.length),t=0;t<r.length;t++)n[t]=r.item(t);return n}(e):ae(e)},ur=function(e,r){var n,t,o=e.dom(),i=l.window.getComputedStyle(o).getPropertyValue(r),a=""!==i||null!=(t=ee(n=e)?n.dom().parentNode:n.dom())&&t.ownerDocument.body.contains(t)?i:cr(o,r);return null===a?void 0:a},cr=function(e,r){return void 0!==e.style?e.style.getPropertyValue(r):""},sr=function(){return(sr=Object.assign||function(e){for(var r,n=1,t=arguments.length;n<t;n++)for(var o in r=arguments[n])Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o]);return e}).apply(this,arguments)},fr=function(o,e){return G(e,function(e,r){return{k:e.slice(1,e.length),v:(n=o,t=r,"class"===t?ar(n).filter(function(e){return!/^(mce-.*)/.test(e)}).join(" "):ne(n,t))};var n,t})},lr=function(e){return(r=e,n=function(e){return 1<(r=e).length&&"%"===r.charAt(0);var r},t={},o={},Y(r,function(e,r){(n(e,r)?t:o)[r]=e}),{t:t,f:o}).t;var r,n,t,o},mr=function(e,n){var r=K(e,"styles").map(function(e){return t=n,r=lr(e),G(r,function(e,r){return{k:e.slice(1,e.length),v:ur(t,(n=r,n.replace(/([A-Z])/g,function(e){return"-"+e[0].toLowerCase()})))};var n});var t,r}),t=K(e,"attributes").map(function(e){return fr(n,lr(e))}),o=sr({},r.getOr({}),t.getOr({}));return $(o).every(function(e){return""!==e})?_.some(o):_.none()},dr=function(e,r,n){return(t=e.get(r),0===t.length?_.none():_.some(t[0])).bind(function(e){return mr(e,n)}).map(function(e){return{kind:d.SubstitutionSchema,formatName:r,substitutedVariables:e}});var t},vr=function(n,t){return(e=n,r=e.getParam("formatpainter_blacklisted_formats","link,address,removeformat,formatpainter_removeformat","string").split(/[ ,]/),H(e.formatter.get()).filter(function(e){return!I(r,e)})).filter(function(e){var r=Qe(n,e);return n.formatter.matchNode(t.dom(),e,{},r)});var e,r},pr=function(e){return(r=e,U($(c),function(e){return r.queryCommandState(e)})).map(function(e){return{kind:d.ListSchema,command:e}});var r},gr=function(e){var r,n,t,o,i,a=e.dom,u=e.selection.getStart();return{schemas:pr(e).toArray().concat((t=e,o=u,i=t.dom.getParents(o,O(!0)),z(M(i,le.fromDom),function(r){return z(vr(t,r),function(e){return dr(t.formatter,e,r).toArray()})}))),context:(r=a,n=u,r.getParent(n,"TABLE")?v.Table:v.Unspecified)}},hr=function(e){if(S(tinymce,"4.9.0"))return l.window.console.error("The format painter plugin requires at least version 4.9.0 of TinyMCE."),{};var n,r,t,o,i,a,u,c,s=p(m.Retrival),f=p({schemas:[],context:v.Unspecified});return(n=e).on("PreInit",function(){Y(Ge,function(e,r){n.formatter.get(r)||n.formatter.register(r,e)})}),t=s,o=f,(r=e).addCommand("mceToggleFormatPainter",function(){be(r,t)}),r.addCommand("mcePaintFormats",function(){r.undoManager.transact(function(){ir(r,o.get())})}),r.addCommand("mceRetrieveFormats",function(){o.set(gr(r))}),(i=e).ui?(u=i).ui.registry.addToggleButton("formatpainter",{active:!1,icon:"format-painter",tooltip:"Format Painter",onAction:function(){return u.execCommand("mceToggleFormatPainter")},onSetup:function(r){var e=function(e){r.setActive(e.state)};return u.on("FormatPainterToggle",e),function(){return u.off("FormatPainterToggle",e)}}}):(a=i).addButton("formatpainter",{active:!1,icon:"format-painter",tooltip:"Format Painter",cmd:"mceToggleFormatPainter",onPostRender:function(r){a.on("FormatPainterToggle",function(e){r.control.active(e.state)})}}),(c=e).addShortcut("Meta+alt+C","",function(){c.execCommand("mceRetrieveFormats")}),c.addShortcut("Meta+alt+V","",function(){c.execCommand("mcePaintFormats")}),{}};return function(){tinymce.PluginManager.add("formatpainter",hr)}}(window)(); diff --git a/src/api/selfProblems/nameList.js b/src/api/selfProblems/nameList.js new file mode 100644 index 0000000..c2b51fd --- /dev/null +++ b/src/api/selfProblems/nameList.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getPersonPage(params) { + return request({ + url: '/internal/audit/person/list', + method: 'get', + params: params + }) +} + + +export function addPerson(data) { + return request({ + url: '/internal/audit/person/insert', + method: 'post', + data: data + }) +} + +export function editPerson(params) { + return request({ + url: `/internal/audit/person/update`, + method: 'post', + data: params + }) +} + +export function delPerson(data) { + return request({ + url: `/internal/audit/person/deleted?personId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/selfProblems/plan.js b/src/api/selfProblems/plan.js new file mode 100644 index 0000000..ad9c05b --- /dev/null +++ b/src/api/selfProblems/plan.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getPlanPage(params) { + return request({ + url: '/internal/audit/carry/list', + method: 'get', + params: params + }) +} + + +export function addPlan(data) { + return request({ + url: '/internal/audit/carry/insert', + method: 'post', + data: data + }) +} + +export function editPlan(params) { + return request({ + url: `/internal/audit/carry/update`, + method: 'post', + data: params + }) +} + +export function delPlan(data) { + return request({ + url: `/internal/audit/carry/deleted?carryId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/selfProblems/scenario.js b/src/api/selfProblems/scenario.js new file mode 100644 index 0000000..f103ea6 --- /dev/null +++ b/src/api/selfProblems/scenario.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getScenarioPage(params) { + return request({ + url: '/internal/audit/plan/list', + method: 'get', + params: params + }) +} + + +export function addScenario(data) { + return request({ + url: '/internal/audit/plan/insert', + method: 'post', + data: data + }) +} + +export function editScenario(params) { + return request({ + url: `/internal/audit/plan/update`, + method: 'post', + data: params + }) +} + +export function delScenario(data) { + return request({ + url: `/internal/audit/plan/deleted?planId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/selfProblems/tableList.js b/src/api/selfProblems/tableList.js new file mode 100644 index 0000000..8eec89d --- /dev/null +++ b/src/api/selfProblems/tableList.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getEvaluatePage(params) { + return request({ + url: '/internal/audit/evaluate/list', + method: 'get', + params: params + }) +} + + +export function addEvaluate(data) { + return request({ + url: '/internal/audit/evaluate/insert', + method: 'post', + data: data + }) +} + +export function editEvaluate(params) { + return request({ + url: `/internal/audit/evaluate/update`, + method: 'post', + data: params + }) +} + +export function delEvaluate(data) { + return request({ + url: `/internal/audit/evaluate/deleted?evaluateId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/supplier/satisaied.js b/src/api/supplier/satisaied.js new file mode 100644 index 0000000..c44c15b --- /dev/null +++ b/src/api/supplier/satisaied.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getSatisfiedPage(params) { + return request({ + url: '/internal/audit/customer/list', + method: 'get', + params: params + }) +} + + +export function addSatisfied(data) { + return request({ + url: '/internal/audit/customer/insert', + method: 'post', + data: data + }) +} + +export function editSatisfied(params) { + return request({ + url: `/internal/audit/customer/update`, + method: 'post', + data: params + }) +} + +export function delSatisfied(data) { + return request({ + url: `/internal/audit/customer/deleted?customerId=${data}`, + method: 'get' + }) +} + + diff --git a/src/api/supplier/supplierList.js b/src/api/supplier/supplierList.js new file mode 100644 index 0000000..fe53c2d --- /dev/null +++ b/src/api/supplier/supplierList.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' + + +export function getSupplierPage(params) { + return request({ + url: '/internal/audit/supplier/list', + method: 'get', + params: params + }) +} + + +export function addSupplier(data) { + return request({ + url: '/internal/audit/supplier/insert', + method: 'post', + data: data + }) +} + +export function editSupplier(params) { + return request({ + url: `/internal/audit/supplier/update`, + method: 'post', + data: params + }) +} + +export function delSupplier(data) { + return request({ + url: `/internal/audit/supplier/deleted?supplierId=${data}`, + method: 'get' + }) +} + + diff --git a/src/components/Tinymce/Tinymce.vue b/src/components/Tinymce/Tinymce.vue index 3a47e16..fef35bd 100644 --- a/src/components/Tinymce/Tinymce.vue +++ b/src/components/Tinymce/Tinymce.vue @@ -24,6 +24,7 @@ import "tinymce/plugins/wordcount"; import "tinymce/plugins/fullscreen"; import "../../../public/tinymce/plugins/upfile/index"; +import "../../../public/tinymce/plugins/formatpainter/plugin.min"; import {getToken} from "@/utils/auth"; // import "tinymce/plugins/upfile"; // import "tinymce/plugins/attachment"; @@ -47,11 +48,11 @@ }, plugins: { type: [String, Array], - default: " paragraphspacing upfile lists image table wordcount fullscreen " + default: "formatpainter paragraphspacing upfile lists image table wordcount fullscreen " }, toolbar: { type: [String, Array], - default: " styleselect fontsizeselect paragraphspacing | upfile image bold italic | fontselect |alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | undo redo | lists insertfile table | removeformat fullscreen " + default: " styleselect fontsizeselect paragraphspacing formatpainter | upfile image bold italic | fontselect |alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | undo redo | lists insertfile table | removeformat fullscreen " } }, data() { @@ -81,6 +82,7 @@ '黑体=SimHei, "Microsoft YaHei", "PingFang SC", sans-serif;' + // Windows黑体 '微软雅黑=Microsoft YaHei, sans-serif;' + '仿宋=FangSong, "Fang", serif;', + fontsize_formats: "8pt 10pt 12pt 13pt 14pt 18pt 24pt 36pt", // 字体样式应用到文本时使用 <span> 而非 <font> inline_styles: true, diff --git a/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue b/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue index 2b4356f..e480e98 100644 --- a/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue +++ b/src/views/build/conpanyFunctionConsult/qualityManage/rangeManage/range/index.vue @@ -42,7 +42,17 @@ node-key="id" :current-node-key="currentSelectedKey" @node-click="handleNodeClick" - ></el-tree> + > + <template #default="{ node,data }"> + <el-tooltip + :content="data.mess" + placement="bottom" + :disabled="!isTextOverflow(data)" + > + <span class="tree-text">{{ data.mess }}</span> + </el-tooltip> + </template> + </el-tree> </div> <el-empty v-else description="暂无数据" /> </div> @@ -236,6 +246,29 @@ } loading.value = false; } +const textMeasureRef = ref(null); +const getMeasureElement = () => { + if (!textMeasureRef.value) { + const el = document.createElement('span'); + el.className = 'text-measure-element'; + el.style.cssText = ` + position: absolute; + visibility: hidden; + white-space: nowrap; + font-size: 14px; /* 匹配实际字体大小 */ + `; + document.body.appendChild(el); + textMeasureRef.value = el; + } + return textMeasureRef.value; +}; +// 判断文本是否溢出 +const isTextOverflow = (text) => { + const measureEl = getMeasureElement(); + measureEl.textContent = text.mess; + return measureEl.scrollWidth > 300; // 180px 是节点容器实际宽度 +}; + const handleTree = (val) => { const traverse = (nodes, currentPath = '') => { nodes.forEach((node, index) => { @@ -597,6 +630,26 @@ :deep(.el-tree){ background: none; } + :deep(.el-tooltip ) + { + color: black; + text-overflow: ellipsis; + overflow: hidden; + word-break: break-all; + white-space: nowrap; + } + .tree-text { + display: inline-block; + max-width: 300px; /* 根据实际容器宽度调整 */ + white-space: nowrap; /* 强制不换行 */ + overflow: hidden; /* 隐藏溢出 */ + text-overflow: ellipsis; /* 显示省略号 */ + } + /* 可选:移除el-tree默认的节点内边距 */ + .el-tree-node__content { + padding-right: 5px; + } + .tree-container { max-width: 600px; margin-top: 20px; diff --git a/src/views/certificatePdf.vue b/src/views/certificatePdf.vue index 167f502..90b1df7 100644 --- a/src/views/certificatePdf.vue +++ b/src/views/certificatePdf.vue @@ -29,7 +29,14 @@ }) const {info} = toRefs(data) onMounted(()=>{ - data.info = route.query + if(route.query.type == 'inter'){ + data.info.name = route.query.paperName + data.info.stuName = route.query.personName + data.info.number = route.query.certifity + data.info.companyName = route.query.companyName + }else { + data.info = route.query + } console.log(' data.info', data.info) nextTick(()=>{ getPdf() @@ -37,7 +44,7 @@ }) function getPdf() { - let title = data.info.name + '证书' + let title = data.info.stuName + '_' + data.info.name + '合格证书' htmlToPdf(title); } diff --git a/src/views/work/qualityInfo/supplierQuality/satisfied/components/editDialog.vue b/src/views/work/qualityInfo/supplierQuality/satisfied/components/editDialog.vue new file mode 100644 index 0000000..6da8030 --- /dev/null +++ b/src/views/work/qualityInfo/supplierQuality/satisfied/components/editDialog.vue @@ -0,0 +1,275 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="600px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item v-if="state.isAdmin" label="企业:" prop="companyId"> + <el-select v-model="state.form.companyId" placeholder="请选择" clearable style="width: 100%"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year" > + <el-select + :disabled="state.title === '查看'" + v-model="state.form.year" + filterable + allow-create + default-first-option + :reserve-keyword="false" + placeholder="请选择年份" + @change="handleChangeNum" + style="width: 100%" + > + <el-option + v-for="item in state.yearList" + :key="item.value" + :label="item.label" + :value="item.label" + /> + </el-select> + </el-form-item> + <el-form-item label="文件名称:" prop="fileName"> + <el-input v-model.trim="state.form.fileName" :disabled="state.title =='查看'" placeholder="文件名称"></el-input> + </el-form-item> + <el-form-item label="文件:" prop="filePath"> + <el-upload accept=".doc,.docx" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :limit='state.fileLimit' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles)" > + <el-button type="primary">点击上传</el-button> + <template #tip> + <div class="el-upload__tip">支持上传.doc、.docx格式文档,尺寸小于5M,最多可上传1张</div> + </template> + </el-upload> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {addIndustryTemp, updateIndustryTemp, updateInfoPlatforms} from "@/api/staffManage/staff"; +import {getToken} from "@/utils/auth"; +import {delPic} from "@/api/onlineEducation/banner"; +import {getIndustry} from "@/api/system/industry"; +import {addSatisfied, editSatisfied} from "@/api/supplier/satisaied"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const checkFiles = (rule, value, callback) => { + if (state.fileList.length == 0) { + callback(new Error('请上传模板文件')) + } else { + callback() + } +} +const state = reactive({ + title: '', + form: { + id: null, + year:'', + filePath: '', + fileName: '', + companyId: null, + }, + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + year: [{ required: true, message: '请输入年份', trigger: 'blur' }], + fileName: [{ required: true, message: '请输入文件名称', trigger: 'blur' }], + filePath: [{ required: true, validator: checkFiles, trigger: 'blur' }], + }, + isAdmin: false, + companyList: [], + industryList: [], + uploadUrl: import.meta.env.VITE_APP_BASE_API + '/system/common/uploadFile', + header: { + Authorization: getToken() + }, + fileLimit: 1, + fileList: [], + yearList: [ + { + value: 1, + label: '2025' + }, + { + value: 2, + label: '2024' + }, + { + value: 3, + label: '2023' + }, + { + value: 4, + label: '2022' + }, + { + value: 5, + label: '2021' + }, + ], +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyId, isAdmin, companyList) => { + state.isAdmin = isAdmin + if(isAdmin){ + state.companyList = companyList + } + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + state.form.companyId = companyId + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + if(value.filePath) { + const obj = { + url: value.filePath, + name: value.fileName + } + state.fileList = [obj] + } + } + dialogVisible.value = true +} + +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title == '新增'){ + const {id,...data} = state.form + const res = await addSatisfied(data) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + }else{ + const res = await editSatisfied(state.form) + if(res.code == 200){ + ElMessage.success(res.message) + emit('getList') + handleClose() + dialogVisible.value = false; + }else{ + ElMessage.warning(res.message) + } + } + } +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.form.fileName = res.data.originName + state.form.filePath = res.data.path + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: '文件上传失败' + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; +const handleRemove = async (file, uploadFiles) => { + let path = state.form.filePath; + await delPic({path: path}).then(res => { + if(res.code == 200){ + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + state.form.filePath = '' + state.form.fileName = '' + }else{ + ElMessage({ + type: 'warning', + message: res.message + }) + } + }).catch(() => { + state.form.imgUrl = '' + }); +} + +const handleClose = () => { + state.form = { + id: null, + year:'', + filePath: '', + fileName: '', + companyId: null, + } + state.fileList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} +const handleChangeNum = (value) => { + if (!/^\d+$/.test(value)) { // 验证是否为数字 + ElMessage.warning('只能输入数字') + state.form.year = '' // 重置选择,避免非法值被添加到options中 + } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项 + state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同) + } +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/qualityInfo/supplierQuality/satisfied/index.vue b/src/views/work/qualityInfo/supplierQuality/satisfied/index.vue new file mode 100644 index 0000000..00ce096 --- /dev/null +++ b/src/views/work/qualityInfo/supplierQuality/satisfied/index.vue @@ -0,0 +1,316 @@ +<template> + <div class="app-container"> + <div style="display: flex;justify-content: space-between"> + <el-form :inline="true" style="display: flex;align-items: center;flex-wrap: wrap;" > + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item v-if="isAdmin" label="企业:" > + <el-select v-model="data.queryParams.companyId" placeholder="请选择" clearable> + <el-option + v-for="item in companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" style="margin-left: 20px"> + <el-select + v-model="data.queryParams.year" + placeholder="请选择年份" + style="width: 240px" + filterable + allow-create + default-first-option + :reserve-keyword="false" + @change="handleChangeNum" + > + <el-option + v-for="item in data.yearList" + :key="item.value" + :label="item.label" + :value="item.label" + /> + </el-select> + </el-form-item> + <el-form-item > + <el-button type="primary" @click="getList">查询</el-button> + <el-button type="primary" plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true"> + <el-table-column label="序号" type="index" align="center" width="80"/> + <el-table-column label="文件名称" prop="fileNameSimple" align="center"> + </el-table-column> + <el-table-column label="文件" prop="templateName" align="center"> + <template #default="scope"> + <el-link style="" type="primary" @click="openFile(scope.row.filePath)">{{scope.row.fileName}}</el-link> + </template> + </el-table-column> + <el-table-column label="年度" prop="year" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="downloadFile(scope.row)">下载</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)">编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button> + </template> + </el-table-column> + </el-table> + + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + + <edit-dialog ref="dialogRef" @getList=getList></edit-dialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, onUnmounted, reactive, ref, toRefs} from "vue"; +import {ElMessage, ElMessageBox} from "element-plus"; +import {delCompany, getCompany} from "@/api/onlineEducation/company"; +import { Plus, Upload, Download} from '@element-plus/icons-vue'; +import {delUser, getUser} from "@/api/onlineEducation/user"; +import Cookies from "js-cookie"; +import editDialog from './components/editDialog.vue' +import { + delIndustryTemp, + getIndustryTemp, uploadTemplate, +} from "@/api/staffManage/staff"; +import useUserStore from "@/store/modules/user"; +import axios from "axios"; +import {getToken} from "@/utils/auth"; +import {getIndustry} from "@/api/system/industry"; +import {renderAsync} from "docx-preview"; +import {delSatisfied, getSatisfiedPage} from "@/api/supplier/satisaied"; +const userStore = useUserStore() +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const dialogRef = ref(); +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + year: '' + }, + total: 0, + dataList: [], + companyList: [], + industryList: [], + isAdmin: false, + typeList: [], + exportDialog: false, + yearList: [ + { + value: 1, + label: '2025' + }, + { + value: 2, + label: '2024' + }, + { + value: 3, + label: '2023' + }, + { + value: 4, + label: '2022' + }, + { + value: 5, + label: '2021' + }, + ], + +}); +const state = reactive({ + form: { + id: null, + filePath: '', + companyId: null + }, + exportFileList: [], +}) + +const { queryParams, total, dataList,companyList,industryList, isAdmin } = toRefs(data); +const userInfo = ref() +onMounted(async ()=>{ + if(userStore.roles.includes('admin')){ + data.isAdmin = true + data.queryParams.companyId = null + await getCompanyList() + }else{ + data.isAdmin = false + data.queryParams.companyId = userStore.companyId + } + await getList() +}) + +onUnmounted(()=>{ + +}) +const openFile = async(path)=>{ + const ext = path.split('.').pop().toLowerCase(); + if (ext === 'doc') { + ElMessageBox.confirm('暂不支持线上预览.doc文件,是否下载查看?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning' }).then(() => { + window.open(`${import.meta.env.VITE_APP_BASE_API}/${path}`, '_blank'); + }).catch(() => { + console.log('取消预览') + }); + return + } + try { + // 1. 获取文件 + const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/' + path); + const arrayBuffer = await response.arrayBuffer(); + // 2. 创建新窗口 + const win = window.open('', '_blank') + win.document.write(` + <!DOCTYPE html> + <html> + <head> + <title>预览</title> + <style> + body { margin: 20px; font-family: Arial; } + .docx-container { width: 100%; height: 100%; } + </style> + </head> + <body> + <div id="container" class="docx-container"></div> + </body> + </html> + `); + // 3. 渲染 DOCX + await renderAsync(arrayBuffer, win.document.getElementById('container')); + + } catch (error) { + console.error('预览失败:', error); + alert(`预览失败: ${error.message}`); + } +} +const getList = async () => { + loading.value = true + const res = await getSatisfiedPage(data.queryParams) + if(res.code == 200){ + data.dataList = res.data.list.map(item => { + return { + ...item, + fileNameSimple: item.fileName.split('.')[0] + } + }) + data.total = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false +} + + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const downloadFile = (e)=>{ + axios.get(import.meta.env.VITE_APP_BASE_API + '/' +e.filePath,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`},responseType: 'blob'}).then(res=>{ + if (res) { + const link = document.createElement('a') + let blob = new Blob([res.data],{type: res.data.type}) + link.style.display = "none"; + link.href = URL.createObjectURL(blob); // 创建URL + link.setAttribute("download", e.fileName); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } else { + ElMessage({ + type: 'warning', + message: '文件读取失败' + }); + } + }) +} + +const openDialog = (type, value) => { + dialogRef.value.openDialog(type, value, data.queryParams.companyId, data.isAdmin, data.companyList); +} + +const exportData = () => { + data.exportDialog = true + +} + + +/** 重置新增的表单以及其他数据 */ +const reset= async()=> { + if(data.isAdmin){ + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: null, + year: '' + } + await getCompanyList() + }else { + data.queryParams = { + pageNum: 1, + pageSize: 10, + companyId: data.queryParams.companyId, + year: '' + } + } + await getList() +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSatisfied( val.id) + if(res.code == 200){ + ElMessage.success('数据删除成功') + await getList() + }else{ + ElMessage.warning(res.message) + } + }) +} +const handleChangeNum = (value) => { + if (!/^\d+$/.test(value)) { // 验证是否为数字 + ElMessage.warning('只能输入数字') + data.queryParams.year = '' // 重置选择,避免非法值被添加到options中 + } else if (!data.yearList.some(option => option.label === value)) { // 确保不是已存在的选项 + data.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同) + } +} + + +</script> diff --git a/src/views/work/qualityInfo/supplierQuality/supplierList/components/supplierDialog.vue b/src/views/work/qualityInfo/supplierQuality/supplierList/components/supplierDialog.vue new file mode 100644 index 0000000..f74e352 --- /dev/null +++ b/src/views/work/qualityInfo/supplierQuality/supplierList/components/supplierDialog.vue @@ -0,0 +1,219 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="550px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin"> + <el-select v-model="state.form.companyId" filterable placeholder="请选择" clearable style="width: 100%" :disabled="title == '查看' || title == '编辑' || !state.isAdmin"> + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="供应商名称:" prop="supplierName" > + <el-input v-model="state.form.supplierName" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="供应商类型:" prop="supplierType" > + <el-input v-model="state.form.supplierType" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="联系人:" prop="user" > + <el-input v-model="state.form.user" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="联系电话:" prop="phone" > + <el-input v-model="state.form.phone" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="邮箱:" prop="emil" > + <el-input v-model="state.form.emil" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="主营产品:" prop="merito" > + <el-input v-model="state.form.merito" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="服务内容:" prop="content" > + <el-input v-model="state.form.content" :disabled="title === '查看'"/> + </el-form-item> + </el-form> + <template #footer v-if="title !== '查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {onMounted, reactive, ref, toRefs} from 'vue' +import Editor from "@/components/Editor/index.vue"; +import {ElMessage} from "element-plus"; +import {addNotice} from "@/api/backManage/notice"; +import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; +import {addCompany, checkName, distributeCompany, editCompany, getCompany} from "@/api/onlineEducation/company"; +import {validEmail, verifyPhone} from "@/utils/validate"; +import {addBasic, editBasic} from "@/api/companyInfo/basicInfo"; +import Cookies from "js-cookie"; +import {addSupplier, editSupplier} from "@/api/supplier/supplierList"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const emit = defineEmits(["getList"]); +const validatePhone = (rule, value, callback)=>{ + if(value === ''){ + callback(new Error('请输入手机号')) + }else{ + if(!verifyPhone(value)){ + callback(new Error('手机号格式有误')) + }else{ + callback() + } + } +} +const validateEmail = (rule, value, callback)=>{ + if(value === ''){ + callback(new Error('请输入邮箱')) + }else{ + if(!validEmail(value)){ + callback(new Error('邮箱格式有误')) + }else{ + callback() + } + } +} +const state = reactive({ + form: { + id: '', + companyId: null, + supplierName: '', + supplierType: '', + user: '', + phone: '', + emil: '', + merito: '', + content: '', + }, + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + supplierName: [{ required: true, message: '请输入供应商名称', trigger: 'blur' }], + supplierType:[{ required: true, message: '请输入供应商类型', trigger: 'blur' }], + user: [{ required: true, message: '请输入联系人', trigger: 'blur' }], + phone: [{ required: true, validator: validatePhone, trigger: 'blur' }], + emil: [{ required: true, validator: validateEmail, trigger: 'blur' }], + merito: [{ required: true, message: '请输入主营产品', trigger: 'blur' }], + content: [{ required: true, message: '请输入服务内容', trigger: 'blur' }], + }, + isAdmin: false, + companyList: [] +}) + +onMounted(() => { + +}) +const openDialog = async (type, value,companyList) => { + + + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.isAdmin = userInfo.userType === 0; + if(state.isAdmin){ + state.companyList = companyList + } + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.form = JSON.parse(JSON.stringify(value)); + if(state.isAdmin){ + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + } + dialogVisible.value = true; +} + +const onSubmit = async () => { + const valid = await busRef.value.validate(); + if(!state.isAdmin){ + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyId = userInfo.companyId + } + if(valid){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addSupplier(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editSupplier(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const reset = () => { + state.form = { + id: '', + companyId: null, + supplierName: '', + supplierType: '', + user: '', + phone: '', + emil: '', + merito: '', + content: '', + } + state.companyList = [] +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/qualityInfo/supplierQuality/supplierList/index.vue b/src/views/work/qualityInfo/supplierQuality/supplierList/index.vue new file mode 100644 index 0000000..f36fce3 --- /dev/null +++ b/src/views/work/qualityInfo/supplierQuality/supplierList/index.vue @@ -0,0 +1,201 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select v-model="data.queryParams.companyId" filterable placeholder="请选择" clearable> + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="供应商名称" prop="supplierName" align="center" /> + <el-table-column label="供应商类型" prop="supplierType" align="center" /> + <el-table-column label="联系人" prop="user" align="center" /> + <el-table-column label="联系电话" prop="phone" align="center" /> + <el-table-column label="邮箱" prop="emil" align="center" /> + <el-table-column label="主营产品" prop="merito" align="center" /> + <el-table-column label="服务内容" prop="content" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <supplierDialog ref="noticeRef" @getList = "getList"></supplierDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import supplierDialog from "./components/supplierDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; +import {delSupplier, getSupplierPage} from "@/api/supplier/supplierList"; + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + if(data.isAdmin){ + data.queryParams.companyId = null + }else { + data.queryParams.companyId = userInfo.companyId + } + getList(); + if(data.isAdmin){ + getCompanyList() + } +}); +const getList = async () => { + loading.value = true; + const res = await getSupplierPage(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value,data.companyList); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); + getCompanyList() +} + + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delSupplier(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/auditorManage/nameList/components/nameListDialog.vue b/src/views/work/selfProblems/internalAudit/auditorManage/nameList/components/nameListDialog.vue new file mode 100644 index 0000000..e43fcd2 --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/auditorManage/nameList/components/nameListDialog.vue @@ -0,0 +1,198 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="550px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin"> + <el-select + v-model="state.form.companyId" + filterable + clearable + style="width: 100%" + :disabled="state.title == '查看' || state.title == '编辑' || !state.isAdmin" + @change="selectValueCom" + > + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="人员选择:" prop="personId"> + <el-select + clearable + v-model="state.form.personId" + :disabled="state.title =='查看'" + filterable + style="width: 100%" + > + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item label="专长领域:" prop="speciality"> + <el-input v-model.trim="state.form.speciality" :disabled="state.title =='查看'" placeholder="专长领域"></el-input> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {updateInfoPlatforms, updateSysClause} from "@/api/staffManage/staff"; +import Cookies from "js-cookie"; +import {addPerson, editPerson} from "@/api/selfProblems/nameList"; +import {addScenario, editScenario} from "@/api/selfProblems/scenario"; +import {getStudent} from "@/api/onlineEducation/student"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const state = reactive({ + title: '', + form: { + id: null, + personId: null, + companyId: null, + speciality: '' + }, + isAdmin: false, + peopleList: [], + formRules:{ + personId: [{ required: true, message: '请选择人员', trigger: 'blur' }], + companyId: [{ required: true, message: '请选择公司', trigger: 'blur' }], + speciality: [{ required: true, message: '请输入专长领域', trigger: 'blur' }], + } +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyList) => { + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.isAdmin = userInfo.userType === 0; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + if(state.isAdmin){ + state.companyList = companyList + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + } + await getPeopleList() + dialogVisible.value = true +} + +const getPeopleList = async ()=> { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const queryParams = { + pageNum: 1, + pageSize: 9999, + companyId: state.form.companyId + } + const res = await getStudent(queryParams) + if(res.code == 200){ + state.peopleList = res.data.list?res.data.list:[] + }else{ + ElMessage.warning(res.message) + } +}; +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid) { + if (state.title === '新增') { + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addPerson(data) + if (res.code === 200) { + ElMessage({ + type: 'success', + message: '新增成功' + }); + } else { + ElMessage.warning(res.message) + } + emit("getList") + handleClose() + } else if (state.title === '编辑') { + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editPerson(data) + if (res.code === 200) { + ElMessage({ + type: 'success', + message: '编辑成功' + }); + } else { + ElMessage.warning(res.message) + } + emit("getList") + handleClose() + } + } +} +const selectValueCom = (val) => { + state.form.personId = null + getPeopleList() +} + +const handleClose = () => { + state.form = { + id: null, + personId: null, + companyId: null, + speciality: '' + } + state.peopleList = [] + superRef.value.clearValidate(); + dialogVisible.value = false; + +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/auditorManage/nameList/index.vue b/src/views/work/selfProblems/internalAudit/auditorManage/nameList/index.vue new file mode 100644 index 0000000..39be324 --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/auditorManage/nameList/index.vue @@ -0,0 +1,215 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select v-model="data.queryParams.companyId" filterable placeholder="请选择" clearable> + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="姓名" prop="personName" align="center" /> + <el-table-column label="所属部门" prop="deptName" align="center" /> + <el-table-column label="职务" prop="duty" align="center" /> + <el-table-column label="专长领域" prop="speciality" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <nameDialog ref="noticeRef" @getList = "getList"></nameDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import nameDialog from "./components/nameListDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; +import {delPerson, getPersonPage} from "@/api/selfProblems/nameList"; + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + if(data.isAdmin){ + data.queryParams.companyId = null + getCompanyList() + }else { + data.queryParams.companyId = userInfo.companyId + } + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getPersonPage(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value,data.companyList); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); + getCompanyList() +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = '/infoExample.docx' +const startGeneration = async () => { + choosedData.value.forEach(item => { + try { + generateWordDocument(templatePath, item, item.companyName+'_基本情况.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }) +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delPerson(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/auditorManage/tableList/components/editDialog.vue b/src/views/work/selfProblems/internalAudit/auditorManage/tableList/components/editDialog.vue new file mode 100644 index 0000000..4939c0e --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/auditorManage/tableList/components/editDialog.vue @@ -0,0 +1,253 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="state.title" + width="550px" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="superRef" :rules="state.formRules" label-width="150px" > + <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin"> + <el-select + v-model="state.form.companyId" + filterable + clearable + style="width: 100%" + :disabled="state.title == '查看' || state.title == '编辑' || !state.isAdmin" + @change="selectValueCom" + > + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="人员选择:" prop="personId"> + <el-select + clearable + v-model="state.form.personId" + :disabled="state.title =='查看'" + filterable + style="width: 100%" + @change="changePerson" + > + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + <el-form-item label="内审员证书:" prop="certifity"> + <el-select + clearable + v-model="state.form.certifity" + :disabled="state.title =='查看'" + filterable + style="width: 100%" + > + <el-option + v-for="item in state.certList" + :key="item.number" + :label="item.certName" + :value="item.number" + /> + </el-select> + </el-form-item> + <el-form-item label="审核经历次数:" prop="amount"> + <el-input v-model.trim="state.form.amount" :disabled="state.title =='查看'" placeholder="核经历次数"></el-input> + </el-form-item> + <el-form-item label="评定结论:" prop="conclusion"> + <el-input v-model.trim="state.form.conclusion" :disabled="state.title =='查看'" type="textarea" :rows="2" placeholder="评定结论"></el-input> + </el-form-item> + </el-form> + <template #footer v-if="state.title !='查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {reactive, ref, toRefs, defineEmits, nextTick, onMounted} from 'vue' +import {ElMessage} from "element-plus"; +import {addUser, editUser, getUser, getUserById, resetPwd} from "@/api/onlineEducation/user" +import {Base64} from "js-base64" +import {getCompany} from "@/api/onlineEducation/company"; +import {updateInfoPlatforms, updateSysClause} from "@/api/staffManage/staff"; +import Cookies from "js-cookie"; +import {addScenario, editScenario} from "@/api/selfProblems/scenario"; +import {addEvaluate, editEvaluate} from "@/api/selfProblems/tableList"; +import {getStudent, getStuTrainRecord} from "@/api/onlineEducation/student"; + +const emit = defineEmits(["getList"]); +const dialogVisible = ref(false) +const superRef = ref() +const state = reactive({ + title: '', + form: { + id: null, + personId: null, + companyId: null, + certifity: '', + amount: '', + conclusion: '' + + }, + isAdmin: false, + peopleList: [], + certList: [], + formRules:{ + companyId: [{ required: true, message: '请选择公司', trigger: 'blur' }], + personId: [{ required: true, message: '请选择人员', trigger: 'blur' }], + } +}) +onMounted(() => { + +}); + +const openDialog = async (type, value,companyList) => { + state.title = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.isAdmin = userInfo.userType === 0; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + if(state.isAdmin){ + state.companyList = companyList + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + if(state.title == '编辑'||state.title == '查看'){ + Object.keys(state.form).forEach(key => { + if (key in value) { + state.form[key] = value[key] + } + }) + } + await getPeopleList() + await getCertList() + dialogVisible.value = true +} + +const getPeopleList = async ()=> { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const queryParams = { + pageNum: 1, + pageSize: 9999, + companyId: state.form.companyId + } + const res = await getStudent(queryParams) + if(res.code == 200){ + state.peopleList = res.data.list?res.data.list:[] + }else{ + ElMessage.warning(res.message) + } +}; +const getCertList = async ()=> { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const param = { + studentId: state.form.personId + } + const res = await getStuTrainRecord(param) + if(res.code == 200){ + const data = res.data.filter(i => i.passed == 1) + state.certList = data.map(item => { + return{ + ...item, + certName: item.name + '合格证书' + } + }) + + }else{ + ElMessage.warning(res.message) + } +}; +const onSubmit = async () => { + const valid = await superRef.value.validate(); + if(valid){ + if(state.title === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addEvaluate(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + handleClose() + }else if(state.title === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editEvaluate(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + handleClose() + } + + } +} +const selectValueCom = (val) => { + state.form.personId = null + state.form.certifity = '' + getPeopleList() +} + +const handleClose = () => { + state.form = { + id: null, + personId: null, + companyId: null, + certifity: '', + amount: '', + conclusion: '' + } + state.certList = [] + state.companyList = [] + state.peopleList = [] + superRef.value.clearValidate(); + superRef.value.resetFields() + dialogVisible.value = false; +} +const changePerson = () =>{ + state.form.certifity = '' + getCertList() +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/internalAudit/auditorManage/tableList/index.vue b/src/views/work/selfProblems/internalAudit/auditorManage/tableList/index.vue new file mode 100644 index 0000000..f424f8e --- /dev/null +++ b/src/views/work/selfProblems/internalAudit/auditorManage/tableList/index.vue @@ -0,0 +1,228 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item> + <el-button + v-if="data.userType ==0 || data.userType == 1" + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select v-model="data.queryParams.companyId" filterable placeholder="请选择" clearable> + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column label="姓名" prop="personName" align="center" /> + <el-table-column label="所属部门" prop="deptName" align="center" /> + <el-table-column label="内审员证书" prop="certifity" align="center" > + <template #default="scope"> + <el-button v-if="scope.row.certifity" type="primary" @click="downloadCert(scope.row)" link>证书</el-button> + </template> + </el-table-column> + <el-table-column label="审核经历次数" prop="amount" align="center" /> + <el-table-column label="评定结论" prop="conclusion" align="center" /> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <editDialog ref="noticeRef" @getList = "getList"></editDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import editDialog from "./components/editDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; +import {delEvaluate, getEvaluatePage} from "@/api/selfProblems/tableList"; +import Default from "@tinymce/tinymce-vue"; +import {useRouter} from "vue-router"; +const router = useRouter(); + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false, + userType: null +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + data.userType = userInfo.userType + if(data.isAdmin){ + data.queryParams.companyId = null + getCompanyList() + }else { + data.queryParams.companyId = userInfo.companyId + } + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getEvaluatePage(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value,data.companyList); +} +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); + getCompanyList() +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = '/infoExample.docx' +const startGeneration = async () => { + choosedData.value.forEach(item => { + try { + generateWordDocument(templatePath, item, item.companyName+'_基本情况.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }) +} +const downloadCert = (info) => { + info.type = 'inter' + const routePath = '/certPdf' + const resolvedRoute = router.resolve(routePath) + const queryString = new URLSearchParams(info).toString() + const fullPath = `${resolvedRoute.href}?${queryString}` + window.open(fullPath, '_blank') + +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delEvaluate(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/work/selfProblems/plan/components/planDialog.vue b/src/views/work/selfProblems/plan/components/planDialog.vue new file mode 100644 index 0000000..fcbcb34 --- /dev/null +++ b/src/views/work/selfProblems/plan/components/planDialog.vue @@ -0,0 +1,561 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="50%" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-width="100px" > + <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin"> + <el-select + v-model="state.form.companyId" + filterable + clearable + style="width: 100%" + :disabled="title == '查看' || title == '编辑' || !state.isAdmin" + @change="selectValueCom" + > + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year" > + <el-select + :disabled="title === '查看'" + v-model="state.form.year" + filterable + allow-create + default-first-option + :reserve-keyword="false" + @change="handleChangeNum" + style="width: 100%" + > + <el-option + v-for="item in state.yearList" + :key="item.value" + :label="item.label" + :value="item.label" + /> + </el-select> + </el-form-item> + <el-form-item label="审核目的:" prop="auditPurpose" > + <el-input v-model="state.form.auditPurpose" :rows="2" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="审核依据:" prop="reviewBasis" > + <el-input v-model="state.form.reviewBasis" :rows="2" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="审核范围:" prop="reviewScope" > + <el-input v-model="state.form.reviewScope" :rows="2" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="审核日期:" prop="reviewStart" > + <el-date-picker + :disabled="title === '查看'" + v-model="checkTime" + type="daterange" + range-separator="至" + start-placeholder="开始日期" + end-placeholder="结束日期" + format="YYYY-MM-DD" + /> + </el-form-item> + <el-form-item label="审核组长/审核员:" prop="reviewPerson" > + <el-input v-model="state.form.reviewPerson" :rows="2" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="审核起止时间:" prop="firstStarttime" > + <div style="display: flex;flex-direction: column"> + <el-date-picker + :disabled="title === '查看'" + v-model="checkStartTime" + type="datetimerange" + range-separator="至" + start-placeholder="首次会议开始时间" + end-placeholder="首次会议结束时间" + format="YYYY-MM-DD HH:mm:ss" + style="width: 100%" + /> + <el-date-picker + :disabled="title === '查看'" + style="margin-top: 10px;width: 100%" + v-model="checkEndTime" + type="datetimerange" + range-separator="至" + start-placeholder="末次会议开始时间" + end-placeholder="末次会议结束时间" + format="YYYY-MM-DD HH:mm:ss" + /> + </div> + </el-form-item> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item > + <el-button + :disabled="title === '查看'" + type="primary" + @click="addTable" + >新增</el-button> + <el-table style="margin-top: 10px;margin-bottom: 20px" :data="state.form.deptList" :border="true"> + <el-table-column label="日期" prop="date" align="center"> + <template #default="{row,$index}"> + <el-form-item :prop="'deptList.' + '[' + $index + ']' + '.date'" :rules="state.rules.date"> + <el-input :disabled="title === '查看'" type="textarea" v-model="row.date" placeholder="请输入"></el-input> + </el-form-item> + </template> + </el-table-column> + <el-table-column label="时间" prop="time" align="center"> + <template #default="{row,$index}"> + <el-form-item :prop="'deptList.' + '[' + $index + ']' + '.time'" :rules="state.rules.time"> + <el-input :disabled="title === '查看'" type="textarea" v-model="row.time" placeholder="请输入"></el-input> + </el-form-item> + </template> + </el-table-column> + <el-table-column label="受审核部门" prop="deptId" align="center"> + <template #default="{row,$index}"> + <el-form-item :prop="'deptList.' + '[' + $index + ']' + '.deptId'" :rules="state.rules.deptId"> + <el-select + :disabled="title === '查看'" + v-model="row.deptId" + placeholder="请选择部门" + style="width: 240px" + @change="changeDept(row)" + > + <el-option + v-for="item in state.deptList" + :key="item.deptId" + :label="item.deptName" + :value="item.deptId" + /> + </el-select> + </el-form-item> + </template> + </el-table-column> + <el-table-column label="事项/要素" prop="dept" align="center"> + <template #default="{row,$index}"> + <span>{{row.termNum}}</span> + </template> + </el-table-column> + <el-table-column label="审核员" prop="dept" align="center"> + <template #default="{row,$index}"> + <el-form-item :prop="'deptList.' + '[' + $index + ']' + '.checkId'" :rules="state.rules.checkId"> + <el-select clearable v-model="row.checkId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </template> + </el-table-column> + <el-table-column label="操作" align="center" width="120" v-if="title !== '查看'" > + <template #default="scope"> + <el-button link type="danger" @click="delTable(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="编制:" prop="compilationId" > + <el-select clearable v-model="state.form.compilationId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="校对:" prop="proofreadId" > + <el-select clearable v-model="state.form.proofreadId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="审核:" prop="checkId" > + <el-select clearable v-model="state.form.checkId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="批准:" prop="ratifyId" > + <el-select clearable v-model="state.form.ratifyId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer v-if="title !== '查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {nextTick, onMounted, reactive, ref, toRefs} from 'vue' +import Editor from "@/components/Editor/index.vue"; +import {ElMessage} from "element-plus"; +import {addNotice} from "@/api/backManage/notice"; +import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; +import {addCompany, checkName, distributeCompany, editCompany, getCompany} from "@/api/onlineEducation/company"; +import {verifyPhone} from "@/utils/validate"; +import {addBasic, editBasic} from "@/api/companyInfo/basicInfo"; +import Cookies from "js-cookie"; +import {getUser} from "@/api/onlineEducation/user"; +import {getDept} from "@/api/qualityObjectives/object"; +import {addPlan, editPlan} from "@/api/selfProblems/plan"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const length = ref() +const checkTime = ref([]) +const checkStartTime = ref([]) +const checkEndTime = ref([]) +const emit = defineEmits(["getList"]); +const validateFieldsReview = (rule, value, callback) =>{ + if (checkTime.value && checkTime.value.length >0 ) { + callback(); + } else { + callback(new Error('请选择时间')); + } +} +const validateFields = (rule, value, callback) =>{ + if (checkStartTime.value && checkStartTime.value.length >0 && checkEndTime.value && checkEndTime.value.length >0 ) { + callback(); + } else { + callback(new Error('请选择时间')); + } +} +const state = reactive({ + form: { + id: '', + companyId: null, + year: "", //年份 + auditPurpose: "", //审核目的 + reviewBasis: "", //审核依据 + reviewScope: "", //审核范围 + reviewStart: "", + reviewEnd: "", //审核时间 + reviewPerson: "", //审核组 + firstStarttime: "", //首次审核开始时间 + firstEndtime: "", //首次审核结束时间 + lastStarttime: "", //末次审核开始时间 + lastEndtime: "", //末次审核结束时间 + compilationId: null, //编制人id + proofreadId: null, //校对人id + checkId: null, //审核人id + ratifyId: null, //批准人id + deptList: [] + }, + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + year: [{ required: true, message: '请输入年份', trigger: 'blur' }], + auditPurpose: [{ required: true, message: '请输入审核目的', trigger: 'blur' }], //审核目的 + reviewBasis: [{ required: true, message: '请输入审核依据', trigger: 'blur' }],//审核依据 + reviewScope:[{ required: true, message: '请输入审核范围', trigger: 'blur' }], //审核范围 + reviewStart: [{ required: true,validator: validateFieldsReview, trigger: 'blur' }],//审核时间 + reviewPerson:[{ required: true, message: '请输入审核组长/审核员', trigger: 'blur' }], //审核组 + firstStarttime:[{ required: true, validator: validateFields,trigger: 'blur' }], + checkEndTime:[{ required: true, message: '请选择末次会议时间', trigger: 'blur' }], + compilationId: [{ required: true, message: '请选择编制人', trigger: 'blur' }], //编制人id + proofreadId: [{ required: true, message: '请选择校对人', trigger: 'blur' }], //校对人id + checkId: [{ required: true, message: '请选择审核人', trigger: 'blur' }], //审核人id + ratifyId: [{ required: true, message: '请选择批准人', trigger: 'blur' }], //批准人id + }, + rules: { + date: [{required: true, message: "", trigger: "blur"}], + time: [{required: true, message: "", trigger: "blur"}], + deptId: [{required: true, message: "", trigger: "blur"}], + checkId: [{required: true, message: "", trigger: "blur"}], + + }, + isAdmin: false, + companyList: [], + yearList: [ + { + value: 1, + label: '2025' + }, + { + value: 2, + label: '2024' + }, + { + value: 3, + label: '2023' + }, + { + value: 4, + label: '2022' + }, + { + value: 5, + label: '2021' + }, + ], + peopleList: [], + deptList: [], +}) + +onMounted(() => { + +}) +const openDialog = async (type, value,companyList) => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.isAdmin = userInfo.userType === 0; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + if(state.isAdmin){ + state.companyList = companyList + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + await getDeptList() + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.form = JSON.parse(JSON.stringify(value)); + checkTime.value = [state.form.reviewStart,state.form.reviewEnd] + checkStartTime.value = [state.form.firstStarttime,state.form.firstEndtime] + checkEndTime.value = [state.form.lastStarttime,state.form.lastEndtime] + await nextTick(()=> { + state.form.deptList.forEach(item => { + state.deptList.forEach(i => { + if(i.deptId == item.deptId){ + item.termNum = sortVersionNumbers(i.caluseVO1List?.map(x=>x.clauseNum)).join('、') + } + }) + }) + }) + } + await getPeopleList() + + dialogVisible.value = true; +} +const getPeopleList = async ()=> { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const queryParams = { + pageNum: 1, + pageSize: 9999, + companyId: state.form.companyId + } + const res = await getUser(queryParams) + if(res.code == 200){ + state.peopleList = res.data.list?res.data.list:[] + }else{ + ElMessage.warning(res.message) + } +}; + +const onSubmit = async () => { + state.form.reviewStart = checkTime.value[0] + state.form.reviewEnd = checkTime.value[0] + state.form.firstStarttime = checkStartTime.value[0] + state.form.firstEndtime = checkStartTime.value[1] + state.form.lastStarttime = checkEndTime.value[0] + state.form.lastEndtime = checkEndTime.value[1] + + const valid = await busRef.value.validate(); + if(!state.isAdmin){ + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyId = userInfo.companyId + } + if(state.form.deptList && state.form.deptList.length ==0){ + ElMessage.warning('请添加受审部门信息') + return + } + + console.log('111',state.form) + if(valid){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addPlan(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editPlan(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} +const delTable = (val) => { + state.form.deptList = state.form.deptList.filter(item=> item.deptId != val.deptId) +} +const handleClose = () => { + busRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const changeDept = (val) => { + let termNum = '' + state.deptList.forEach(item => { + if(item.deptId == val.deptId){ + termNum = sortVersionNumbers(item.caluseVO1List?.map(i=>i.clauseNum)).join('、') + } + }) + state.form.deptList.forEach(item => { + if(item.deptId == val.deptId){ + item.termNum = termNum + } + }) + +} +const sortVersionNumbers = (versions) => { + return versions.sort((a, b) => { + const partsA = a.split('.').map(Number); + const partsB = b.split('.').map(Number); + const maxLength = Math.max(partsA.length, partsB.length) + for (let i = 0; i < maxLength; i++) { + const numA = partsA[i] || 0 + const numB = partsB[i] || 0 + + if (numA !== numB) { + return numA - numB + } + } + return 0 + }); +} +const addTable = () => { + state.form.deptList.push({}) +} +const handleChangeNum = (value) => { + if (!/^\d+$/.test(value)) { // 验证是否为数字 + ElMessage.warning('只能输入数字') + state.form.year = '' // 重置选择,避免非法值被添加到options中 + } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项 + state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同) + } +} +const getDeptList = async () => { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const param = { + pageNum: 1, + pageSize: 999, + companyId: state.form.companyId + } + const res = await getDept(param) + if(res.code === 200){ + state.deptList = res.data + } +} +const selectValueCom = (val) => { + state.form.compilationId= null + state.form.proofreadId = null + state.form.checkId = null + state.form.ratifyId = null + getPeopleList() + getDeptList() +} +const reset = () => { + state.form = { + id: '', + companyId: null, + year: "", //年份 + auditPurpose: "", //审核目的 + reviewBasis: "", //审核依据 + reviewScope: "", //审核范围 + reviewStart: "", + reviewEnd: "", //审核时间 + reviewPerson: "", //审核组 + firstStarttime: "", //首次审核开始时间 + firstEndtime: "", //首次审核结束时间 + lastStarttime: "", //末次审核开始时间 + lastEndtime: "", //末次审核结束时间 + compilationId: null, //编制人id + proofreadId: null, //校对人id + checkId: null, //审核人id + ratifyId: null, //批准人id + deptList: [] + + } + state.companyList = [] + state.peopleList = [] + checkTime.value = [] + checkStartTime.value = [] + checkEndTime.value = [] +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/plan/index.vue b/src/views/work/selfProblems/plan/index.vue new file mode 100644 index 0000000..effd72a --- /dev/null +++ b/src/views/work/selfProblems/plan/index.vue @@ -0,0 +1,265 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select v-model="data.queryParams.companyId" filterable placeholder="请选择" clearable> + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + <el-form-item style="margin-left: 15px"> + <el-button + type="primary" + @click="exportData" + >导出</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" /> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column v-if="data.isAdmin" label="公司名称" prop="companyName" align="center" /> + <el-table-column label="计划名称" align="center"> + <template #default="scope"> + <span>{{scope.row.year}}年内审实施计划</span> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <planDialog ref="noticeRef" @getList = "getList"></planDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, nextTick, onMounted, reactive, ref, toRefs} from "vue"; +import planDialog from "./components/planDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; +import {delPlan, getPlanPage} from "@/api/selfProblems/plan"; +import {getDept} from "@/api/qualityObjectives/object"; + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false, + deptList: [] +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + if(data.isAdmin){ + data.queryParams.companyId = null + getCompanyList() + }else { + data.queryParams.companyId = userInfo.companyId + } + getList(); + getDeptList() +}); +const getList = async () => { + loading.value = true; + const res = await getPlanPage(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value,data.companyList); +} +const selectValue = (val) => { + data.companyList.forEach(item => { + if(item.name === val){ + data.queryParams.companyId = item.id + } + }) +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + // data.queryParams.companyId = data.companyList[0].id + } else { + ElMessage.warning(res.message) + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); + getCompanyList() +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = '/planExample.docx' +const startGeneration = async () => { + for (const item of choosedData.value) { + await nextTick(()=> { + item.deptList.forEach(de => { + data.deptList.forEach(d=> { + if(de.deptId == d.deptId){ + de.term = sortVersionNumbers(d.caluseVO1List?.map(x=>x.clauseNum)).join('、') + } + }) + }) + }) + console.log('x',item.deptList) + item.reviewStart = item.reviewStart.substring(0,10) + item.reviewEnd = item.reviewEnd.substring(0,10) + try { + generateWordDocument(templatePath, item, item.companyName+'_' +item.year +'内审实施计划.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + } +} +const sortVersionNumbers = (versions) => { + return versions.sort((a, b) => { + const partsA = a.split('.').map(Number); + const partsB = b.split('.').map(Number); + const maxLength = Math.max(partsA.length, partsB.length) + for (let i = 0; i < maxLength; i++) { + const numA = partsA[i] || 0 + const numB = partsB[i] || 0 + + if (numA !== numB) { + return numA - numB + } + } + return 0 + }); +} +const getDeptList= async () => { + const param = { + companyId: data.queryParams.companyId, + } + const res = await getDept(param) + if(res.code === 200){ + data.deptList = res.data + } +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delPlan(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> diff --git a/src/views/work/selfProblems/scenario/components/scenarioDialog.vue b/src/views/work/selfProblems/scenario/components/scenarioDialog.vue new file mode 100644 index 0000000..8685cb8 --- /dev/null +++ b/src/views/work/selfProblems/scenario/components/scenarioDialog.vue @@ -0,0 +1,364 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="50%" + :before-close="handleClose" + :close-on-press-escape="false" + :close-on-click-modal="false" + > + <el-form :model="state.form" size="default" ref="busRef" :rules="state.formRules" label-position="top" label-width="150px" > + <el-form-item label="企业名称:" prop="companyId" v-if="state.isAdmin"> + <el-select + v-model="state.form.companyId" + filterable + clearable + style="width: 100%" + :disabled="title == '查看' || title == '编辑' || !state.isAdmin" + @change="selectValueCom" + > + <el-option + v-for="item in state.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item label="年份:" prop="year" > + <el-select + :disabled="title === '查看'" + v-model="state.form.year" + filterable + allow-create + default-first-option + :reserve-keyword="false" + @change="handleChangeNum" + style="width: 100%" + > + <el-option + v-for="item in state.yearList" + :key="item.value" + :label="item.label" + :value="item.label" + /> + </el-select> + </el-form-item> + <el-form-item label="1.目的" prop="purpose" > + <el-input v-model="state.form.purpose" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="2.内审目的" prop="auditPurpose" > + <el-input v-model="state.form.auditPurpose" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="3.审核范围" prop="reviewScope" > + <el-input v-model="state.form.reviewScope" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="4.审核依据" prop="reviewBasis" > + <el-input v-model="state.form.reviewBasis" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="5.审核实施" prop="reviewCarry" > + <el-input v-model="state.form.reviewCarry" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="6.审核组构成" prop="reviewConstitute" > + <el-input v-model="state.form.reviewConstitute" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + <el-form-item label="7.要求" prop="reviewRequire" > + <el-input v-model="state.form.reviewRequire" :rows="4" type="textarea" :disabled="title === '查看'"/> + </el-form-item> + </el-form> + <el-form :model="state.form" size="default" ref="peoRef" :rules="state.peoRules" label-width="60px"> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="编制:" prop="compilationId" > + <el-select clearable v-model="state.form.compilationId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="校对:" prop="proofreadId" > + <el-select clearable v-model="state.form.proofreadId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="审核:" prop="checkId" > + <el-select clearable v-model="state.form.checkId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="批准:" prop="ratifyId" > + <el-select clearable v-model="state.form.ratifyId" :disabled="title =='查看'" filterable style="width: 240px"> + <el-option + v-for="item in state.peopleList" + :key="item.id" + :label="item.name" + :value="item.id" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer v-if="title !== '查看'"> + <span class="dialog-footer"> + <el-button @click="handleClose" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + </div> +</template> +<script setup> +import {onMounted, reactive, ref, toRefs} from 'vue' +import Editor from "@/components/Editor/index.vue"; +import {ElMessage} from "element-plus"; +import {addNotice} from "@/api/backManage/notice"; +import {addDict, editDict, getDictDetail} from "@/api/backManage/evaluate"; +import {addCompany, checkName, distributeCompany, editCompany, getCompany} from "@/api/onlineEducation/company"; +import {verifyPhone} from "@/utils/validate"; +import {addBasic, editBasic} from "@/api/companyInfo/basicInfo"; +import Cookies from "js-cookie"; +import {getUser} from "@/api/onlineEducation/user"; +import {addScenario, editScenario} from "@/api/selfProblems/scenario"; + +const dialogVisible = ref(false); +const title = ref(""); +const busRef = ref(); +const peoRef = ref() +const length = ref() +const emit = defineEmits(["getList"]); +const state = reactive({ + form: { + id: '', + companyId: null, + year: "", + purpose: "", + auditPurpose: "", + reviewBasis: "", + reviewScope: "", + reviewCarry: "", + reviewConstitute: "", + reviewRequire: "", + compilationId: null, + proofreadId: null, + checkId: null, + ratifyId: null + }, + formRules:{ + companyId: [{ required: true, message: '请选择企业', trigger: 'blur' }], + year: [{ required: true, message: '请选择年份', trigger: 'blur' }], + purpose:[{ required: true, message: '请输入目的', trigger: 'blur' }], + auditPurpose: [{ required: true, message: '请输入审核目的', trigger: 'blur' }], + reviewBasis: [{ required: true, message: '请输入审核依据', trigger: 'blur' }], + reviewScope: [{ required: true, message: '请输入审核范围', trigger: 'blur' }], + reviewCarry: [{ required: true, message: '请输入审核实施', trigger: 'blur' }], + reviewConstitute: [{ required: true, message: '请输入审核组构成', trigger: 'blur' }], + reviewRequire: [{ required: true, message: '请输入要求', trigger: 'blur' }], + + }, + peoRules: { + compilationId: [{ required: true, message: '请选择编制人', trigger: 'blur' }], + proofreadId: [{ required: true, message: '请选择校对人', trigger: 'blur' }], + checkId: [{ required: true, message: '请选择审核人', trigger: 'blur' }], + ratifyId: [{ required: true, message: '请选择批准人', trigger: 'blur' }], + }, + isAdmin: false, + companyList: [], + yearList: [ + { + value: 1, + label: '2025' + }, + { + value: 2, + label: '2024' + }, + { + value: 3, + label: '2023' + }, + { + value: 4, + label: '2022' + }, + { + value: 5, + label: '2021' + }, + ], + peopleList: [], +}) + +onMounted(() => { + +}) +const openDialog = async (type, value,companyList) => { + + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.isAdmin = userInfo.userType === 0; + state.form.companyName = userInfo.companyName + state.form.companyId = userInfo.companyId + if(state.isAdmin){ + state.companyList = companyList + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + title.value = type === 'add' ? '新增' : type ==='edit' ? '编辑' : '查看' ; + if(type === 'edit' || type === 'review') { + state.form = JSON.parse(JSON.stringify(value)); + if(state.isAdmin){ + state.form.companyId = value.companyId + state.form.companyName = value.companyName + } + } + await getPeopleList() + dialogVisible.value = true; +} +const getPeopleList = async ()=> { + if(state.isAdmin && !state.form.companyId && (state.form.companyId == 0 || state.form.companyId == null)){ + return + } + const queryParams = { + pageNum: 1, + pageSize: 9999, + companyId: state.form.companyId + } + const res = await getUser(queryParams) + if(res.code == 200){ + state.peopleList = res.data.list?res.data.list:[] + }else{ + ElMessage.warning(res.message) + } +}; + +const onSubmit = async () => { + const valid = await busRef.value.validate(); + const validPro = await peoRef.value.validate(); + if(!state.isAdmin){ + const userInfo = JSON.parse(Cookies.get('userInfo')) + state.form.companyId = userInfo.companyId + } + if(valid && validPro){ + if(title.value === '新增'){ + const {id, ...data} = JSON.parse(JSON.stringify(state.form)) + const res = await addScenario(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '新增成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + peoRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + }else if(title.value === '编辑'){ + const {...data} = JSON.parse(JSON.stringify(state.form)) + const res = await editScenario(data) + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '编辑成功' + }); + }else{ + ElMessage.warning(res.message) + } + emit("getList") + busRef.value.clearValidate(); + peoRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + } + } +} + +const handleClose = () => { + busRef.value.clearValidate(); + peoRef.value.clearValidate(); + reset(); + dialogVisible.value = false; + emit("getList") + +} +const handleChangeNum = (value) => { + if (!/^\d+$/.test(value)) { // 验证是否为数字 + ElMessage.warning('只能输入数字') + state.form.year = '' // 重置选择,避免非法值被添加到options中 + } else if (!state.yearList.some(option => option.label === value)) { // 确保不是已存在的选项 + state.yearList.push({ value, label: value }); // 添加新选项(这里简单地将值和标签设为相同) + } +} +const selectValueCom = (val) => { + state.form.compilationId = null + state.form.proofreadId = null + state.form.checkId = null + state.form.ratifyId = null + getPeopleList() +} +const reset = () => { + state.form = { + id: '', + companyId: null, + year: "", + purpose: "", + auditPurpose: "", + reviewBasis: "", + reviewScope: "", + reviewCarry: "", + reviewConstitute: "", + reviewRequire: "", + compilationId: null, + proofreadId: null, + checkId: null, + ratifyId: null + } + state.companyList = [] + state.peopleList = [] +} +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/work/selfProblems/scenario/index.vue b/src/views/work/selfProblems/scenario/index.vue new file mode 100644 index 0000000..6a4dfe2 --- /dev/null +++ b/src/views/work/selfProblems/scenario/index.vue @@ -0,0 +1,222 @@ +<template> + <div class="app-container"> + <div style="margin-bottom: 10px"> + <el-form style="display: flex;flex-wrap: wrap;"> + <el-form-item> + <el-button + type="primary" + plain + icon="Plus" + @click="openDialog('add',{})" + >新增</el-button> + </el-form-item> + <el-form-item label="企业名称:" v-if="data.isAdmin" style="margin-left: 20px"> + <el-select v-model="data.queryParams.companyId" filterable placeholder="请选择" clearable> + <el-option + v-for="item in data.companyList" + :key="item.id" + :label="item.name" + :value="item.id"> + </el-option> + </el-select> + </el-form-item> + <el-form-item v-if="data.isAdmin"> + <el-button type="primary" style="margin-left: 30px" @click="searchClick">查询</el-button> + <el-button plain @click="reset">重置</el-button> + </el-form-item> + + + <el-form-item style="margin-left: 15px"> + <el-button + type="primary" + @click="exportData" + >导出</el-button> + </el-form-item> + + </el-form> + </div> + <!-- 表格数据 --> + <el-table v-loading="loading" :data="dataList" :border="true" @selection-change="handleSelectionChange"> + <el-table-column type="selection" width="55" /> + <el-table-column type="index" label="序号" width="80" align="center"></el-table-column> + <el-table-column v-if="data.isAdmin" label="企业名称" prop="companyName" align="center"> + </el-table-column> + <el-table-column label="方案名称" align="center"> + <template #default="scope"> + <span>{{scope.row.year}}年度内部审核策划方案</span> + </template> + </el-table-column> + <el-table-column label="操作" align="center" class-name="small-padding fixed-width" > + <template #default="scope"> + <el-button link type="primary" @click="openDialog('review',scope.row)" >查看</el-button> + <el-button link type="primary" @click="openDialog('edit',scope.row)" >编辑</el-button> + <el-button link type="danger" @click="handleDelete(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + + <div class="pag-container"> + <el-pagination + v-model:current-page="data.queryParams.pageNum" + v-model:page-size="data.queryParams.pageSize" + :page-sizes="[10,15,20,25]" + layout="total, sizes, prev, pager, next, jumper" + :total="total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <scenarioDialog ref="noticeRef" @getList = "getList"></scenarioDialog> + </div> +</template> + +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs} from "vue"; +import scenarioDialog from "./components/scenarioDialog.vue" +import {ElMessage, ElMessageBox} from "element-plus"; +import {getCompany} from "@/api/onlineEducation/company"; +import Cookies from "js-cookie"; +import {generateWordDocument} from "@/utils/exportWord"; +import {delBasic, getBasic} from "@/api/companyInfo/basicInfo"; +import {delScenario, getScenarioPage} from "@/api/selfProblems/scenario"; + +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const noticeRef = ref(); +const loadingCompany = ref(false) +const choosedData = ref([]) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + companyId: null, + }, + companyList: [], + isAdmin: false +}); +const dataList = ref([]); +const total = ref(0); + +const { queryParams } = toRefs(data); + +onMounted(() => { + const userInfo = JSON.parse(Cookies.get('userInfo')) + console.log("userInfo",userInfo) + data.isAdmin = userInfo.userType === 0; + if(data.isAdmin){ + data.queryParams.companyId = null + getCompanyList() + }else { + data.queryParams.companyId = userInfo.companyId + } + getList(); +}); +const getList = async () => { + loading.value = true; + const res = await getScenarioPage(data.queryParams); + if(res.code === 200){ + dataList.value = res.data.list + total.value = res.data.total + }else{ + ElMessage.warning(res.message) + } + loading.value = false; + +} + +const searchClick = () => { + getList(); +} +const openDialog = (type, value) => { + noticeRef.value.openDialog(type, value,data.companyList); +} + +const getCompanyList = async ()=>{ + const queryParams = { + pageNum: 1, + pageSize: 999 + } + const res = await getCompany(queryParams) + if (res.code == 200) { + data.companyList = res.data.list?res.data.list:[] + } else { + ElMessage.warning(res.message) + } +} + +const handleSizeChange = (val) => { + data.queryParams.pageSize = val + getList() +} +const handleCurrentChange = (val) => { + data.queryParams.pageNum = val + getList() +} + +/** 重置新增的表单以及其他数据 */ +function reset() { + data.queryParams = { + companyId: '', + pageNum: 1, + pageSize: 10, + } + choosedData.value = [] + data.companyList = []; + getList(); + getCompanyList() +} +const exportData = () => { + if(choosedData.value && choosedData.value.length === 0){ + ElMessage.warning('请选择需要导出的数据') + }else { + startGeneration() + } +} +const templatePath = '/scenarioExample.docx' +const startGeneration = async () => { + choosedData.value.forEach(item => { + try { + item.title = item.year+'年度内部审核策划方案' + generateWordDocument(templatePath, item, item.companyName+ '_' + item.title +'.docx'); + } catch (error){ + ElMessage({ + type: 'warning', + message: '导出失败' + }); + } + }) +} + +const handleSelectionChange = (val) => { + choosedData.value = val +} +const handleDelete = (val) => { + ElMessageBox.confirm( + '确定删除此条数据?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then( async() => { + const res = await delScenario(val.id); + if(res.code === 200){ + ElMessage({ + type: 'success', + message: '删除成功' + }); + getList(); + }else{ + ElMessage.warning(res.message) + } + }) +} + +</script> +<style lang="scss"> +.pag-container{ + float: right; + margin-top: 10px; +} +</style> -- Gitblit v1.9.2