测试用例前段vue代码.txt 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583
  1. <template>
  2. <!-- 关联用例库-->
  3. <div>
  4. <el-dialog
  5. :title="dialogTitlePlanUsecase"
  6. :visible.sync="dialogVisiblePlanUsecase"
  7. :close-on-click-modal="false"
  8. :close-on-press-escape="false"
  9. @open="dlgOpen"
  10. @close="dlgClose"
  11. width="90%"
  12. top="20px"
  13. append-to-body
  14. >
  15. <div>
  16. <el-row class="handle-box" style="margin-bottom: 10px">
  17. <el-col :span="16">
  18. <el-select
  19. v-model="search.usecaseType"
  20. size="small"
  21. filterable
  22. clearable
  23. placeholder="用例类型"
  24. @change="handleSearch"
  25. >
  26. <!-- <el-option label="功能测试" value="功能测试"></el-option>-->
  27. <!-- <el-option label="性能测试" value="性能测试"></el-option>-->
  28. <!-- <el-option label="兼容测试" value="兼容测试"></el-option>-->
  29. <el-option
  30. v-for="item in dc_data.TEST_USECASE_TYPE"
  31. :key="item.value"
  32. :label="item.label"
  33. :value="item.value"
  34. />
  35. </el-select>
  36. <el-input
  37. v-model="search.createdByName"
  38. size="small"
  39. placeholder="创建人"
  40. class="ch-input ch-input-size"
  41. @keyup.enter.native="handleSearch()"
  42. />
  43. <el-select
  44. v-model="search.priority"
  45. size="small"
  46. filterable
  47. clearable
  48. placeholder="请选择优先级"
  49. @change="handleSearch"
  50. >
  51. <!-- <el-option label="P0" value="P0"></el-option>-->
  52. <!-- <el-option label="P1" value="P1"></el-option>-->
  53. <!-- <el-option label="P2" value="P2"></el-option>-->
  54. <el-option
  55. v-for="item in dc_data.TEST_USECASE_PRIORITY"
  56. :key="item.value"
  57. :label="item.label"
  58. :value="item.value"
  59. />
  60. </el-select>
  61. </el-col>
  62. <el-col :span="3" offset="5">
  63. <el-button size="small" class="ch-button-warning" @click="handleReset()"><i
  64. class="el-icon-refresh"
  65. />&nbsp;重置
  66. </el-button>
  67. <el-button size="small" class="ch-button" @click="handleSearch()"><i class="el-icon-search"/>&nbsp;搜索
  68. </el-button>
  69. </el-col>
  70. </el-row>
  71. <!-- <button @click="test()">test</button>-->
  72. <p> &nbsp;&nbsp;&nbsp;&nbsp;选中数量 : {{ idList.length }}</p>
  73. <el-row class="handle-box">
  74. <el-col :span="24">
  75. <el-table
  76. ref="multipleTable"
  77. v-loading="loading"
  78. :data="AllData"
  79. stripe
  80. border
  81. row-class-name="g_table_row"
  82. @selection-change="handleSelectionChange"
  83. >
  84. <!-- @sort-change="sortChange"-->
  85. <el-table-column
  86. type="selection"
  87. width="55"
  88. />
  89. <el-table-column label="ID" prop="idPro" width="50"/>
  90. <!-- <el-table-column label="项目名称" prop="projectName"/>-->
  91. <el-table-column label="用例标题" prop="usecaseTitle"/>
  92. <el-table-column label="优先级" prop="priority"/>
  93. <el-table-column label="创建人" prop="createdByName"/>
  94. <el-table-column label="创建时间" prop="createdAt"/>
  95. <el-table-column label="用例类型" prop="usecaseType"/>
  96. </el-table>
  97. <!-- <div class="table-page">-->
  98. <!-- <el-pagination-->
  99. <!-- :current-page.sync="currentPage"-->
  100. <!-- :page-size="pageSize"-->
  101. <!-- :page-sizes="[5, 8, 10, 12, 15]"-->
  102. <!-- background-->
  103. <!-- layout="sizes, total, prev, pager, next"-->
  104. <!-- :total="allpage"-->
  105. <!-- @size-change="handleSizeChange"-->
  106. <!-- @current-change="handleCurrentChange"-->
  107. <!-- />-->
  108. <!-- </div>-->
  109. </el-col>
  110. </el-row>
  111. </div>
  112. <div slot="footer">
  113. <el-button @click="dialogVisiblePlanUsecase = false">取 消</el-button>
  114. <el-button type="primary" @click="confirmSubmit()">保 存</el-button>
  115. </div>
  116. </el-dialog>
  117. </div>
  118. </template>
  119. <script>
  120. import Base from '../base/base'
  121. export default {
  122. name: 'TestToPlanUsecase',
  123. components: {},
  124. mixins: [Base],
  125. data() {
  126. return {
  127. // 主界面交互字段是否进行了保存
  128. isPlanUsecaseSave: false,
  129. // 查询的时候用的字典========================================
  130. dc_key: ['TEST_USECASE_TYPE', 'TEST_USECASE_PRIORITY'],
  131. search: {
  132. priority: '',
  133. createdByName: '',
  134. usecaseType: ''
  135. // associatedProjectId: ''
  136. },
  137. // ========================================================
  138. // 列表相关=================================================
  139. // 列表中的内容
  140. AllData: [],
  141. // 加载中
  142. loading: false,
  143. // 选中事件的id列表
  144. idList: [],
  145. pageSize: 100000,
  146. // 数据页,就是当前页已经改成第二页了,但是数据对应的页码还是第一页就会有问题,所以单独设置出来
  147. // datacurrentPage: 1,
  148. // 判断是不是自己主动进行的选择操作,这样可以跳过触发handleSelectionChange事件的问题
  149. isMyselSelect: false,
  150. // =====================================================
  151. // 本页面弹框信息
  152. dialogVisiblePlanUsecase: false,
  153. dialogTitlePlanUsecase: '',
  154. // ===================================
  155. // planId上个界面传进来的计划id associatedProjectId上个界面传进来的项目id
  156. planId: '',
  157. associatedProjectId: ''
  158. }
  159. },
  160. mounted() {
  161. // const _this = this
  162. // this.initDict(_this.dc_key).then((res) => {
  163. // console.log('0')
  164. // // 获取列表数据
  165. // _this.getData()
  166. // })
  167. },
  168. methods: {
  169. dlgOpen() {
  170. const _this = this
  171. this.initDict(_this.dc_key).then((res) => {
  172. // console.log('0')
  173. // 获取列表数据
  174. _this.getData()
  175. _this.isPlanUsecaseSave = false
  176. })
  177. },
  178. dlgClose() {
  179. // console.log('close')
  180. // const _this = this
  181. this.idList = []
  182. },
  183. test() {
  184. console.log(1)
  185. console.log(this.AllData)
  186. this.$refs.multipleTable.toggleRowSelection(this.AllData[0])
  187. },
  188. // zt自己建的进入该界面的初始化方法
  189. initData(dialogTitlePlanUsecase, row) {
  190. const _this = this
  191. _this.dialogTitlePlanUsecase = dialogTitlePlanUsecase
  192. _this.dialogVisiblePlanUsecase = true
  193. _this.planId = row.id
  194. _this.associatedProjectId = row.proId
  195. // console.log(row)
  196. },
  197. getData: function() {
  198. const _this = this
  199. // console.log(_this.currentPage)
  200. _this.idList = []
  201. _this.loading = true
  202. _this.AllData = []
  203. _this.search.pageNum = _this.currentPage
  204. // console.log(_this.currentPage)
  205. _this.search.pageSize = _this.pageSize
  206. _this.search.planId = _this.planId
  207. _this.search.associatedProjectId = _this.associatedProjectId
  208. this.baseRequest('listVoWithHasSelect', _this.search).then((res) => {
  209. if (res.data.rows) {
  210. _this.isMyselSelect = true
  211. for (let i = 0; i < res.data.rows.length; i++) {
  212. const json = _this.getItemJson(res.data.rows[i])
  213. _this.AllData.push(json)
  214. // console.log(res.data.rows[i].planId)
  215. if (res.data.rows[i].planId) {
  216. _this.$refs.multipleTable.toggleRowSelection(_this.AllData[i])
  217. _this.idList.push(json.id)
  218. }
  219. }
  220. _this.isMyselSelect = false
  221. // res.data.rows.forEach(function(item) {
  222. // const json = _this.getItemJson(item)
  223. // _this.AllData.push(json)
  224. // })
  225. _this.allpage = res.data.total
  226. // 对分页进行判断是否已经选择了分页中的数据
  227. // _this.datacurrentPage = _this.currentPage
  228. // eslint-disable-next-line no-lone-blocks
  229. // {
  230. // if (this.idList.length === 0) {
  231. // // console.consolelog('no info')
  232. // } else {
  233. // for (let i = 0; i < _this.idList.length; i++) {
  234. // // console.log('000...' + _this.idList[i])
  235. // if (_this.idList[i].indexOf('@#' + _this.currentPage + '#@') !== -1) {
  236. // // console.log('111...' + _this.idList[i])
  237. // for (let j = 0; j < _this.AllData.length; j++) {
  238. // // console.log('222...' + _this.idList[i])
  239. // if (_this.AllData[j].id === _this.idList[i].substring(0, _this.idList[i].indexOf('@#' + _this.currentPage + '#@'))) {
  240. // // console.log('333...' + _this.idList[i])
  241. // // 这个操作会触发handleSelectionChange的事件,导致有问题,会将别的选项删除
  242. // _this.isMyselSelect = true
  243. // _this.$refs.multipleTable.toggleRowSelection(_this.AllData[j])
  244. // }
  245. // }
  246. // }
  247. // }
  248. // _this.isMyselSelect = false
  249. // // console.log('has info')
  250. // }
  251. //
  252. // }
  253. }
  254. _this.loading = false
  255. }).catch(() => {
  256. })
  257. // this.initOutData()
  258. },
  259. handleSearch: function() {
  260. this.getData()
  261. },
  262. handleReset: function() {
  263. this.submitTime = []
  264. for (const i in this.search) {
  265. if (i !== 'pageNum' && i !== 'pageSize') {
  266. this.search[i] = ''
  267. }
  268. }
  269. this.handleSearch()
  270. },
  271. // 选中事件
  272. handleSelectionChange(val) {
  273. // { 新的可以翻页且固定选择的方法
  274. // console.log('自动操作,当前页数:' + this.currentPage + '===' + this.datacurrentPage)
  275. if (this.isMyselSelect) {
  276. return
  277. }
  278. //
  279. // if (this.datacurrentPage !== this.currentPage) {
  280. // return
  281. // }
  282. // if (this.idList.length === 0) {
  283. // // console.consolelog('no info')
  284. // } else {
  285. // for (let i = 0; i < this.idList.length; i++) {
  286. // if (this.idList[i].indexOf('@#' + this.currentPage + '#@') != -1) {
  287. // this.idList.splice(i, 1)
  288. // i--
  289. // }
  290. // }
  291. // // console.log('has info')
  292. // }
  293. // val.forEach(element => {
  294. // this.idList.push(element.id + '@#' + this.currentPage + '#@')
  295. // })}
  296. // eslint-disable-next-line no-lone-blocks
  297. { // 老的方法
  298. this.idList = []
  299. val.forEach(element => {
  300. this.idList.push(element.id)
  301. })
  302. // console.log(this.idList)
  303. }
  304. },
  305. getItemJson: function(item) {
  306. // const json = {
  307. // createdAt: item.createdAt ? this.$common.transDate(item.createdAt,this.$constant.DATE_PATTERN.DATE_TIME_h) : ''
  308. // }
  309. // return json
  310. item.createdAt = item.createdAt ? this.$common.transDate(item.createdAt, this.$constant.DATE_PATTERN.DATE_TIME_h) : ''
  311. return item
  312. }
  313. ,
  314. // 保存/编辑数据
  315. confirmSubmit: function() {
  316. const _this = this
  317. _this.$confirm('确认是否保存关联用例?', '提示', {
  318. confirmButtonText: '确定',
  319. cancelButtonText: '取消',
  320. type: 'warning'
  321. }).then(() => {
  322. console.log('进行保存....')
  323. const postData = {
  324. planId: _this.planId
  325. }
  326. // eslint-disable-next-line no-empty
  327. if (this.idList.length === 0) {
  328. } else {
  329. postData.usecaseIds = JSON.stringify(_this.idList)
  330. }
  331. _this.opRecordSavePlanUsecase(postData, 'addUpdate')
  332. console.log('end')
  333. }).catch(() => {
  334. _this.$message({
  335. type: 'info',
  336. message: '已取消保存'
  337. })
  338. })
  339. },
  340. opRecordSavePlanUsecase: function(postData, soaUrl, isRefresh) {
  341. // console.log('postData/soaUrl/isRefresh', postData, soaUrl, isRefresh)
  342. if (isRefresh === undefined) {
  343. isRefresh = true
  344. }
  345. const _this = this
  346. const acting = this.$notify({
  347. title: '正在处理,请稍等',
  348. type: 'warning'
  349. })
  350. return this.testPlanUsecaseControllerRequest(soaUrl, postData).then((res) => {
  351. acting.close()
  352. if (isRefresh) {
  353. _this.$notify({
  354. title: '处理成功',
  355. type: 'info'
  356. })
  357. }
  358. _this.isPlanUsecaseSave = true
  359. _this.dialogVisiblePlanUsecase = false
  360. this.$emit('childEvent', _this.isPlanUsecaseSave)
  361. }).catch((err) => {
  362. acting.close()
  363. _this.$alert(err)
  364. })
  365. }
  366. ,
  367. /* 分页设定*/
  368. handleSizeChange: function(val) {
  369. this.pageSize = val
  370. this.getData()
  371. }
  372. ,
  373. /* 分页设定*/
  374. handleCurrentChange: function(val) {
  375. this.currentPage = val
  376. this.getData()
  377. }
  378. ,
  379. testPlanUsecaseControllerRequest(opUrl, postData) {
  380. return this.$channel.globleRequest('TestPlanUsecaseController', opUrl, postData, 'project')
  381. }
  382. ,
  383. baseRequest(opUrl, postData) {
  384. return this.$channel.globleRequest('TestUsecaseController', opUrl, postData, 'project')
  385. }
  386. }
  387. }
  388. </script>
  389. <style scoped>
  390. .ch-input .el-input__inner {
  391. border-radius: 0px;
  392. border-color: #32323A;
  393. }
  394. .ch-input-size {
  395. width: 150px;
  396. }
  397. .ch-button {
  398. border-radius: 0px;
  399. border-color: #32323A;
  400. background-color: #32323A;
  401. color: #fff;
  402. }
  403. .ch-button-warning {
  404. margin-left: 10px;
  405. border-radius: 0px;
  406. border-color: #E6A23C;
  407. background-color: #E6A23C;
  408. color: #fff;
  409. }
  410. .ch-button-export {
  411. margin-left: 10px;
  412. border-radius: 0px;
  413. border-color: #98CC1F;
  414. background-color: #98CC1F;
  415. color: #fff;
  416. }
  417. </style>
  418. <template>
  419. <!-- 用例库-->
  420. <div>
  421. <el-row class="handle-box" style="margin-bottom: 10px">
  422. <el-col :span="16">
  423. <!-- vue 回车触发聚焦 @keyup.enter.native-->
  424. <!-- <el-input-->
  425. <!-- v-model="search.projectName"-->
  426. <!-- style="width: 350px"-->
  427. <!-- size="small"-->
  428. <!-- placeholder="项目名称"-->
  429. <!-- class="ch-input ch-input-size"-->
  430. <!-- @change="handleSearch()"-->
  431. <!-- />-->
  432. <el-select
  433. style="width: 250px"
  434. v-model="search.associatedProjectId"
  435. size="small"
  436. filterable
  437. clearable
  438. placeholder="项目名称"
  439. @change="handleSearch()"
  440. >
  441. <el-option
  442. v-for="item in ProjectData"
  443. :key="item.value"
  444. :label="item.label"
  445. :value="item.value"
  446. >
  447. <span style="float: left">{{ item.label }}</span>
  448. <span
  449. style="float: right; color: #8492a6; font-size: 13px"
  450. >{{ item.custname }}</span>
  451. </el-option>
  452. </el-select>
  453. <el-select
  454. v-model="search.usecaseType"
  455. size="small"
  456. filterable
  457. clearable
  458. placeholder="用例类型"
  459. @change="handleSearch"
  460. >
  461. <!-- <el-option label="功能测试" value="功能测试"></el-option>-->
  462. <!-- <el-option label="性能测试" value="性能测试"></el-option>-->
  463. <!-- <el-option label="兼容测试" value="兼容测试"></el-option>-->
  464. <el-option
  465. v-for="item in dc_data.TEST_USECASE_TYPE"
  466. :key="item.value"
  467. :label="item.label"
  468. :value="item.value"
  469. />
  470. </el-select>
  471. <el-input
  472. v-model="search.createdByName"
  473. size="small"
  474. placeholder="创建人"
  475. class="ch-input ch-input-size"
  476. @keyup.enter.native="handleSearch()"
  477. />
  478. <el-select
  479. v-model="search.priority"
  480. size="small"
  481. filterable
  482. clearable
  483. placeholder="请选择优先级"
  484. @change="handleSearch"
  485. >
  486. <!-- <el-option label="P0" value="P0"></el-option>-->
  487. <!-- <el-option label="P1" value="P1"></el-option>-->
  488. <!-- <el-option label="P2" value="P2"></el-option>-->
  489. <el-option
  490. v-for="item in dc_data.TEST_USECASE_PRIORITY"
  491. :key="item.value"
  492. :label="item.label"
  493. :value="item.value"
  494. />
  495. </el-select>
  496. </el-col>
  497. <el-col :span="8">
  498. <el-button size="small" class="ch-button-warning" @click="handleReset()"><i class="el-icon-refresh"/>&nbsp;重置
  499. </el-button>
  500. <el-button size="small" class="ch-button" @click="handleSearch()"><i class="el-icon-search"/>&nbsp;搜索
  501. </el-button>
  502. <el-button size="small" class="ch-button-export" @click="initOutData()"><i class="el-icon-download"/>&nbsp;导出用例
  503. </el-button>
  504. <el-button size="small" class="ch-button" @click="handleAdd()"><i class="el-icon-menu"/>&nbsp;新增用例
  505. </el-button>
  506. <!-- <el-button size="small" class="ch-button" @click="deleteRecord()"><i class="el-icon-menu" />&nbsp;批量删除</el-button>-->
  507. </el-col>
  508. </el-row>
  509. <el-row class="handle-box">
  510. <el-col :span="24">
  511. <el-table
  512. ref="multipleTable"
  513. v-loading="loading"
  514. :data="AllData"
  515. stripe
  516. border
  517. row-class-name="g_table_row"
  518. @selection-change="handleSelectionChange"
  519. >
  520. <!-- @sort-change="sortChange"-->
  521. <el-table-column
  522. type="selection"
  523. width="55"
  524. />
  525. <!-- <el-table-column label="ID" type="index" width="50" fixed />-->
  526. <!-- <el-table-column label="ID" prop="idPro" width="100" fixed>-->
  527. <!-- <template slot-scope="scope">-->
  528. <!-- <span style="color: blue" @click="viewInfo(scope.row)">{{ scope.row.idPro }}</span>-->
  529. <!-- </template>-->
  530. <!-- </el-table-column>-->
  531. <el-table-column label="ID" prop="idPro" width="50"/>
  532. <el-table-column label="项目名称" prop="projectName"/>
  533. <el-table-column label="用例标题" prop="usecaseTitle"/>
  534. <el-table-column label="创建人" prop="createdByName"/>
  535. <el-table-column label="创建时间" prop="createdAt"/>
  536. <el-table-column label="优先级" prop="priority"/>
  537. <el-table-column label="用例类型" prop="usecaseType"/>
  538. <!-- <el-table-column label="实际处理日期" prop="actCompletionDate" width="150" sortable="custom" />-->
  539. <el-table-column label="操作" header-align="center" width="220" fixed="right">
  540. <template scope="scope">
  541. <el-button size="mini" type="primary" @click="handleCopyEdit(scope.row)">复制</el-button>
  542. <!-- <el-button v-if="scope.row.status=='1'" size="mini" type="primary" @click="handleEdit(scope.row)">编辑</el-button>-->
  543. <el-button
  544. size="mini"
  545. type="primary"
  546. @click="handleEdit(scope.row)"
  547. >编辑
  548. </el-button>
  549. <el-button
  550. size="mini"
  551. type="danger"
  552. @click="deleteSelect(scope.row) "
  553. >删除
  554. </el-button>
  555. </template>
  556. </el-table-column>
  557. </el-table>
  558. <div class="table-page">
  559. <el-pagination
  560. :current-page.sync="currentPage"
  561. :page-size="pageSize"
  562. :page-sizes="[5, 8, 10, 12, 15]"
  563. background
  564. layout="sizes, total, prev, pager, next"
  565. :total="allpage"
  566. @size-change="handleSizeChange"
  567. @current-change="handleCurrentChange"
  568. />
  569. </div>
  570. </el-col>
  571. </el-row>
  572. <el-dialog
  573. :title="dialogTitle"
  574. :visible.sync="dialogVisible"
  575. width="75%"
  576. top="50px"
  577. :close-on-click-modal="false"
  578. :close-on-press-escape="false"
  579. @open="dlgOpen"
  580. @close="dlgClose"
  581. >
  582. <el-form ref="form" :model="form" style="width: 100%;padding: 0px 5px 5px 5px" :rules="rules">
  583. <el-row>
  584. <el-col style="padding-bottom: 10px">
  585. <!-- <span class="card_title">基本信息</span>-->
  586. <el-card shadow="always" style="padding: 15px 5px 5px 15px">
  587. <el-row>
  588. <el-col :span="3" class="col-txt"><span>关联项目</span></el-col>
  589. <el-col :span="10" class="col-input">
  590. <el-form-item prop="associatedProjectId">
  591. <el-select
  592. v-model="form.associatedProjectId"
  593. filterable
  594. clearable
  595. placeholder="项目名称"
  596. @change="getCustName(form.associatedProjectId)"
  597. >
  598. <el-option
  599. v-for="item in ProjectData"
  600. :key="item.value"
  601. :label="item.label"
  602. :value="item.value"
  603. >
  604. <span style="float: left">{{ item.label }}</span>
  605. <span
  606. style="float: right; color: #8492a6; font-size: 13px"
  607. >{{ item.custname }}</span>
  608. </el-option>
  609. </el-select>
  610. </el-form-item>
  611. </el-col>
  612. <el-col :span="3" class="col-txt"><span>客户名称</span></el-col>
  613. <el-col :span="5" class="col-input">
  614. <el-input v-model="form.custName" readonly></el-input>
  615. </el-col>
  616. </el-row>
  617. <el-row>
  618. <el-col :span="3" class="col-txt"><span>用例主题</span></el-col>
  619. <el-col :span="18" class="col-input">
  620. <el-form-item prop="usecaseTitle">
  621. <el-input
  622. v-model="form.usecaseTitle"
  623. :rows="1"
  624. type="textarea"
  625. />
  626. </el-form-item>
  627. </el-col>
  628. </el-row>
  629. <el-row>
  630. <el-col :span="3" class="col-txt"><span>用例类型</span></el-col>
  631. <el-col :span="5" class="col-input">
  632. <el-form-item prop="usecaseType">
  633. <el-select
  634. v-model="form.usecaseType"
  635. filterable
  636. clearable
  637. placeholder="用例类型"
  638. >
  639. <el-option
  640. v-for="item in dc_data.TEST_USECASE_TYPE"
  641. :key="item.value"
  642. :label="item.label"
  643. :value="item.value"
  644. />
  645. </el-select>
  646. <!-- <el-input v-model="form.bugType" />-->
  647. </el-form-item>
  648. </el-col>
  649. <el-col :span="3" class="col-txt"><span>优先级</span></el-col>
  650. <el-col :span="5" class="col-input">
  651. <el-form-item prop="priority">
  652. <el-select
  653. v-model="form.priority"
  654. filterable
  655. clearable
  656. placeholder="优先级"
  657. >
  658. <el-option
  659. v-for="item in dc_data.TEST_USECASE_PRIORITY"
  660. :key="item.value"
  661. :label="item.label"
  662. :value="item.value"
  663. />
  664. </el-select>
  665. <!-- <el-input v-model="form.bugAttribute" />-->
  666. </el-form-item>
  667. </el-col>
  668. </el-row>
  669. <el-row>
  670. <el-col :span="3" class="col-txt"><span>前置条件</span></el-col>
  671. <el-col :span="18" class="col-input">
  672. <el-form-item prop="preconditions">
  673. <el-input v-model="form.preconditions" type="textarea"/>
  674. </el-form-item>
  675. </el-col>
  676. </el-row>
  677. <el-row>
  678. <el-col :span="3" class="col-txt"><span>按步骤执行</span></el-col>
  679. </el-row>
  680. <el-row>
  681. <el-col :span="3" class="col-txt"><span>#</span></el-col>
  682. <el-col :span="10" class="col-input"><span>步骤描述</span></el-col>
  683. <el-col :span="8" class="col-input"><span>预期结果</span></el-col>
  684. </el-row>
  685. <el-row style="list-style: none" v-for="(item,index) in array" :key="index">
  686. <el-col :span="3" class="col-txt"><span>{{ index + 1 }}</span></el-col>
  687. <el-col :span="10" class="col-input">
  688. <el-form-item>
  689. <el-input
  690. v-model="item.step"
  691. :rows="1"
  692. type="textarea"
  693. />
  694. </el-form-item>
  695. </el-col>
  696. <el-col :span="8" class="col-input">
  697. <el-form-item>
  698. <el-input
  699. v-model="item.expectedResults"
  700. :rows="1"
  701. type="textarea"
  702. />
  703. </el-form-item>
  704. </el-col>
  705. <el-col :span="2" class="col-txt">
  706. <el-button @click="addStep(index)" type="primary" size="small" circle>+</el-button>
  707. </el-col>
  708. <el-col :span="1" class="col-txt">
  709. <el-button v-if="array.length!=1||index!=0" @click="removeSetp(index)" type="danger"
  710. size="small" icon="el-icon-delete" circle
  711. ></el-button>
  712. </el-col>
  713. </el-row>
  714. </el-card>
  715. </el-col>
  716. </el-row>
  717. </el-form>
  718. <div slot="footer">
  719. <el-button @click="dialogVisible = false">取 消</el-button>
  720. <el-button v-if="!viewVisible" type="primary" @click="confirmSubmit()">确 定</el-button>
  721. </div>
  722. </el-dialog>
  723. </div>
  724. </template>
  725. <script>
  726. import Base from '../base/base'
  727. import BaseData from '../base/baseData'
  728. // import QuillEditor from '@/components/QuillEditor'
  729. // import { upload } from '@/static/utils/channel'
  730. // import UserSelect from '@/views/components/UserSelect'
  731. // import BizUserSelect from '@/views/components/BizUserSelect'
  732. // import { sendSock, createWebSocket, closeSock } from '@/static/utils/socket'
  733. // import common from '@/static/utils/common'
  734. export default {
  735. name: 'TestUsecase',
  736. components: {
  737. // QuillEditor,
  738. // UserSelect,
  739. // BizUserSelect
  740. },
  741. mixins: [Base, BaseData],
  742. data() {
  743. return {
  744. // 查询的时候用的字典========================================
  745. dc_key: ['TEST_USECASE_TYPE', 'TEST_USECASE_PRIORITY'],
  746. // ========================================================
  747. // 列表相关=================================================
  748. // 列表中的内容
  749. AllData: [],
  750. // 加载中
  751. loading: false,
  752. // 选中事件的id列表
  753. idList: [],
  754. // =====================================================
  755. // 弹框相关============================================================
  756. form: this.initForm(),
  757. // 是否只是查看
  758. viewVisible: false,
  759. // 判断弹框界面是否开着
  760. dialogVisible: false,
  761. dialogTitle: '新增',
  762. // 是否是新增
  763. isAdd: true,
  764. // 添加步骤
  765. array: [
  766. // {
  767. // id
  768. // step: '步骤1',
  769. // expectedResults: '预期结果1'
  770. // }, {
  771. // step: '步骤2',
  772. // expectedResults: '预期结果2'
  773. // }, {
  774. // step: '步骤3',
  775. // expectedResults: '预期结果3'
  776. // }
  777. ],
  778. // ================================================================
  779. search: {
  780. priority: '',
  781. createdByName: '',
  782. usecaseType: '',
  783. projectName: ''
  784. // date_from_1: '',
  785. // date_to_1: '',
  786. },
  787. currentPage: 1,
  788. allpage: 0,
  789. pageSize: 10,
  790. // wxCodeUrl: false,
  791. rules: {
  792. associatedProjectId: [{ required: true, message: '请选择项目', trigger: 'blur' }],
  793. usecaseTitle: [{ required: true, message: '请输入用例主题', trigger: 'blur' }],
  794. usecaseType: [{ required: true, message: '请选择用例类型', trigger: 'blur' }],
  795. priority: [{ required: true, message: '请选择优先级', trigger: 'blur' }],
  796. handleUserId: [{ required: true, message: '请选择处理人', trigger: 'blur' }]
  797. }
  798. }
  799. },
  800. mounted() {
  801. const _this = this
  802. this.initDict(_this.dc_key).then((res) => {
  803. console.log('初始化')
  804. // console.log(_this.dc_data)
  805. // 获取列表数据
  806. _this.getData()
  807. // 获取项目数据
  808. _this.initProject()
  809. // console.log(_this.ProjectData)
  810. // console.log(_this.ProjectMap)
  811. })
  812. },
  813. methods: {
  814. getData: function() {
  815. const _this = this
  816. // console.log(_this.currentPage)
  817. _this.loading = true
  818. _this.AllData = []
  819. _this.search.pageNum = _this.currentPage
  820. // console.log(_this.currentPage)
  821. _this.search.pageSize = _this.pageSize
  822. this.baseRequest('listVo', _this.search).then((res) => {
  823. if (res.data.rows) {
  824. res.data.rows.forEach(function(item) {
  825. const json = _this.getItemJson(item)
  826. _this.AllData.push(json)
  827. })
  828. _this.allpage = res.data.total
  829. }
  830. _this.loading = false
  831. }).catch(() => {
  832. })
  833. // this.initOutData()
  834. },
  835. // 添加步骤
  836. addStep(index) {
  837. const _this = this
  838. // 如果序号大于最大值,就是屁股插入,不然就是中间插入
  839. if ((index + 2) > _this.array.length) {
  840. _this.array.push({
  841. id: '',
  842. step: '',
  843. expectedResults: ''
  844. })
  845. } else {
  846. _this.array.splice(index + 1, 0, {
  847. id: '',
  848. step: '',
  849. expectedResults: ''
  850. })
  851. }
  852. },
  853. // 删除步骤
  854. removeSetp(index) {
  855. const _this = this
  856. if (_this.array) {
  857. _this.array.splice(index, 1)
  858. }
  859. },
  860. // 将项目名称对应的客户名称填到对应的字段中
  861. getCustName(val) {
  862. const _this = this
  863. // console.log('hello')
  864. // console.log(_this.ProjectData.length)
  865. // console.log(val)
  866. for (let i = 0; i < _this.ProjectData.length; i++) {
  867. // console.log(_this.ProjectData[i].value)
  868. if (_this.ProjectData[i].value == val) {
  869. // console.log('ok')
  870. _this.form.custName = _this.ProjectData[i].custname
  871. // console.log(_this.form.custName)
  872. break
  873. }
  874. }
  875. // console.log(_this.form)
  876. },
  877. handleSearch: function() {
  878. this.getData()
  879. },
  880. handleReset: function() {
  881. this.submitTime = []
  882. for (const i in this.search) {
  883. if (i !== 'pageNum' && i !== 'pageSize') {
  884. this.search[i] = ''
  885. }
  886. }
  887. this.handleSearch()
  888. },
  889. // 选中事件
  890. handleSelectionChange(val) {
  891. this.idList = []
  892. val.forEach(element => {
  893. this.idList.push(element.id)
  894. })
  895. console.log(this.idList)
  896. },
  897. // 当表格的排序条件发生变化的时候会触发该事件 { column, prop, order }
  898. // sortChange(column,prop,order) {
  899. //
  900. // },
  901. // 批量删除操作
  902. deleteRecord: function(val) {
  903. if (this.idList.length === 0) {
  904. this.$notify({
  905. title: '请先选择明细记录',
  906. type: 'info'
  907. })
  908. return
  909. }
  910. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  911. confirmButtonText: '确定',
  912. cancelButtonText: '取消',
  913. type: 'warning'
  914. }).then(() => {
  915. this.baseRequest('remove/' + this.idList).then((res) => {
  916. if (res.status === 200) {
  917. this.getData()
  918. this.$message({
  919. message: '删除成功',
  920. type: 'success'
  921. })
  922. }
  923. }).catch(() => {
  924. })
  925. }).catch(() => {
  926. this.$message({
  927. type: 'info',
  928. message: '已取消删除'
  929. })
  930. })
  931. },
  932. // 进行删除操作
  933. deleteSelect: function(val) {
  934. console.log(val)
  935. if (!val) {
  936. this.$notify({
  937. title: '请先选择要删除的列',
  938. type: 'info'
  939. })
  940. return
  941. }
  942. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  943. confirmButtonText: '确定',
  944. cancelButtonText: '取消',
  945. type: 'warning'
  946. }).then(() => {
  947. console.log('删除' + val.id)
  948. this.baseRequest('remove/' + val.id).then((res) => {
  949. if (res.status === 200) {
  950. this.getData()
  951. this.$message({
  952. message: '删除成功',
  953. type: 'success'
  954. })
  955. }
  956. }).catch(() => {
  957. })
  958. }).catch(() => {
  959. this.$message({
  960. type: 'info',
  961. message: '已取消删除'
  962. })
  963. })
  964. },
  965. initForm: function() {
  966. return {
  967. priority: 'P0',
  968. id: ''
  969. }
  970. },
  971. // 导出数据===========================================
  972. initOutData: function() {
  973. const _this = this
  974. this.OutData = []
  975. const title = []
  976. title.push('编号')
  977. title.push('项目名称')
  978. title.push('客户名称')
  979. title.push('用例主题')
  980. title.push('用例类型')
  981. title.push('优先级')
  982. title.push('前置条件')
  983. title.push('步骤顺序号')
  984. title.push('步骤描述')
  985. title.push('预期结果')
  986. title.push('创建人')
  987. title.push('创建时间')
  988. this.OutData.push(title)
  989. let postData = {}
  990. postData = _this.search
  991. if (_this.idList.length === 0) {
  992. // this.$notify({
  993. // title: '请先选择明细记录',
  994. // type: 'info'
  995. // })
  996. // return
  997. postData.idList = null
  998. } else {
  999. console.log('initOutData', _this.idList)
  1000. postData.idList = JSON.stringify(_this.idList)
  1001. }
  1002. this.baseRequest('findAllByInfo', postData).then((res) => {
  1003. if (res.data) {
  1004. res.data.forEach(function(item) {
  1005. const jsonMap = _this.getItemJson(item)
  1006. const jsonArray = []
  1007. jsonArray.push(jsonMap.id)
  1008. jsonArray.push(jsonMap.projectName)
  1009. jsonArray.push(jsonMap.custName)
  1010. jsonArray.push(jsonMap.usecase_title)
  1011. jsonArray.push(jsonMap.usecase_type)
  1012. jsonArray.push(jsonMap.priority)
  1013. jsonArray.push(jsonMap.preconditions)
  1014. jsonArray.push(jsonMap.stepIndex)
  1015. jsonArray.push(jsonMap.stepdescribe)
  1016. jsonArray.push(jsonMap.expected_results)
  1017. jsonArray.push(jsonMap.createdByName)
  1018. jsonArray.push(jsonMap.createdAtString)
  1019. _this.OutData.push(jsonArray)
  1020. })
  1021. _this.confirmOutput()
  1022. }
  1023. }).catch(() => {
  1024. })
  1025. },
  1026. getItemJson: function(item) {
  1027. // const json = {
  1028. // createdAt: item.createdAt ? this.$common.transDate(item.createdAt,this.$constant.DATE_PATTERN.DATE_TIME_h) : ''
  1029. // }
  1030. // return json
  1031. item.createdAt = item.createdAt ? this.$common.transDate(item.createdAt, this.$constant.DATE_PATTERN.DATE_TIME_h) : ''
  1032. return item
  1033. },
  1034. confirmOutput() {
  1035. const OutSize = [{ wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }]
  1036. const fileName = '导出用例' + new Date().Format('yyyy-MM-dd hh:mm')
  1037. this.$outputXlsxFile(this.OutData, OutSize, fileName)
  1038. },
  1039. dlgClose() {
  1040. // const _this = this
  1041. if (!this.isAdd) {
  1042. this.array = []
  1043. this.form = this.initForm()
  1044. } else if (this.dialogTitle === '复制') {
  1045. this.array = []
  1046. this.form = this.initForm()
  1047. }
  1048. },
  1049. dlgOpen: function() {
  1050. const _this = this
  1051. console.log(_this.array)
  1052. if (_this.form.id !== '') {
  1053. _this.array = []
  1054. const postData = {
  1055. id: _this.form.id
  1056. }
  1057. this.baseRequest('getVoById', postData).then((res) => {
  1058. if (res.data) {
  1059. _this.form = res.data
  1060. }
  1061. }).catch(() => {
  1062. })
  1063. this.testUsecaseStepControllerRequest('findListByUsecaseId', { usecaseId: _this.form.id }).then((res) => {
  1064. if (res.data) {
  1065. _this.array = []
  1066. for (let i = 0; i < res.data.length; i++) {
  1067. const json = {
  1068. id: res.data[i].id,
  1069. step: res.data[i].stepdescribe,
  1070. expectedResults: res.data[i].expectedResults
  1071. }
  1072. // console.log(json)
  1073. // console.log(_this.array)
  1074. _this.array.push(json)
  1075. }
  1076. }
  1077. if (this.array.length == 0) {
  1078. this.array.push({
  1079. id: '',
  1080. step: '',
  1081. expectedResults: ''
  1082. })
  1083. }
  1084. }).catch(() => {
  1085. })
  1086. } else {
  1087. if (this.array.length == 0) {
  1088. this.array.push({
  1089. id: '',
  1090. step: '',
  1091. expectedResults: ''
  1092. })
  1093. }
  1094. }
  1095. },
  1096. /* 编辑*/
  1097. handleEdit: function(val) {
  1098. this.isAdd = false
  1099. this.form.id = val.id
  1100. this.dialogVisible = true
  1101. this.dialogTitle = '编辑'
  1102. this.viewVisible = false
  1103. },
  1104. // 复制数据
  1105. handleCopyEdit: function(val) {
  1106. this.isAdd = true
  1107. this.form.id = val.id
  1108. this.dialogVisible = true
  1109. this.dialogTitle = '复制'
  1110. this.viewVisible = false
  1111. },
  1112. // 查看
  1113. viewInfo: function(val) {
  1114. this.isAdd = false
  1115. this.form.id = val.id
  1116. this.dialogVisible = true
  1117. this.dialogTitle = '查看'
  1118. this.viewVisible = true
  1119. },
  1120. /* 新增*/
  1121. handleAdd: function() {
  1122. this.form = this.initForm()
  1123. this.isAdd = true
  1124. this.dialogVisible = true
  1125. this.dialogTitle = '新增用例'
  1126. this.viewVisible = false
  1127. if (this.array) {
  1128. // console.log(this.array.length)
  1129. for (let i = 0; i < this.array.length; i++) {
  1130. // console.log(this.array[i].step)
  1131. // console.log(this.array[i].expectedResults)
  1132. if (this.array[i].step == '' && this.array[i].expectedResults == '') {
  1133. this.array.splice(i, 1)
  1134. i--
  1135. }
  1136. }
  1137. // console.log(this.array.length)
  1138. }
  1139. },
  1140. // 保存/编辑数据
  1141. confirmSubmit: function() {
  1142. const _this = this
  1143. this.$refs.form.validate(valid => {
  1144. if (valid) {
  1145. // if (this.fileError) {
  1146. // _this.$message.error('附件正在上传,请等待上传完成')
  1147. // return
  1148. // }
  1149. let soaUrl = 'edit'
  1150. const postData = {
  1151. id: _this.form.id,
  1152. // idPro: _this.form.idPro,
  1153. usecaseTitle: _this.form.usecaseTitle,
  1154. priority: _this.form.priority,
  1155. usecaseType: _this.form.usecaseType,
  1156. associatedProjectId: _this.form.associatedProjectId,
  1157. preconditions: _this.form.preconditions
  1158. }
  1159. const newArray = []
  1160. for (let i = 0; i < _this.array.length; i++) {
  1161. newArray.push(
  1162. {
  1163. id: _this.array[i].id,
  1164. stepNumber: i,
  1165. stepdescribe: _this.array[i].step,
  1166. expectedResults: _this.array[i].expectedResults
  1167. }
  1168. )
  1169. }
  1170. if (newArray.length !== 0) {
  1171. // eslint-disable-next-line no-empty
  1172. if (newArray.length == 1 && newArray[0].stepdescribe == '' && newArray[0].expectedResults == '') {
  1173. } else {
  1174. postData.testUsecaseSteps = JSON.stringify(newArray)
  1175. }
  1176. }
  1177. if (this.dialogTitle === '复制' && this.isAdd) {
  1178. soaUrl = 'add'
  1179. // postData.handleTime = ''
  1180. // postData.verificationTime = ''
  1181. // postData.verificationSituation = ''
  1182. // postData.actCompletionDate = ''
  1183. } else if (this.isAdd) {
  1184. soaUrl = 'add'
  1185. }
  1186. // console.log(postData)
  1187. if (soaUrl == 'edit') {
  1188. this.$confirm('此操作将永久修改该数据, 是否继续?', '提示', {
  1189. confirmButtonText: '确定',
  1190. cancelButtonText: '取消',
  1191. type: 'warning'
  1192. }).then(() => {
  1193. this.opRecord(postData, soaUrl)
  1194. }).catch(() => {
  1195. this.$message({
  1196. type: 'info',
  1197. message: '已取消修改'
  1198. })
  1199. })
  1200. } else {
  1201. this.opRecord(postData, soaUrl)
  1202. }
  1203. _this.array = []
  1204. } else {
  1205. console.log('error submit!!')
  1206. return false
  1207. }
  1208. })
  1209. },
  1210. /* 分页设定*/
  1211. handleSizeChange: function(val) {
  1212. this.pageSize = val
  1213. this.getData()
  1214. },
  1215. /* 分页设定*/
  1216. handleCurrentChange: function(val) {
  1217. this.currentPage = val
  1218. this.getData()
  1219. },
  1220. testUsecaseStepControllerRequest(opUrl, postData) {
  1221. return this.$channel.globleRequest('TestUsecaseStepController', opUrl, postData, 'project')
  1222. },
  1223. baseRequest(opUrl, postData) {
  1224. return this.$channel.globleRequest('TestUsecaseController', opUrl, postData, 'project')
  1225. }
  1226. }
  1227. }
  1228. </script>
  1229. <style scoped>
  1230. .ch-input .el-input__inner {
  1231. border-radius: 0px;
  1232. border-color: #32323A;
  1233. }
  1234. .ch-input-size {
  1235. width: 150px;
  1236. }
  1237. .ch-button {
  1238. border-radius: 0px;
  1239. border-color: #32323A;
  1240. background-color: #32323A;
  1241. color: #fff;
  1242. }
  1243. .ch-button-warning {
  1244. margin-left: 10px;
  1245. border-radius: 0px;
  1246. border-color: #E6A23C;
  1247. background-color: #E6A23C;
  1248. color: #fff;
  1249. }
  1250. .ch-button-export {
  1251. margin-left: 10px;
  1252. border-radius: 0px;
  1253. border-color: #98CC1F;
  1254. background-color: #98CC1F;
  1255. color: #fff;
  1256. }
  1257. </style>
  1258. <template>
  1259. <!-- 测试计划-->
  1260. <div>
  1261. <!-- ==============================================================================-->
  1262. <!-- ==============================================================================-->
  1263. <!-- <el-button @click="test()">测试</el-button>-->
  1264. <!-- ==============================================================================-->
  1265. <!-- ==============================================================================-->
  1266. <el-row class="handle-box" style="margin-bottom: 10px">
  1267. <el-col :span="12">
  1268. <!-- vue 回车触发聚焦 @keyup.enter.native-->
  1269. <!-- <el-input-->
  1270. <!-- v-model="search.projectName"-->
  1271. <!-- style="width: 350px"-->
  1272. <!-- size="small"-->
  1273. <!-- placeholder="项目名称"-->
  1274. <!-- class="ch-input ch-input-size"-->
  1275. <!-- @change="handleSearch()"-->
  1276. <el-select
  1277. v-model="search.proId"
  1278. style="width: 240px"
  1279. size="small"
  1280. filterable
  1281. clearable
  1282. placeholder="项目名称"
  1283. @change="handleSearch()"
  1284. >
  1285. <el-option
  1286. v-for="item in ProjectData"
  1287. :key="item.value"
  1288. :label="item.label"
  1289. :value="item.value"
  1290. >
  1291. <span style="float: left">{{ item.label }}</span>
  1292. <span
  1293. style="float: right; color: #8492a6; font-size: 13px"
  1294. >{{ item.custname }}</span>
  1295. </el-option>
  1296. </el-select>
  1297. <el-select
  1298. v-model="search.status"
  1299. size="small"
  1300. filterable
  1301. clearable
  1302. placeholder="请选择状态"
  1303. @change="handleSearch"
  1304. >
  1305. <!-- 状态0正常(灰色状态,未启动)1删除2正常(可用状态)3用例执行完成',-->
  1306. <el-option label="未启动" value="0"/>
  1307. <el-option label="进行中" value="2"/>
  1308. <el-option label="已完成" value="3"/>
  1309. <!-- <el-option-->
  1310. <!-- v-for="item in dc_data.TEST_USECASE_TYPE"-->
  1311. <!-- :key="item.value"-->
  1312. <!-- :label="item.label"-->
  1313. <!-- :value="item.value"-->
  1314. <!-- />-->
  1315. </el-select>
  1316. <el-input
  1317. v-model="search.handleUserNames"
  1318. size="small"
  1319. placeholder="负责人"
  1320. class="ch-input ch-input-size"
  1321. @keyup.enter.native="handleSearch()"
  1322. />
  1323. </el-col>
  1324. <el-col :span="8" offset="4">
  1325. <el-button size="small" class="ch-button-warning" @click="handleReset()"><i class="el-icon-refresh"/>重置
  1326. </el-button>
  1327. <el-button size="small" class="ch-button" @click="handleSearch()"><i class="el-icon-search"/>&nbsp;搜索
  1328. </el-button>
  1329. <!-- <el-button size="small" class="ch-button-export" @click="initOutData()"><i class="el-icon-download"/>&nbsp;导出用例-->
  1330. <!-- </el-button>-->
  1331. <el-button size="small" class="ch-button" @click="handleAdd()"><i class="el-icon-menu"/>&nbsp;新增测试计划
  1332. </el-button>
  1333. <!-- <el-button size="small" class="ch-button" @click="handleEditTop()"><i class="el-icon-menu"/>&nbsp;计划编辑-->
  1334. <!-- </el-button>-->
  1335. <!-- <el-button size="small" class="ch-button" @click="handleStatusTop()"><i class="el-icon-menu"/>&nbsp;计划状态-->
  1336. <!-- </el-button>-->
  1337. <!-- <el-button size="small" class="ch-button" @click="deleteRecord()"><i class="el-icon-menu" />&nbsp;批量删除</el-button>-->
  1338. </el-col>
  1339. </el-row>
  1340. <el-row class="handle-box">
  1341. <el-col :span="24">
  1342. <el-table
  1343. ref="multipleTable"
  1344. v-loading="loading"
  1345. :data="AllData"
  1346. stripe
  1347. border
  1348. row-class-name="g_table_row"
  1349. @selection-change="handleSelectionChange"
  1350. >
  1351. <!-- @sort-change="sortChange"-->
  1352. <el-table-column
  1353. type="selection"
  1354. width="55"
  1355. />
  1356. <!-- <el-table-column label="ID" type="index" width="50" fixed />-->
  1357. <!-- <el-table-column label="ID" prop="idPro" width="100" fixed>-->
  1358. <!-- <template slot-scope="scope">-->
  1359. <!-- <span style="color: blue" @click="viewInfo(scope.row)">{{ scope.row.idPro }}</span>-->
  1360. <!-- </template>-->
  1361. <!-- </el-table-column>-->
  1362. <el-table-column label="关联项目名称" prop="projectName" width="200"/>
  1363. <el-table-column label="关联任务ID" prop="taskNo" width="100"/>
  1364. <el-table-column label="测试计划名称" prop="planName" width="300"/>
  1365. <el-table-column label="计划完成日期" prop="completionDate" width="85"/>
  1366. <el-table-column label="负责人" prop="handleUserNames" width="80"/>
  1367. <el-table-column label="当前状态" prop="statusString" width="80"/>
  1368. <el-table-column label="创建人" prop="createdByName" width="80"/>
  1369. <el-table-column label="创建日期" prop="createdAtString" width="80"/>
  1370. <el-table-column label="通过率" prop="passRateString" width="80"/>
  1371. <el-table-column label="已测用例/关联用例" prop="passRateInfoString" width="80"/>
  1372. <el-table-column label="结果分布" prop="resultDistribution" width="180">
  1373. <template slot-scope="scope">
  1374. <div class="container">
  1375. <div class="passcontainer">
  1376. <el-tooltip class="item" effect="dark"
  1377. :content="countWidth(scope.row.totalNum,scope.row.passNum)+'%'"
  1378. placement="top"
  1379. >
  1380. <div class="br5rem"
  1381. :style="{width:countWidth(scope.row.totalNum,scope.row.passNum)+'%',background:'green',height:'20px',float:'left'}"
  1382. >
  1383. </div>
  1384. </el-tooltip>
  1385. <el-tooltip class="item" effect="dark"
  1386. :content="countWidth(scope.row.totalNum,scope.row.repairNum)+'%'"
  1387. placement="top"
  1388. >
  1389. <div class="br5rem"
  1390. :style="{width:countWidth(scope.row.totalNum,scope.row.repairNum)+'%',background:'blue',height:'20px',float:'left'}"
  1391. ></div>
  1392. </el-tooltip>
  1393. <el-tooltip class="item" effect="dark"
  1394. :content="countWidth(scope.row.totalNum,scope.row.failNum)+'%'"
  1395. placement="top"
  1396. >
  1397. <div class="br5rem"
  1398. :style="{width:countWidth(scope.row.totalNum,scope.row.failNum)+'%',background:'red',height:'20px',float:'left'}"
  1399. ></div>
  1400. </el-tooltip>
  1401. <el-tooltip class="item" effect="dark"
  1402. :content="countWidth(scope.row.totalNum,scope.row.skipNum)+'%'"
  1403. placement="top"
  1404. >
  1405. <div class="br5rem"
  1406. :style="{width:countWidth(scope.row.totalNum,scope.row.skipNum)+'%',background:'#ECEEF4',height:'20px',float:'left'}"
  1407. ></div>
  1408. </el-tooltip>
  1409. </div>
  1410. </div>
  1411. </template>
  1412. </el-table-column>
  1413. <el-table-column label="测试阶段" prop="planPhase" width="80"/>
  1414. <!-- <el-table-column label="实际处理日期" prop="actCompletionDate" width="150" sortable="custom" />-->
  1415. <el-table-column label="操作" width="200" fixed="right">
  1416. <!-- <el-button v-if="this.isShowTaskEdit" size="mini" type="primary" @click="openAddBatch()">创建批次</el-button>-->
  1417. <template scope="scope">
  1418. <!-- <el-button v-if="this.$has('createBatch')" size="mini" type="primary" @click="openAddBatch()">创建批次</el-button>-->
  1419. <el-button
  1420. v-if="scope.row.isShowTaskEdit"
  1421. size="mini"
  1422. type="primary"
  1423. round
  1424. style="margin-bottom: 10px"
  1425. @click="handleEdit(scope.row)"
  1426. >计划编辑
  1427. </el-button>
  1428. <el-button
  1429. v-if="scope.row.isShowTaskStatus"
  1430. size="mini"
  1431. type="success"
  1432. round
  1433. style="margin-bottom: 10px"
  1434. @click="handleTaskStatus(scope.row)"
  1435. >计划状态
  1436. </el-button>
  1437. <br v-if="scope.row.isShowTaskStatus||scope.row.isShowTaskEdit">
  1438. <el-button
  1439. v-if="scope.row.status ==0||scope.row.status ==2"
  1440. size="mini"
  1441. type="primary"
  1442. :disabled="scope.row.status==0"
  1443. round
  1444. @click="handleToPlanUsecase(scope.row)"
  1445. >关联用例
  1446. </el-button>
  1447. <el-button
  1448. v-if="scope.row.status==0||scope.row.status ==2"
  1449. size="mini"
  1450. type="success"
  1451. :disabled="scope.row.status==0"
  1452. round
  1453. @click="handleDoPlanUsecase(scope.row)"
  1454. >用例执行
  1455. </el-button>
  1456. <el-button
  1457. v-else-if="scope.row.status==3"
  1458. size="mini"
  1459. type="success"
  1460. round
  1461. @click="handleShowPlanUsecase(scope.row)"
  1462. >用例执行查看
  1463. </el-button>
  1464. <!-- <el-button-->
  1465. <!-- size="mini"-->
  1466. <!-- type="danger"-->
  1467. <!-- @click="deleteSelect(scope.row) "-->
  1468. <!-- >删除-->
  1469. <!-- </el-button>-->
  1470. </template>
  1471. </el-table-column>
  1472. </el-table>
  1473. <div class="table-page">
  1474. <el-pagination
  1475. :current-page.sync="currentPage"
  1476. :page-size="pageSize"
  1477. :page-sizes="[5, 8, 10, 12, 15]"
  1478. background
  1479. layout="sizes, total, prev, pager, next"
  1480. :total="allpage"
  1481. @size-change="handleSizeChange"
  1482. @current-change="handleCurrentChange"
  1483. />
  1484. </div>
  1485. </el-col>
  1486. </el-row>
  1487. <el-dialog
  1488. :title="dialogTitle"
  1489. :visible.sync="dialogVisible"
  1490. width="90%"
  1491. top="25px"
  1492. :close-on-click-modal="false"
  1493. :close-on-press-escape="false"
  1494. @open="dlgOpen"
  1495. @close="dlgClose"
  1496. >
  1497. <el-form ref="form" :model="form" style="width: 100%;padding: 0px 5px 5px 5px" :rules="rules">
  1498. <p v-if="form.taskNo">关联任务ID: {{ form.taskNo }}</p>
  1499. <el-row>
  1500. <el-col style="padding-bottom: 10px;padding-top: 0px">
  1501. <span class="card_title">基本信息</span>
  1502. <el-card shadow="always" style="padding: 5px 0px 5px 0px">
  1503. <el-row>
  1504. <el-col :span="3" class="col-txt"><span>项目名称</span></el-col>
  1505. <el-col :span="10" class="col-input">
  1506. <el-form-item prop="proId">
  1507. <el-select
  1508. v-model="form.proId"
  1509. filterable
  1510. clearable
  1511. placeholder="项目名称"
  1512. @change="getCustName(form.proId)"
  1513. >
  1514. <el-option
  1515. v-for="item in ProjectData"
  1516. :key="item.value"
  1517. :label="item.label"
  1518. :value="item.value"
  1519. >
  1520. <span style="float: left">{{ item.label }}</span>
  1521. <span
  1522. style="float: right; color: #8492a6; font-size: 13px"
  1523. >{{ item.custname }}</span>
  1524. </el-option>
  1525. </el-select>
  1526. </el-form-item>
  1527. </el-col>
  1528. <el-col :span="3" class="col-txt"><span>客户名称</span></el-col>
  1529. <el-col :span="5" class="col-input">
  1530. <el-input v-model="form.custName" readonly/>
  1531. </el-col>
  1532. <!-- ==============================================================================-->
  1533. <!-- ==============================================================================-->
  1534. <!-- <el-button @click="test()">测试</el-button>-->
  1535. <!-- ==============================================================================-->
  1536. <!-- ==============================================================================-->
  1537. </el-row>
  1538. <el-row>
  1539. <el-col :span="1" offset="1" class="col-txt"><span>#</span></el-col>
  1540. <el-col :span="9" class="col-input"><span>计划名称</span></el-col>
  1541. <el-col :span="4" class="col-input-zt"><span>负责人</span></el-col>
  1542. <el-col :span="4" class="col-input"><span>计划完成日期</span></el-col>
  1543. <el-col :span="3" class="col-input"><span>测试阶段</span></el-col>
  1544. <el-col :span="2" class="col-txt-center"><span>操作</span></el-col>
  1545. </el-row>
  1546. <el-row v-for="(item,index) in array" style="list-style: none">
  1547. <el-col :span="1" offset="1" class="col-txt">
  1548. <span>{{ (item.id == '') && !isAdd ? '新增' + (index + 1) : (index + 1) }}</span>
  1549. </el-col>
  1550. <!-- 计划内容-->
  1551. <el-col :span="9" class="col-input">
  1552. <el-form-item prop="planName">
  1553. <el-input
  1554. v-model="item.planName"
  1555. autosize
  1556. placeholder="请输入内容"
  1557. type="textarea"
  1558. />
  1559. </el-form-item>
  1560. </el-col>
  1561. <!-- <el-col span="1">{{item.selectList}}</el-col>-->
  1562. <!--这是负责人的栏位handleUserId -->
  1563. <el-col :span="4" class="col-input">
  1564. <el-form-item prop="handleUserId">
  1565. <user-select2-z-t
  1566. :array-id="index"
  1567. :default-select="item.selectList"
  1568. :multiple="true"
  1569. @selectValue2="parentMethod"
  1570. />
  1571. </el-form-item>
  1572. </el-col>
  1573. <!--计划完成日期-->
  1574. <el-col :span="4" class="col-input-zt">
  1575. <el-date-picker
  1576. v-model="item.completionDate"
  1577. type="date"
  1578. format="yyyy-MM-dd"
  1579. value-format="yyyy-MM-dd"
  1580. placeholder="日期"
  1581. />
  1582. </el-col>
  1583. <el-col :span="3" class="col-input">
  1584. <el-select
  1585. v-model="item.planPhase"
  1586. filterable
  1587. clearable
  1588. placeholder="测试阶段"
  1589. >
  1590. <!-- <el-option label="功能测试" value="功能测试"></el-option>-->
  1591. <!-- <el-option label="性能测试" value="性能测试"></el-option>-->
  1592. <!-- <el-option label="兼容测试" value="兼容测试"></el-option>-->
  1593. <el-option
  1594. v-for="item in dc_data.TEST_PHASE"
  1595. :key="item.value"
  1596. :label="item.label"
  1597. :value="item.value"
  1598. />
  1599. </el-select>
  1600. </el-col>
  1601. <el-col :span="1" class="col-txt">
  1602. <el-button type="primary" size="small" circle @click="addStep(index)">+
  1603. </el-button>
  1604. </el-col>
  1605. <el-col :span="1" class="col-txt">
  1606. <el-button
  1607. v-if="array.length!=1||index!=0"
  1608. type="danger"
  1609. size="small"
  1610. icon="el-icon-delete"
  1611. circle
  1612. @click="removeSetp(index)"
  1613. />
  1614. </el-col>
  1615. </el-row>
  1616. </el-card>
  1617. </el-col>
  1618. <el-col style="padding-bottom: 0px;padding-top: 0px">
  1619. <span class="card_title">其他信息</span>
  1620. <el-card shadow="always" style="padding: 15px 5px 5px 15px">
  1621. <el-row>
  1622. <el-col :span="3" class="col-txt"><span>创建日期</span></el-col>
  1623. <el-col :span="5" class="col-input">
  1624. <el-input v-model="form.createdAt" readonly/>
  1625. </el-col>
  1626. <el-col :span="3" offset="5" class="col-txt"><span>创建人</span></el-col>
  1627. <el-col :span="5" class="col-input">
  1628. <el-input v-model="form.createdByName" readonly/>
  1629. </el-col>
  1630. </el-row>
  1631. </el-card>
  1632. </el-col>
  1633. </el-row>
  1634. </el-form>
  1635. <div slot="footer">
  1636. <el-button @click="dialogVisible = false">取 消</el-button>
  1637. <el-button v-if="!viewVisible" type="primary" @click="confirmSubmit()">确 定</el-button>
  1638. </div>
  1639. </el-dialog>
  1640. <el-dialog
  1641. :title="dialogTitleStatus"
  1642. :visible.sync="dialogVisibleStatus"
  1643. width="30%"
  1644. top="60px"
  1645. @open="dlgOpen"
  1646. @close="dlgClose"
  1647. >
  1648. <el-form ref="form" :model="form" style="width: 100%;padding: 0px 5px 0px 5px" :rules="rules2">
  1649. <el-card shadow="always" style="padding: 5px 5px 5px 5px">
  1650. <el-row>
  1651. <el-col :span="6" class="col-txt"><span>当前状态</span></el-col>
  1652. <el-col :span="18" class="col-input">
  1653. <el-form-item>
  1654. <el-select v-model="form.status" placeholder="请选择">
  1655. <el-option label="未启动" value="0"/>
  1656. <el-option label="进行中" value="2"/>
  1657. <el-option label="完成" value="3"/>
  1658. </el-select>
  1659. </el-form-item>
  1660. </el-col>
  1661. </el-row>
  1662. <el-row>
  1663. <el-col :span="6" class="col-txt"><span>状态说明</span></el-col>
  1664. <el-col :span="18" class="col-input">
  1665. <el-form-item>
  1666. <el-input
  1667. v-model="form.statusremark"
  1668. type="textarea"
  1669. :rows="2"
  1670. placeholder="请输入内容"
  1671. />
  1672. </el-form-item>
  1673. </el-col>
  1674. </el-row>
  1675. </el-card>
  1676. </el-form>
  1677. <div slot="footer">
  1678. <el-button @click="dialogVisibleStatus = false">取 消</el-button>
  1679. <el-button type="primary" @click="confirmSubmitStatus()">保 存</el-button>
  1680. </div>
  1681. </el-dialog>
  1682. <TestToPlanUsecase v-if="dialogVisibleToPlanUsecase" ref="toPlanUsecase" @childEvent="getToPlanUsecaseData"/>
  1683. <!-- 下面的方式也是可以实现的-->
  1684. <!-- <TestDoPlanUsecaseBack ref="doPlanUsecase" v-if="dialogVisibleDoPlanUsecase"/>-->
  1685. <el-dialog
  1686. :title="dialogTitlePlanUsecase"
  1687. :visible.sync="dialogVisiblePlanUsecase"
  1688. :close-on-click-modal="false"
  1689. :close-on-press-escape="true"
  1690. width="90%"
  1691. top="20px"
  1692. @close="dlgClosePlanUsecase"
  1693. >
  1694. <TestDoPlanUsecase v-if="dialogVisibleDoPlanUsecase" ref="doPlanUsecase"/>
  1695. </el-dialog>
  1696. </div>
  1697. </template>
  1698. <script>
  1699. import Base from '../base/base'
  1700. import BaseData from '../base/baseData'
  1701. import QuillEditor from '@/components/QuillEditor'
  1702. // import { upload } from '@/static/utils/channel'
  1703. import UserSelect from '@/views/components/UserSelect'
  1704. import BizUserSelect from '@/views/components/BizUserSelect'
  1705. import UserSelect2ZT from '@/views/components/UserSelect2ZT'
  1706. // import { sendSock, createWebSocket, closeSock } from '@/static/utils/socket'
  1707. // import common from '@/static/utils/common'
  1708. import TestToPlanUsecase from '@/views/testmanage/testToPlanUsecase'
  1709. import TestDoPlanUsecase from '@/views/testmanage/testDoPlanUsecase'
  1710. // import TestDoPlanUsecaseBack from '@/views/testmanage/testDoPlanUsecaseBack'
  1711. export default {
  1712. name: 'TestPlan',
  1713. components: {
  1714. UserSelect2ZT,
  1715. TestToPlanUsecase,
  1716. TestDoPlanUsecase
  1717. // TestDoPlanUsecaseBack,
  1718. // QuillEditor,
  1719. // UserSelect
  1720. // BizUserSelect
  1721. },
  1722. mixins: [Base, BaseData],
  1723. data() {
  1724. return {
  1725. // 新增计划/选择计划完成日期
  1726. value1: '',
  1727. // 查询的时候用的字典========================================
  1728. dc_key: ['TEST_PHASE'],
  1729. // ========================================================
  1730. // 列表相关=================================================
  1731. // 列表中的内容
  1732. AllData: [],
  1733. // 加载中
  1734. loading: false,
  1735. // 选中事件的id列表
  1736. idList: [],
  1737. // =====================================================
  1738. // 弹框相关============================================================
  1739. form: this.initForm(),
  1740. // 关联任务id放在form中了
  1741. // form.taskNo: '',
  1742. // 负责人ids,例如:1072154901540241408,1072151835407548416
  1743. // form.handleUserId
  1744. // 新增计划/选择负责人,预先选择的负责人id
  1745. // form.selectList: [],
  1746. // 是否只是查看
  1747. viewVisible: false,
  1748. // 判断弹框界面是否开着
  1749. dialogVisible: false,
  1750. dialogTitle: '新增',
  1751. // 是否是新增
  1752. isAdd: true,
  1753. // 添加计划存放的对象
  1754. array: [],
  1755. // 计划状态弹框================================================================
  1756. dialogTitleStatus: '计划状态',
  1757. dialogVisibleStatus: false,
  1758. // 关联用例和用例执行弹框=========================================================
  1759. dialogVisibleToPlanUsecase: false,
  1760. dialogVisibleDoPlanUsecase: false,
  1761. // ================================================================
  1762. search: {
  1763. // 项目id
  1764. proId: '',
  1765. // 选择状态
  1766. status: '',
  1767. // 负责人名称
  1768. handleUserNames: ''
  1769. // date_from_1: '',
  1770. // date_to_1: '',
  1771. },
  1772. currentPage: 1,
  1773. allpage: 0,
  1774. pageSize: 5,
  1775. // wxCodeUrl: false,
  1776. rules: {
  1777. proId: [{ required: true, message: '请选择项目', trigger: 'blur' }]
  1778. // planName: [{ required: true, message: '请填写计划名称', trigger: 'blur' }],
  1779. // urgencyDegree: [{ required: true, message: '请选择紧急程度', trigger: 'blur' }],
  1780. // title: [{ required: true, message: '请输入主题', trigger: 'blur' }],
  1781. // handleUserId: [{ required: true, message: '请选择处理人', trigger: 'blur' }]
  1782. },
  1783. // 是否展示计划编辑
  1784. isShowTaskEdit: false,
  1785. // 是否展示计划状态
  1786. isShowTaskStatus: false,
  1787. // 获取用户名称
  1788. truename: ''
  1789. }
  1790. },
  1791. mounted() {
  1792. const _this = this
  1793. this.initDict(_this.dc_key).then((res) => {
  1794. console.log('初始化')
  1795. // console.log(_this.dc_data)
  1796. // 获取列表数据
  1797. _this.getData()
  1798. // 获取项目数据
  1799. _this.initProject()
  1800. // console.log(_this.$has('isShowTaskEdit'))
  1801. _this.isShowTaskEdit = _this.$has('isShowTaskEdit')
  1802. _this.isShowTaskStatus = _this.$has('isShowTaskStatus')
  1803. // console.log(_this.isShowTaskEdit)
  1804. // console.log(_this.ProjectData)
  1805. // console.log(_this.ProjectMap)
  1806. _this.handlegetMyName()
  1807. })
  1808. },
  1809. methods: {
  1810. countWidth(typenum, total) {
  1811. console.log((total / typenum) * 100)
  1812. return ((total / typenum) * 100).toFixed(0)
  1813. },
  1814. // 子传父的方法
  1815. getToPlanUsecaseData(data) {
  1816. console.log('子传父的方法' + data)
  1817. if (data) {
  1818. this.getData()
  1819. }
  1820. },
  1821. // 获取用户姓名
  1822. handlegetMyName: function() {
  1823. // const userType = this.$common.currUserType();
  1824. const user = this.$common.currUser()
  1825. this.truename = user.truename
  1826. // console.log(user)
  1827. // if (user && userType === "2") {
  1828. // this.username = user.username;
  1829. // user.truename
  1830. // } else {
  1831. // this.username = user.truename;
  1832. // }
  1833. },
  1834. // 选择负责人的时候用的
  1835. parentMethod: function(val, index) {
  1836. // if (val.length > 0) {
  1837. // this.form.handleUserId = val.join(',')
  1838. // }
  1839. if (val.length > 0) {
  1840. this.array[index].handleUserId = val.join(',')
  1841. }
  1842. // console.log('1')
  1843. // console.log(index)
  1844. // console.log(val)
  1845. },
  1846. test() {
  1847. console.log('test')
  1848. console.log('子传父的方法' + this.msg)
  1849. // console.log(this.props)
  1850. // console.log(this.options)
  1851. // this.baseRequest('test', null).then((res) => {
  1852. // if (res.data) {
  1853. // console.log(res.data)
  1854. // }
  1855. // }).catch(() => {
  1856. // })
  1857. },
  1858. // 仅仅统计数据,不统计总数
  1859. getDataOnly: function() {
  1860. const _this = this
  1861. // console.log(_this.currentPage)
  1862. _this.loading = true
  1863. _this.AllData = []
  1864. _this.search.pageNum = _this.currentPage
  1865. // console.log(_this.currentPage)
  1866. _this.search.pageSize = _this.pageSize
  1867. this.baseRequest('listVo', _this.search).then((res) => {
  1868. // if (res.data.rows) {
  1869. // res.data.rows.forEach(function(item) {
  1870. // const json = _this.getItemJson(item)
  1871. // _this.AllData.push(json)
  1872. // })
  1873. // _this.allpage = res.data.total
  1874. // }
  1875. if (res.data) {
  1876. res.data.forEach(function(item) {
  1877. const json = _this.getItemJson(item)
  1878. _this.AllData.push(json)
  1879. })
  1880. }
  1881. _this.loading = false
  1882. }).catch(() => {
  1883. })
  1884. },
  1885. getData: function() {
  1886. const _this = this
  1887. // console.log(_this.currentPage)
  1888. _this.loading = true
  1889. _this.AllData = []
  1890. _this.search.pageNum = _this.currentPage
  1891. // console.log(_this.currentPage)
  1892. _this.search.pageSize = _this.pageSize
  1893. this.baseRequest('listVo', _this.search).then((res) => {
  1894. // if (res.data.rows) {
  1895. // res.data.rows.forEach(function(item) {
  1896. // const json = _this.getItemJson(item)
  1897. // _this.AllData.push(json)
  1898. // })
  1899. // _this.allpage = res.data.total
  1900. // }
  1901. if (res.data) {
  1902. res.data.forEach(function(item) {
  1903. const json = _this.getItemJson(item)
  1904. _this.AllData.push(json)
  1905. })
  1906. }
  1907. _this.loading = false
  1908. }).catch(() => {
  1909. })
  1910. this.baseRequest('getTotal', _this.search).then((res) => {
  1911. if (res.data) {
  1912. _this.allpage = res.data
  1913. }
  1914. _this.loading = false
  1915. }).catch(() => {
  1916. })
  1917. // this.initOutData()
  1918. },
  1919. // 添加步骤
  1920. addStep(index) {
  1921. const _this = this
  1922. // 如果序号大于最大值,就是屁股插入,不然就是中间插入
  1923. if ((index + 2) > _this.array.length) {
  1924. _this.array.push({
  1925. id: '',
  1926. planName: '',
  1927. selectList: [],
  1928. completionDate: '',
  1929. planPhase: ''
  1930. })
  1931. } else {
  1932. if (_this.array[index + 1].handleUserId) {
  1933. console.log('有数据', _this.array[index + 1].handleUserId)
  1934. _this.array[index + 1].selectList = _this.array[index + 1].handleUserId.split(',')
  1935. }
  1936. _this.array.splice(index + 1, 0, {
  1937. id: '',
  1938. planName: '',
  1939. selectList: [],
  1940. completionDate: '',
  1941. planPhase: ''
  1942. })
  1943. }
  1944. console.log('数据为', _this.array)
  1945. },
  1946. // 删除步骤
  1947. removeSetp(index) {
  1948. const _this = this
  1949. if (_this.array) {
  1950. _this.array.splice(index, 1)
  1951. }
  1952. },
  1953. // 将项目名称对应的客户名称填到对应的字段中
  1954. getCustName(val) {
  1955. const _this = this
  1956. // console.log('hello')
  1957. // console.log(_this.ProjectData.length)
  1958. // console.log(val)
  1959. for (let i = 0; i < _this.ProjectData.length; i++) {
  1960. // console.log(_this.ProjectData[i].value)
  1961. if (_this.ProjectData[i].value == val) {
  1962. // console.log('ok')
  1963. _this.form.custName = _this.ProjectData[i].custname
  1964. // console.log(_this.form.custName)
  1965. break
  1966. }
  1967. }
  1968. // console.log(_this.form)
  1969. },
  1970. handleSearch: function() {
  1971. this.getData()
  1972. },
  1973. handleReset: function() {
  1974. this.submitTime = []
  1975. for (const i in this.search) {
  1976. if (i !== 'pageNum' && i !== 'pageSize') {
  1977. this.search[i] = ''
  1978. }
  1979. }
  1980. this.handleSearch()
  1981. },
  1982. // 选中事件
  1983. handleSelectionChange(val) {
  1984. this.idList = []
  1985. val.forEach(element => {
  1986. this.idList.push(element.id)
  1987. })
  1988. console.log(this.idList)
  1989. },
  1990. // 当表格的排序条件发生变化的时候会触发该事件 { column, prop, order }
  1991. // sortChange(column,prop,order) {
  1992. //
  1993. // },
  1994. // 批量删除操作
  1995. deleteRecord: function(val) {
  1996. if (this.idList.length === 0) {
  1997. this.$notify({
  1998. title: '请先选择明细记录',
  1999. type: 'info'
  2000. })
  2001. return
  2002. }
  2003. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  2004. confirmButtonText: '确定',
  2005. cancelButtonText: '取消',
  2006. type: 'warning'
  2007. }).then(() => {
  2008. this.baseRequest('remove/' + this.idList).then((res) => {
  2009. if (res.status === 200) {
  2010. this.getData()
  2011. this.$message({
  2012. message: '删除成功',
  2013. type: 'success'
  2014. })
  2015. }
  2016. }).catch(() => {
  2017. })
  2018. }).catch(() => {
  2019. this.$message({
  2020. type: 'info',
  2021. message: '已取消删除'
  2022. })
  2023. })
  2024. },
  2025. // 进行删除操作
  2026. deleteSelect: function(val) {
  2027. console.log(val)
  2028. if (!val) {
  2029. this.$notify({
  2030. title: '请先选择要删除的列',
  2031. type: 'info'
  2032. })
  2033. return
  2034. }
  2035. this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
  2036. confirmButtonText: '确定',
  2037. cancelButtonText: '取消',
  2038. type: 'warning'
  2039. }).then(() => {
  2040. console.log('删除' + val.id)
  2041. this.baseRequest('remove/' + val.id).then((res) => {
  2042. if (res.status === 200) {
  2043. this.getData()
  2044. this.$message({
  2045. message: '删除成功',
  2046. type: 'success'
  2047. })
  2048. }
  2049. }).catch(() => {
  2050. })
  2051. }).catch(() => {
  2052. this.$message({
  2053. type: 'info',
  2054. message: '已取消删除'
  2055. })
  2056. })
  2057. },
  2058. initForm: function() {
  2059. return {
  2060. id: ''
  2061. }
  2062. },
  2063. // 导出数据===========================================
  2064. initOutData: function() {
  2065. const _this = this
  2066. this.OutData = []
  2067. const title = []
  2068. title.push('编号')
  2069. title.push('项目名称')
  2070. title.push('客户名称')
  2071. title.push('用例主题')
  2072. title.push('用例类型')
  2073. title.push('优先级')
  2074. title.push('前置条件')
  2075. title.push('步骤顺序号')
  2076. title.push('步骤描述')
  2077. title.push('预期结果')
  2078. title.push('创建人')
  2079. title.push('创建时间')
  2080. this.OutData.push(title)
  2081. let postData = {}
  2082. postData = _this.search
  2083. if (_this.idList.length === 0) {
  2084. // this.$notify({
  2085. // title: '请先选择明细记录',
  2086. // type: 'info'
  2087. // })
  2088. // return
  2089. } else {
  2090. postData.idList = JSON.stringify(_this.idList)
  2091. }
  2092. this.baseRequest('findAllByInfo', postData).then((res) => {
  2093. if (res.data) {
  2094. res.data.forEach(function(item) {
  2095. const jsonMap = _this.getItemJson(item)
  2096. const jsonArray = []
  2097. jsonArray.push(jsonMap.id)
  2098. jsonArray.push(jsonMap.projectName)
  2099. jsonArray.push(jsonMap.custName)
  2100. jsonArray.push(jsonMap.usecase_title)
  2101. jsonArray.push(jsonMap.usecase_type)
  2102. jsonArray.push(jsonMap.priority)
  2103. jsonArray.push(jsonMap.preconditions)
  2104. jsonArray.push(jsonMap.stepIndex)
  2105. jsonArray.push(jsonMap.stepdescribe)
  2106. jsonArray.push(jsonMap.expected_results)
  2107. jsonArray.push(jsonMap.createdByName)
  2108. jsonArray.push(jsonMap.createdAtString)
  2109. _this.OutData.push(jsonArray)
  2110. })
  2111. _this.confirmOutput()
  2112. }
  2113. }).catch(() => {
  2114. })
  2115. },
  2116. getItemJson: function(item) {
  2117. // const json = {
  2118. // createdAt: item.createdAt ? this.$common.transDate(item.createdAt,this.$constant.DATE_PATTERN.DATE_TIME_h) : ''
  2119. // }
  2120. // return json
  2121. item.completionDate = item.completionDate ? this.$common.transDate(item.completionDate, this.$constant.DATE_PATTERN.DATE) : ''
  2122. // console.log(item.passNum + item.repairNum)
  2123. // console.log((item.passNum + item.repairNum + item.failNum + item.skipNum))
  2124. const useCaseNum = item.passNum + item.repairNum + item.failNum + item.skipNum
  2125. if ((useCaseNum) === 0) {
  2126. item.passRateString = '0%'
  2127. } else {
  2128. item.passRateString = ((item.passNum + item.repairNum) / (useCaseNum) * 100).toFixed(0) + '%'
  2129. }
  2130. if (item.totalNum === 0) {
  2131. item.passRateInfoString = '无用例'
  2132. } else {
  2133. item.passRateInfoString = useCaseNum + '/' + item.totalNum
  2134. }
  2135. // 结果分布
  2136. item.resultDistribution = item.passNum + '-' + item.repairNum + '-' + item.failNum + '-' + item.skipNum
  2137. item.total = item.passNum + item.repairNum + item.failNum + item.skipNum
  2138. item.passGailv =
  2139. item.isShowTaskEdit = this.isShowTaskEdit
  2140. item.isShowTaskStatus = this.isShowTaskStatus
  2141. return item
  2142. },
  2143. confirmOutput() {
  2144. const OutSize = [{ wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }, { wch: 15 }]
  2145. const fileName = '导出用例' + new Date().Format('yyyy-MM-dd hh:mm')
  2146. this.$outputXlsxFile(this.OutData, OutSize, fileName)
  2147. },
  2148. dlgClose() {
  2149. // const _this = this
  2150. if (!this.isAdd) {
  2151. this.array = []
  2152. }
  2153. this.form = this.initForm()
  2154. },
  2155. dlgOpen: function() {
  2156. const _this = this
  2157. // console.log(_this.array)
  2158. if (_this.form.id !== '') {
  2159. _this.array = []
  2160. const postData = {
  2161. id: _this.form.id
  2162. }
  2163. this.baseRequest('getVoById', postData).then((res) => {
  2164. if (res.data) {
  2165. _this.form = res.data
  2166. _this.form.createdAt = this.$common.transDate(_this.form.createdAt, this.$constant.DATE_PATTERN.DATE)
  2167. _this.form.status = String(_this.form.status)
  2168. // console.log(_this.form.handleUserId)
  2169. _this.array.push({
  2170. id: _this.form.id,
  2171. planName: _this.form.planName,
  2172. selectList: _this.form.handleUserId ? _this.form.handleUserId.split(',') : [],
  2173. completionDate: _this.form.completionDate ? this.$common.transDate(_this.form.completionDate, this.$constant.DATE_PATTERN.DATE) : '',
  2174. planPhase: _this.form.planPhase,
  2175. handleUserId: _this.form.handleUserId
  2176. })
  2177. // console.log(_this.array[0].selectList)
  2178. }
  2179. // 添加客户用的
  2180. for (let i = 0; i < _this.ProjectData.length; i++) {
  2181. // console.log(_this.ProjectData[i].value)
  2182. if (_this.ProjectData[i].value == _this.form.proId) {
  2183. // console.log('ok')
  2184. _this.form.custName = _this.ProjectData[i].custname
  2185. // console.log(_this.form.custName)
  2186. break
  2187. }
  2188. }
  2189. // 预防用的
  2190. if (_this.array.length == 0) {
  2191. _this.array.push({
  2192. id: '',
  2193. planName: '',
  2194. selectList: [],
  2195. completionDate: '',
  2196. planPhase: ''
  2197. })
  2198. }
  2199. }).catch(() => {
  2200. })
  2201. } else {
  2202. if (_this.array.length == 0) {
  2203. _this.array.push({
  2204. id: '',
  2205. planName: '',
  2206. selectList: [],
  2207. completionDate: '',
  2208. planPhase: ''
  2209. })
  2210. }
  2211. _this.form.createdAt = this.$common.transDate(new Date(), this.$constant.DATE_PATTERN.DATE)
  2212. _this.form.createdByName = _this.truename
  2213. // console.log(_this.truename)
  2214. }
  2215. },
  2216. /* 关联用例*/
  2217. handleToPlanUsecase(row) {
  2218. this.dialogVisibleToPlanUsecase = true
  2219. this.$nextTick(() => {
  2220. this.$refs.toPlanUsecase.initData('关联用例', row, this.ProjectData, this.ProjectMap)
  2221. })
  2222. },
  2223. /* 用例执行*/
  2224. handleDoPlanUsecase(row) {
  2225. this.dialogVisibleDoPlanUsecase = true
  2226. this.dialogVisiblePlanUsecase = true
  2227. this.dialogTitlePlanUsecase = '用例执行'
  2228. const isShow = false // 判断是否只是展示还是需要进行编辑
  2229. this.$nextTick(() => {
  2230. this.$refs.doPlanUsecase.initData('用例执行', row, isShow)
  2231. })
  2232. },
  2233. /* 用例关闭*/
  2234. dlgClosePlanUsecase() {
  2235. this.getData()
  2236. this.dialogVisibleDoPlanUsecase = false
  2237. this.dialogVisiblePlanUsecase = false
  2238. },
  2239. /* 用例执行查看*/
  2240. handleShowPlanUsecase(row) {
  2241. this.dialogVisibleDoPlanUsecase = true
  2242. this.dialogVisiblePlanUsecase = true
  2243. const isShow = true
  2244. this.$nextTick(() => {
  2245. this.$refs.doPlanUsecase.initData('用例执行查看', row, isShow)
  2246. })
  2247. },
  2248. /* 计划状态*/
  2249. handleTaskStatus: function(val) {
  2250. this.isAdd = false
  2251. this.form = this.initForm()
  2252. this.form.id = val.id
  2253. this.dialogVisibleStatus = true
  2254. this.dialogTitleStatus = '计划状态'
  2255. },
  2256. /* 计划编辑*/
  2257. handleEdit: function(val) {
  2258. this.isAdd = false
  2259. this.form = this.initForm()
  2260. this.form.id = val.id
  2261. this.dialogVisible = true
  2262. this.dialogTitle = '计划编辑'
  2263. this.viewVisible = false
  2264. },
  2265. // 复制数据
  2266. handleCopyEdit: function(val) {
  2267. this.isAdd = true
  2268. this.form.id = val.id
  2269. this.dialogVisible = true
  2270. this.dialogTitle = '复制'
  2271. this.viewVisible = false
  2272. },
  2273. // 查看
  2274. viewInfo: function(val) {
  2275. this.isAdd = false
  2276. this.form.id = val.id
  2277. this.dialogVisible = true
  2278. this.dialogTitle = '查看'
  2279. this.viewVisible = true
  2280. },
  2281. /* 新增*/
  2282. handleAdd: function() {
  2283. // this.form = this.initForm()
  2284. this.form.id = ''
  2285. this.isAdd = true
  2286. this.dialogVisible = true
  2287. this.dialogTitle = '新增测试计划'
  2288. this.viewVisible = false
  2289. if (this.array) {
  2290. // console.log(this.array.length)
  2291. for (let i = 0; i < this.array.length; i++) {
  2292. // console.log(this.array[i].step)
  2293. // console.log(this.array[i].expectedResults)
  2294. if (this.array[i].planName == '' && this.array[i].completionDate == '' && this.array[i].planPhase == '') {
  2295. this.array.splice(i, 1)
  2296. i--
  2297. }
  2298. }
  2299. // console.log(this.array.length)
  2300. }
  2301. },
  2302. // 保存/编辑数据
  2303. confirmSubmit: function() {
  2304. const _this = this
  2305. this.$refs.form.validate(valid => {
  2306. if (valid) {
  2307. // if (this.fileError) {
  2308. // _this.$message.error('附件正在上传,请等待上传完成')
  2309. // return
  2310. // }
  2311. let soaUrl = 'edit'
  2312. const postData = {
  2313. // id: _this.form.id,
  2314. }
  2315. const newArray = []
  2316. // console.log()
  2317. for (let i = 0; i < _this.array.length; i++) {
  2318. if (_this.array[i].planName == '') {
  2319. _this.$message({
  2320. type: 'error',
  2321. message: '请填写计划名称'
  2322. })
  2323. return
  2324. }
  2325. newArray.push(
  2326. {
  2327. id: _this.array[i].id,
  2328. planCommandersId: i,
  2329. planName: _this.array[i].planName,
  2330. handleUserId: _this.array[i].handleUserId,
  2331. completionDate: _this.array[i].completionDate,
  2332. planPhase: _this.array[i].planPhase,
  2333. // 下面是每个计划都要的数据
  2334. taskNo: _this.form.taskNo,
  2335. proId: _this.form.proId
  2336. }
  2337. )
  2338. }
  2339. if (this.dialogTitle === '复制' && this.isAdd) {
  2340. soaUrl = 'add'
  2341. // postData.handleTime = ''
  2342. // postData.verificationTime = ''
  2343. // postData.verificationSituation = ''
  2344. // postData.actCompletionDate = ''
  2345. } else if (this.isAdd) {
  2346. soaUrl = 'add'
  2347. }
  2348. postData.info = JSON.stringify(newArray)
  2349. if (soaUrl == 'edit') {
  2350. _this.$confirm('此操作将永久修改该数据, 是否继续?', '提示', {
  2351. confirmButtonText: '确定',
  2352. cancelButtonText: '取消',
  2353. type: 'warning'
  2354. }).then(() => {
  2355. _this.opRecord(postData, soaUrl)
  2356. }).catch(() => {
  2357. _this.$message({
  2358. type: 'info',
  2359. message: '已取消修改'
  2360. })
  2361. })
  2362. } else {
  2363. _this.opRecord(postData, soaUrl)
  2364. _this.array = []
  2365. }
  2366. } else {
  2367. console.log('error submit!!')
  2368. return false
  2369. }
  2370. })
  2371. },
  2372. // 修改计划状态等信息
  2373. confirmSubmitStatus() {
  2374. const _this = this
  2375. this.$refs.form.validate(valid => {
  2376. if (valid) {
  2377. const soaUrl = 'editStatus'
  2378. const postData = {}
  2379. const newArray = []
  2380. newArray.push(
  2381. {
  2382. id: _this.form.id,
  2383. status: _this.form.status,
  2384. statusremark: _this.form.statusremark
  2385. })
  2386. postData.info = JSON.stringify(newArray)
  2387. _this.opRecordTestPlanStatus(postData, soaUrl)
  2388. _this.array = []
  2389. } else {
  2390. console.log('error submit!!')
  2391. return false
  2392. }
  2393. })
  2394. },
  2395. opRecordTestPlanStatus: function(postData, soaUrl, isRefresh) {
  2396. // console.log('postData/soaUrl/isRefresh', postData, soaUrl, isRefresh)
  2397. if (isRefresh === undefined) {
  2398. isRefresh = true
  2399. }
  2400. const _this = this
  2401. const acting = this.$notify({
  2402. title: '正在处理,请稍等',
  2403. type: 'warning'
  2404. })
  2405. return this.baseRequest(soaUrl, postData).then((res) => {
  2406. acting.close()
  2407. if (isRefresh) {
  2408. _this.opRefreshTestPlanStatus()
  2409. _this.$notify({
  2410. title: '处理成功',
  2411. type: 'info'
  2412. })
  2413. }
  2414. }).catch((err) => {
  2415. acting.close()
  2416. _this.$alert(err)
  2417. })
  2418. },
  2419. // 操作后的执行
  2420. opRefreshTestPlanStatus: function() {
  2421. this.getData()
  2422. this.dialogVisibleStatus = false
  2423. },
  2424. /* 分页设定*/
  2425. handleSizeChange: function(val) {
  2426. this.pageSize = val
  2427. this.getData()
  2428. },
  2429. /* 分页设定*/
  2430. handleCurrentChange: function(val) {
  2431. this.currentPage = val
  2432. if (this.currentPage == 0) {
  2433. this.getData()
  2434. } else {
  2435. this.getDataOnly()
  2436. }
  2437. },
  2438. baseRequest(opUrl, postData) {
  2439. return this.$channel.globleRequest('TestPlanController', opUrl, postData, 'project')
  2440. }
  2441. }
  2442. }
  2443. </script>
  2444. <style scoped>
  2445. .container {
  2446. width: 100%;
  2447. height: 20px;
  2448. background: wheat;
  2449. border-radius: 5rem;
  2450. }
  2451. .br5rem {
  2452. border-radius: 5rem;
  2453. }
  2454. .ch-input .el-input__inner {
  2455. border-radius: 0px;
  2456. border-color: #32323A;
  2457. }
  2458. .ch-input-size {
  2459. width: 150px;
  2460. }
  2461. .col-input-zt {
  2462. text-align: left;
  2463. font-size: 16px;
  2464. font-family: 微软雅黑;
  2465. padding-left: 10px;
  2466. line-height: 40px;
  2467. vertical-align: middle;
  2468. word-break: keep-all;
  2469. overflow: hidden;
  2470. }
  2471. .ch-button {
  2472. border-radius: 0px;
  2473. border-color: #32323A;
  2474. background-color: #32323A;
  2475. color: #fff;
  2476. }
  2477. .ch-button-warning {
  2478. margin-left: 10px;
  2479. border-radius: 0px;
  2480. border-color: #E6A23C;
  2481. background-color: #E6A23C;
  2482. color: #fff;
  2483. }
  2484. .ch-button-export {
  2485. margin-left: 10px;
  2486. border-radius: 0px;
  2487. border-color: #98CC1F;
  2488. background-color: #98CC1F;
  2489. color: #fff;
  2490. }
  2491. </style>