You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

project.js 20 kB

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 years ago
​
​
​
​
​
​
11 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 years ago
​
​
​
​
​
​
​
​
​
11 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
11 years ago
​
11 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. //验证搜索时输入字
  2. function regexName(content) {
  3. var name = $.trim($("#name").val());
  4. if (name.length == 0) {
  5. $("#project_name_span").text(content);
  6. $("#project_name_span").css('color', '#ff0000');
  7. $("#project_name_span").focus();
  8. return false;
  9. }
  10. else {
  11. $("#project_name_span").text("");
  12. return true;
  13. }
  14. }
  15. function submitSerch(content) {
  16. if (regexName(content)) {
  17. $("#project_search_form").submit();
  18. }
  19. }
  20. // 项目描述超过展开
  21. //$(function(){
  22. // $(".subNav").click(function(){
  23. //
  24. // })
  25. //})
  26. function expand_tools_expand(content) {
  27. if (content == "invit") {
  28. $("#expand_tools_expand_invit").toggleClass("currentDd").siblings(".subNav").removeClass("currentDd");
  29. $("#expand_tools_expand_invit").toggleClass("currentDt").siblings(".subNav").removeClass("currentDt");
  30. $("#expand_tools_expand_invit").next(".navContent").slideToggle(500).siblings(".navContent").slideUp(500);
  31. }
  32. else {
  33. // $("#expand_tools_expand").toggleClass("currentDd").siblings(".subNav").removeClass("currentDd");
  34. // $("#expand_tools_expand").toggleClass("currentDt").siblings(".subNav").removeClass("currentDt");
  35. // $("#expand_tools_expand").next(".navContent").slideToggle(500).siblings(".navContent").slideUp(500);
  36. $("#navContent").toggle(500);
  37. }
  38. // 修改数字控制速度, slideUp(500)控制卷起速度
  39. }
  40. // 描述显示更多信息
  41. function show_more_msg() {
  42. $("#course_description").toggleClass("course_description_none");
  43. var information = $("#expend_more_information");
  44. var arrow = $("#arrow");
  45. var val = information.attr("value");
  46. if (val == "show_more") {
  47. $("#expend_more_information").text("收起描述信息");
  48. information.attr("value", "hide_more");
  49. arrow.attr("src", "/images/jiantouup.jpg")
  50. }
  51. else {
  52. $("#expend_more_information").text("展开更多信息");
  53. information.attr("value", "show_more");
  54. arrow.attr("src", "/images/jiantou.jpg")
  55. }
  56. }
  57. function show_more_reply(contentid, id2, id3) {
  58. $(contentid).toggleClass("course_description_none");
  59. var information = $(id2);
  60. var arrow = $(id3);
  61. var val = information.attr("value");
  62. if (val == "show_more") {
  63. $(id2).text("[收起]");
  64. information.attr("value", "hide_more");
  65. information.attr("style", "color:#3ca5c6");
  66. arrow.attr("src", "/images/jiantouup.jpg")
  67. }
  68. else {
  69. $(id2).text("[展开]");
  70. information.attr("value", "show_more");
  71. arrow.attr("src", "/images/jiantou.jpg")
  72. information.attr("style", "color:#0781b4;");
  73. }
  74. }
  75. function show_more_reply1(contentid, id2, id3) {
  76. $(contentid).toggleClass("course_description_none");
  77. var information = $(id2);
  78. var arrow = $(id3);
  79. var val = information.attr("value");
  80. if (val == "show_more") {
  81. $(id2).text("[收起]");
  82. information.attr("value", "hide_more");
  83. information.attr("style", "color:#3ca5c6");
  84. arrow.attr("src", "/images/jiantouup.jpg")
  85. }
  86. else {
  87. $(id2).text("[展开]");
  88. information.attr("value", "show_more");
  89. arrow.attr("src", "/images/jiantou.jpg")
  90. information.attr("style", "color:#0781b4;");
  91. }
  92. }
  93. //项目版本库git帮助文档显示
  94. //function showhelpAndScrollTo(id) {
  95. // $('#' + id).toggle();
  96. // if(cookieget("repositories_visiable") == "true")
  97. // {
  98. // cookiesave("repositories_visiable", false,'','','');
  99. // }
  100. // else
  101. // {
  102. // cookiesave("repositories_visiable", true,'','','');
  103. // }
  104. // var information = $("#showgithelp");
  105. // var val = information.attr("value");
  106. // if(val=="show_help")
  107. // {
  108. // $("#showgithelp").text("收起Git操作指南");
  109. // information.attr("value", "hide_help");
  110. // }
  111. // else
  112. // {
  113. // $("#showgithelp").text("展开Git操作指南");
  114. // information.attr("value", "show_help");
  115. // }
  116. //}
  117. function showhelpAndScrollToMessage(id, id1, count) {
  118. $('#' + id).toggle();
  119. if(cookieget("repositories_visiable") == "true")
  120. {
  121. cookiesave("repositories_visiable", false,'','','');
  122. }
  123. else
  124. {
  125. cookiesave("repositories_visiable", true,'','','');
  126. }
  127. var information = $(id1);
  128. var val = information.attr("value");
  129. if(val=="show_help")
  130. {
  131. $(id1).text("收起回复(" + count + ")" );
  132. information.attr("value", "hide_help");
  133. information.attr("style", "color:#3ca5c6");
  134. }
  135. else
  136. {
  137. $(id1).text("展开回复(" + count + ")");
  138. information.attr("value", "show_help");
  139. information.attr("style", "color:#0781b4;");
  140. }
  141. }
  142. $(function(){
  143. var information = $("#showgithelp");
  144. var val = information.attr("value");
  145. if(cookieget("repositories_visiable") == "true")
  146. {
  147. $('#repos_git_more').hide();
  148. }
  149. else
  150. {
  151. $('#repos_git_more').show();
  152. $("#showgithelp").text("收起Git操作指南");
  153. information.attr("value", "hide_help");
  154. }
  155. });
  156. ///////////////////////////////////////////////////////////////
  157. //////////////////////////////////////////////////////////////项目讨论区
  158. function regexSubject(id) {
  159. var subjectid = "#message_subject" + id ;
  160. var content = $.trim($(subjectid).val());
  161. var message = "#subject_span" + id;
  162. if (content.length == 0) {
  163. $(message).text("主题不能为空");
  164. $(message).css('color', '#ff0000');
  165. return false;
  166. }
  167. else {
  168. $(message).text("填写正确");
  169. $(message).css('color', '#008000');
  170. return true;
  171. }
  172. return false;
  173. }
  174. function regexContent(){
  175. }
  176. function regexContentxx(id) {
  177. var contentid = "#message_content" + id;
  178. var message = "#message_content_span"+ id;
  179. var ps=document.getElementById('message_content' + id).previousElementSibling.children[1].children[0];
  180. alert(ps);
  181. document.getElementById('message_content' + id).value = ps.value;
  182. var content = $.trim($(contentid).val());
  183. alert(content);
  184. if (content.length == 0) {
  185. $(message).text("描述不能为空");
  186. $(message).css('color', '#ff0000');
  187. return false;
  188. }
  189. else {
  190. $(message).text("填写正确");
  191. $(message).css('color', '#008000');
  192. return true;
  193. }
  194. return false;
  195. }
  196. // 项目讨论区编辑和提交
  197. function submitProjectsBoard(id) {
  198. var formid = "#message-form" + id;
  199. if (regexSubject(id) && regexContent(id)) {
  200. $(formid).submit();
  201. }
  202. }
  203. // 提交新闻
  204. function regexTitle() {
  205. var name = $("#news_title").val();
  206. if (name.length == 0) {
  207. $("#title_notice_span").text("标题不能为空");
  208. $("#title_notice_span").css('color', '#ff0000');
  209. $("#title_notice_span").focus();
  210. return false;
  211. }
  212. else if (name.length <= 60) {
  213. $("#title_notice_span").text("填写正确");
  214. $("#title_notice_span").css('color', '#008000');
  215. return true;
  216. }
  217. else {
  218. $("#title_notice_span").text("标题超过60个字符");
  219. $("#title_notice_span").css('color', '#ff0000');
  220. $("#title_notice_span").focus();
  221. return false;
  222. }
  223. }
  224. function regexDescription() {
  225. project_news_description_editor.sync();
  226. var name = project_news_description_editor.html();
  227. if (name.length == 0) {
  228. $("#description_notice_span").text("描述不能为空");
  229. $("#description_notice_span").css('color', '#ff0000');
  230. $("#description_notice_span").focus();
  231. return false;
  232. }
  233. /*else if (name.length > 10000)
  234. {
  235. $("#description_notice_span").text("描述超过10000个字符");
  236. $("#description_notice_span").css('color', '#ff0000');
  237. $("#description_notice_span").focus();
  238. return false;
  239. }*/
  240. else {
  241. $("#description_notice_span").text("填写正确");
  242. $("#description_notice_span").css('color', '#008000');
  243. return true;
  244. }
  245. }
  246. function submitNews() {
  247. if (regexTitle() && regexDescription()) {
  248. $("#news-form").submit();
  249. }
  250. }
  251. function submitFocus(obj) {
  252. $(obj).focus();
  253. }
  254. function submitComment()
  255. {
  256. if (newsReplyVerify()) {
  257. comment_editor.sync();
  258. $("#add_comment_form").submit();
  259. }
  260. }
  261. function newsReplyVerify() {
  262. var content = comment_editor.html();
  263. if(comment_editor.isEmpty()) {
  264. $("#add_reply_news").text("评论不能为空");
  265. $("#add_reply_news").css('color', '#ff0000');
  266. $("#news_submit_comment").one('click',function(){
  267. submitComment();
  268. });
  269. return false;
  270. } else {
  271. $("#add_reply_news").text("填写正确");
  272. $("#add_reply_news").css('color', '#008000');
  273. return true;
  274. }
  275. }
  276. //当项目描述长度小于112px时,不显示更多按钮
  277. $(function () {
  278. // alert($("#course_description_content").height());
  279. if ($("#course_description_content").height() > 400) {
  280. $("#lg-foot").show();
  281. }
  282. });
  283. //配置项目信息
  284. function course_setting(id) {
  285. //alert(id);
  286. $('#tb_' + id).removeClass().addClass("hwork_hovertab");
  287. $('#tbc_0' + id).removeClass().addClass("dis");
  288. $('#tb_' + (3 - id)).removeClass().addClass("hwork_normaltab");
  289. $('#tbc_0' + (3 - id)).removeClass().addClass("undis");
  290. }
  291. //项目类型(朋友圈、开发组、科研组)
  292. function show_window() {
  293. $('#light').css('display', 'block');
  294. $('#fade').css('display', 'block');
  295. }
  296. function close_window(type) {
  297. $('#light').css('display', 'none');
  298. $('#fade').css('display', 'none');
  299. $("#" + type).attr("checked", "checked");
  300. }
  301. //弹框l
  302. /////////////////////////////////////////////
  303. //项目配置
  304. function project_setting(n) {
  305. for (var i = 1; i < 9; i++) {
  306. if (i == n) {
  307. $("#pro_st_tb_" + i).removeClass().addClass("pro_st_hovertab");
  308. $("#pro_st_tbc_0" + i).removeClass().addClass("pro_st_dis");
  309. }
  310. else {
  311. $("#pro_st_tb_" + i).removeClass().addClass("pro_st_normaltab");
  312. $("#pro_st_tbc_0" + i).removeClass().addClass("pro_st_undis");
  313. }
  314. }
  315. }
  316. //配置-验证项目名称
  317. function regex_project_name() {
  318. var name = $.trim($("#project_name").val());
  319. if (name.length == 0) {
  320. $("#project_name_notice").show();
  321. return false;
  322. }
  323. else {
  324. $("#project_name_notice").hide();
  325. return true;
  326. }
  327. }
  328. //配置-信息提交
  329. function submit_edit_project(id) {
  330. if (regex_project_name()) {
  331. $("#edit_project_" + id).submit();
  332. }
  333. }
  334. //配置--成员---申请列表--拒绝
  335. function refusal_applied_member() {
  336. $('#new_membership').append("<input name = 'refusal_button' style='display: none;'>");
  337. $('#new_membership').submit();
  338. }
  339. //新闻描述显示更多信息
  340. function news_show_more_des(id) {
  341. $('#news_description_' + id).toggleClass("news_description_none");
  342. }
  343. $(document).ready(function () {
  344. $("#issue_project_id").css("width", "100%");
  345. $("#issue_project_id").css("overflow ", "hidden");
  346. // $(".jstEditor").css("margin-left ","80px");
  347. //issue_project_id
  348. });
  349. function showAndScrollTo(id, focus) {
  350. $('#' + id).show();
  351. if (focus !== null) {
  352. $('#' + focus).focus();
  353. issue_journal_kind_reply.focus();
  354. }
  355. $('html, body').animate({scrollTop: $('#' + id).offset().top}, 400);
  356. }
  357. function quote_issue_journal(){
  358. alert("test");
  359. issue_journal_kind_reply.focus();
  360. issue_journal_kind_reply.cmd.range.setStart(issue_journal_kind_reply.cmd.range.startOffset)
  361. }
  362. /*缺陷完成度决定缺陷状态*/
  363. function PrecentChange(obj) {
  364. var _v = obj;
  365. if (_v == 100) {
  366. //var select=$("select[id='issue_status_id']");
  367. $("select[id='issue_status_id']").find("option[value='3']").attr("selected", "selected");
  368. }
  369. else if (_v == 0) {
  370. //alert(1);
  371. $("select[id='issue_status_id']").find("option[value='1']").attr("selected", "selected");
  372. }
  373. else if (_v != 100 && _v != 0) {
  374. // alert(2);
  375. $("select[id='issue_status_id']").find("option[value='2']").attr("selected", "selected");
  376. }
  377. }
  378. // Can't use Rails' remote select because we need the form data
  379. // 根据缺陷状态值改变完成度状态
  380. function updateIssueFrom(url) {
  381. $.ajax({
  382. url: url,
  383. type: 'post',
  384. data: $('#issue-form').serialize()
  385. });
  386. }
  387. // firefox pre标签换行
  388. $(document).ready(function () {
  389. var userAgent = navigator.userAgent.toLowerCase();
  390. var browser = {
  391. version: (userAgent.match(/.+(?:rv|it|ra|ie)[/: ]([d.]+)/) || [])[1],
  392. safari: /webkit/.test(userAgent),
  393. opera: /opera/.test(userAgent),
  394. msie: /msie/.test(userAgent) && !/opera/.test(userAgent),
  395. mozilla: /mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
  396. };
  397. if (browser.mozilla || browser.opera) {
  398. $("pre").addClass("break_word_firefox");
  399. }
  400. else {
  401. $("pre").addClass("break_word");
  402. }
  403. });
  404. //论坛提交
  405. function submitProjectBoard()
  406. {
  407. if(regexSubject()&&regexContent())
  408. {
  409. $("#message-form").submit();
  410. }
  411. }
  412. //cookie记忆html区块 显示/隐藏 的代码 start
  413. $(function(){
  414. var personalized_expand_key = "personalized_expand";
  415. function personalized_init(){
  416. var personalized_map = cookieget(personalized_expand_key);
  417. if(personalized_map!=false){
  418. personalized_map = JSON.parse(personalized_map);
  419. $("*[nhtype='toggle4cookie']").each(function(){
  420. var personalized_id=$(this).data('id');
  421. var val = personalized_map[personalized_id];
  422. if(val!=undefined && val!=$(this).data('val')){
  423. personalized_click($(this),0);
  424. }
  425. });
  426. }
  427. }
  428. function personalized_click(obj,timeout){
  429. var target = $(obj.data('target'));
  430. var oldval = obj.data('val');
  431. var val='';
  432. if(oldval=='expand'){val='retract';}else{val='expand';}
  433. obj.data('val',val);
  434. var personalized_map = cookieget(personalized_expand_key);
  435. if(personalized_map == false){
  436. personalized_map={};
  437. }else{
  438. personalized_map = JSON.parse(personalized_map);
  439. }
  440. var personalized_id=obj.data('id');
  441. personalized_map[personalized_id]=val;
  442. cookiesave(personalized_expand_key,JSON.stringify(personalized_map));
  443. target.toggle(timeout);
  444. }
  445. $("*[nhtype='toggle4cookie']").on('click',function(){
  446. personalized_click($(this),500);
  447. });
  448. personalized_init();
  449. });
  450. //cookie记忆html区块 显示/隐藏 的代码 end
  451. // 新建项目的时候判断是否与我已有的项目重复
  452. function judgeprojectname(){
  453. $('#new_project').validate({
  454. errorPlacement: function(error, element){
  455. alert('error')
  456. },
  457. success: function(label){
  458. alert('ok')
  459. },
  460. onkeyup: false,
  461. rules : {
  462. name:{required : true,
  463. remote : {
  464. url : 'projects/judge_same_projectname',
  465. type:'get',
  466. dataType:'text',
  467. data:{
  468. name : function(){ return $.trim( $("#name").val() ); }
  469. },
  470. dataFilter:function( data ){
  471. if( data=='true')return false; else return true;
  472. }
  473. }
  474. }
  475. },
  476. messages : {
  477. name:{required : "请填写项目名称!",remote:'您已新建过同名项目,请修改项目名称!'}
  478. }
  479. });
  480. }
  481. //用户反馈
  482. function submitProjectFeedback() {
  483. $("#project_feedback_form").submit();
  484. }
  485. // 点击按钮复制功能
  486. function jsCopy(){
  487. var e=document.getElementById("copy_rep_content");
  488. e.select();
  489. document.execCommand("Copy");
  490. }
  491. function jsCopy2(id){
  492. //alert("copy_rep_content2_" + id);
  493. var e=document.getElementById("copy_rep_content2_" + id);
  494. e.select();
  495. document.execCommand("Copy");
  496. }
  497. function zip(){
  498. alert("该功能正在紧张的开发中,我们会争取在最短时间内上线,如若对您工作造成不便敬请谅解!")
  499. }
  500. //取消关联
  501. function cancel_relation(orgId,projectId){
  502. if(confirm("确定取消关联吗?") == false) return;
  503. $.ajax({
  504. url:'/org_projects/'+orgId+"?project_id="+projectId,
  505. type:'DELETE',
  506. success:function(data) {
  507. $.ajax({
  508. url: ' /projects/'+projectId+'/search_public_orgs_not_in_project?hint_flag=true',
  509. type:'get'
  510. });
  511. }
  512. });
  513. }
  514. function issueEditShow(){
  515. $("#issue_detail").hide();
  516. $("#issue_edit").show();
  517. }
  518. function issueDetailShow(){
  519. $("#issue_edit").hide();
  520. $("#issue_detail").show();
  521. }
  522. //项目讨论区提交
  523. function regexTopicSubject() {
  524. var name = $("#message_subject").val();
  525. if(name.length ==0)
  526. {
  527. $("#subjectmsg").text("标题不能为空");
  528. $("#subjectmsg").css('color','#ff0000');
  529. $("#message_subject").focus();
  530. return false;
  531. }
  532. else if(name.length <= 255)
  533. {
  534. $("#subjectmsg").text("填写正确");
  535. $("#subjectmsg").css('color','#008000');
  536. return true;
  537. }
  538. else
  539. {
  540. $("#subjectmsg").text("标题超过255个字符");
  541. $("#subjectmsg").css('color','#ff0000');
  542. $("#message_subject").focus();
  543. return false;
  544. }
  545. }
  546. function regexTopicDescription()
  547. {
  548. var name = message_content_editor.html();
  549. if(message_content_editor.isEmpty())
  550. {
  551. $("#message_content_span").text("描述不能为空");
  552. $("#message_content_span").css('color','#ff0000');
  553. return false;
  554. }
  555. else if(name.length >=6000){
  556. $("#message_content_span").text("描述最多3000个汉字(或6000个英文字符)");
  557. $("#message_content_span").css('color','#ff0000');
  558. return false;
  559. }
  560. else
  561. {
  562. $("#message_content_span").text("填写正确");
  563. $("#message_content_span").css('color','#008000');
  564. return true;
  565. }
  566. }
  567. function submit_topic_project()
  568. {
  569. // if(regexTopicSubject() && regexTopicDescription())
  570. // {
  571. message_content_editor.sync();
  572. $("#message-form-project").submit();
  573. // }
  574. }
  575. function reset_topic(){
  576. }
  577. //查找TAG资源
  578. var clickFunction = null; //单击事件函数
  579. var isdb = false; //是否双击
  580. function search_tag_attachment(url,tag_name,q,course_id,sort)
  581. {
  582. //alert("111");
  583. //clearTimeout(clickFunction);
  584. clickFunction = setTimeout(function() {
  585. search_func()
  586. }, 500);
  587. function search_func(){
  588. if(isdb!= false ) return;
  589. $.get(
  590. url,
  591. {
  592. tag_name: tag_name,
  593. q: q,
  594. course_id:course_id
  595. },
  596. function (data) {
  597. }
  598. );
  599. }
  600. }

软件技术创新是当今国家整体创新能力的重要基础和发展引擎。近年来,大众参与的软件创新与创业活动已经成为网络时代软件开发和应用的新形态,正在快速改变着全球软件创新模式和软件产业格局。 ...